From 9289b3de2814e373faae0df8f70a1900fc4fabde Mon Sep 17 00:00:00 2001 From: ian Date: Tue, 29 Jul 2025 16:59:57 +0900 Subject: [PATCH] add files --- A2lTestDlg/A2lTestDlg.sln | 31 + A2lTestDlg/A2lTestDlg/A2L.c | 718 ++++++++++ A2lTestDlg/A2lTestDlg/A2L.h | 121 ++ A2lTestDlg/A2lTestDlg/A2Lpp.cpp | 124 ++ A2lTestDlg/A2lTestDlg/A2Lpp.hpp | 122 ++ A2lTestDlg/A2lTestDlg/A2lTestDlg.cpp | 153 ++ A2lTestDlg/A2lTestDlg/A2lTestDlg.h | 33 + A2lTestDlg/A2lTestDlg/A2lTestDlg.idl | 29 + A2lTestDlg/A2lTestDlg/A2lTestDlg.rc | Bin 0 -> 12482 bytes A2lTestDlg/A2lTestDlg/A2lTestDlg.reg | 17 + A2lTestDlg/A2lTestDlg/A2lTestDlg.vcxproj | 252 ++++ .../A2lTestDlg/A2lTestDlg.vcxproj.filters | 118 ++ A2lTestDlg/A2lTestDlg/A2lTestDlg.vcxproj.user | 6 + A2lTestDlg/A2lTestDlg/A2lTestDlgDlg.cpp | 252 ++++ A2lTestDlg/A2lTestDlg/A2lTestDlgDlg.h | 60 + A2lTestDlg/A2lTestDlg/A2lTestDlg_h.h | 226 +++ A2lTestDlg/A2lTestDlg/A2lTestDlg_i.c | 84 ++ A2lTestDlg/A2lTestDlg/DlgProxy.cpp | 87 ++ A2lTestDlg/A2lTestDlg/DlgProxy.h | 43 + A2lTestDlg/A2lTestDlg/dbg_print.h | 50 + A2lTestDlg/A2lTestDlg/framework.h | 60 + A2lTestDlg/A2lTestDlg/main.h | 95 ++ A2lTestDlg/A2lTestDlg/main_cfg.h | 48 + A2lTestDlg/A2lTestDlg/main_cfg.h.in | 39 + A2lTestDlg/A2lTestDlg/pch.cpp | 5 + A2lTestDlg/A2lTestDlg/pch.h | 13 + A2lTestDlg/A2lTestDlg/platform.h | 183 +++ A2lTestDlg/A2lTestDlg/res/A2lTestDlg.ico | Bin 0 -> 67777 bytes A2lTestDlg/A2lTestDlg/res/A2lTestDlg.rc2 | Bin 0 -> 804 bytes A2lTestDlg/A2lTestDlg/resource.h | 24 + A2lTestDlg/A2lTestDlg/targetver.h | 8 + A2lTestDlg/A2lTestDlg/xcp.h | 1235 +++++++++++++++++ A2lTestDlg/A2lTestDlg/xcpEthTl.h | 27 + A2lTestDlg/A2lTestDlg/xcpLite.h | 188 +++ A2lTestDlg/A2lTestDlg/xcpTl.h | 32 + A2lTestDlg/A2lTestDlg/xcp_cfg.h | 104 ++ A2lTestDlg/A2lTestDlg/xcptl_cfg.h | 70 + 37 files changed, 4657 insertions(+) create mode 100644 A2lTestDlg/A2lTestDlg.sln create mode 100644 A2lTestDlg/A2lTestDlg/A2L.c create mode 100644 A2lTestDlg/A2lTestDlg/A2L.h create mode 100644 A2lTestDlg/A2lTestDlg/A2Lpp.cpp create mode 100644 A2lTestDlg/A2lTestDlg/A2Lpp.hpp create mode 100644 A2lTestDlg/A2lTestDlg/A2lTestDlg.cpp create mode 100644 A2lTestDlg/A2lTestDlg/A2lTestDlg.h create mode 100644 A2lTestDlg/A2lTestDlg/A2lTestDlg.idl create mode 100644 A2lTestDlg/A2lTestDlg/A2lTestDlg.rc create mode 100644 A2lTestDlg/A2lTestDlg/A2lTestDlg.reg create mode 100644 A2lTestDlg/A2lTestDlg/A2lTestDlg.vcxproj create mode 100644 A2lTestDlg/A2lTestDlg/A2lTestDlg.vcxproj.filters create mode 100644 A2lTestDlg/A2lTestDlg/A2lTestDlg.vcxproj.user create mode 100644 A2lTestDlg/A2lTestDlg/A2lTestDlgDlg.cpp create mode 100644 A2lTestDlg/A2lTestDlg/A2lTestDlgDlg.h create mode 100644 A2lTestDlg/A2lTestDlg/A2lTestDlg_h.h create mode 100644 A2lTestDlg/A2lTestDlg/A2lTestDlg_i.c create mode 100644 A2lTestDlg/A2lTestDlg/DlgProxy.cpp create mode 100644 A2lTestDlg/A2lTestDlg/DlgProxy.h create mode 100644 A2lTestDlg/A2lTestDlg/dbg_print.h create mode 100644 A2lTestDlg/A2lTestDlg/framework.h create mode 100644 A2lTestDlg/A2lTestDlg/main.h create mode 100644 A2lTestDlg/A2lTestDlg/main_cfg.h create mode 100644 A2lTestDlg/A2lTestDlg/main_cfg.h.in create mode 100644 A2lTestDlg/A2lTestDlg/pch.cpp create mode 100644 A2lTestDlg/A2lTestDlg/pch.h create mode 100644 A2lTestDlg/A2lTestDlg/platform.h create mode 100644 A2lTestDlg/A2lTestDlg/res/A2lTestDlg.ico create mode 100644 A2lTestDlg/A2lTestDlg/res/A2lTestDlg.rc2 create mode 100644 A2lTestDlg/A2lTestDlg/resource.h create mode 100644 A2lTestDlg/A2lTestDlg/targetver.h create mode 100644 A2lTestDlg/A2lTestDlg/xcp.h create mode 100644 A2lTestDlg/A2lTestDlg/xcpEthTl.h create mode 100644 A2lTestDlg/A2lTestDlg/xcpLite.h create mode 100644 A2lTestDlg/A2lTestDlg/xcpTl.h create mode 100644 A2lTestDlg/A2lTestDlg/xcp_cfg.h create mode 100644 A2lTestDlg/A2lTestDlg/xcptl_cfg.h diff --git a/A2lTestDlg/A2lTestDlg.sln b/A2lTestDlg/A2lTestDlg.sln new file mode 100644 index 0000000..59a3099 --- /dev/null +++ b/A2lTestDlg/A2lTestDlg.sln @@ -0,0 +1,31 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.35731.53 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "A2lTestDlg", "A2lTestDlg\A2lTestDlg.vcxproj", "{86752C60-05E4-465C-9D79-876C97ABD2BA}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 + Release|x64 = Release|x64 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {86752C60-05E4-465C-9D79-876C97ABD2BA}.Debug|x64.ActiveCfg = Debug|x64 + {86752C60-05E4-465C-9D79-876C97ABD2BA}.Debug|x64.Build.0 = Debug|x64 + {86752C60-05E4-465C-9D79-876C97ABD2BA}.Debug|x86.ActiveCfg = Debug|Win32 + {86752C60-05E4-465C-9D79-876C97ABD2BA}.Debug|x86.Build.0 = Debug|Win32 + {86752C60-05E4-465C-9D79-876C97ABD2BA}.Release|x64.ActiveCfg = Release|x64 + {86752C60-05E4-465C-9D79-876C97ABD2BA}.Release|x64.Build.0 = Release|x64 + {86752C60-05E4-465C-9D79-876C97ABD2BA}.Release|x86.ActiveCfg = Release|Win32 + {86752C60-05E4-465C-9D79-876C97ABD2BA}.Release|x86.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {F96F38CF-D37B-45D8-9FA2-665EB10C5913} + EndGlobalSection +EndGlobal diff --git a/A2lTestDlg/A2lTestDlg/A2L.c b/A2lTestDlg/A2lTestDlg/A2L.c new file mode 100644 index 0000000..9638bbc --- /dev/null +++ b/A2lTestDlg/A2lTestDlg/A2L.c @@ -0,0 +1,718 @@ +/*---------------------------------------------------------------------------- +| File: +| A2L.c +| +| Description: +| Create A2L file +| +| Copyright (c) Vector Informatik GmbH. All rights reserved. +| Licensed under the MIT license. See LICENSE file in the project root for details. +| + ----------------------------------------------------------------------------*/ +#include "pch.h" +#include "framework.h" + +#include "main.h" +#include "platform.h" +#include "dbg_print.h" +#include "xcpLite.h" +#include "A2L.h" + +static FILE* gA2lFile = NULL; +static uint16_t gA2lFixedEvent = XCP_INVALID_EVENT; +static uint16_t gA2lDefaultEvent = XCP_INVALID_EVENT; + +static uint32_t gA2lMeasurements; +static uint32_t gA2lParameters; +static uint32_t gA2lTypedefs; +static uint32_t gA2lComponents; +static uint32_t gA2lInstances; +static uint32_t gA2lConversions; + + +//---------------------------------------------------------------------------------- +// Check for memory accessibility +//#define A2L_ENABLE_MEMORY_CHECK +#ifdef A2L_ENABLE_MEMORY_CHECK +static void mem_check(const char* name, int32_t type, uint8_t ext, uint32_t addr) { + (void)type; (void)name; + volatile uint8_t *p = ApplXcpGetPointer(ext,addr); + if (p==NULL) { DBG_PRINTF1("ERROR: memory address 0x%04X of variable %s not accessible !\n",addr,name); assert(0); } + volatile uint8_t b = *p; // if this leads to a memory protection error, check if address transformation from A2L to uint_8_p* transformation is correct +} +#endif + + +//---------------------------------------------------------------------------------- +static const char* gA2lHeader = +"ASAP2_VERSION 1 71\n" +"/begin PROJECT %s \"\"\n" +"/begin HEADER \"\" VERSION \"1.0\" /end HEADER\n" +"/begin MODULE %s \"\"\n" +"/include \"XCP_104.aml\"\n\n" + +"/begin MOD_COMMON \"\"\n" +"BYTE_ORDER MSB_LAST\n" +"ALIGNMENT_BYTE 1\n" +"ALIGNMENT_WORD 1\n" +"ALIGNMENT_LONG 1\n" +"ALIGNMENT_FLOAT16_IEEE 1\n" +"ALIGNMENT_FLOAT32_IEEE 1\n" +"ALIGNMENT_FLOAT64_IEEE 1\n" +"ALIGNMENT_INT64 1\n" +"/end MOD_COMMON\n" +"\n"; + +//---------------------------------------------------------------------------------- +static const char* gA2lMemorySegment = +"/begin MEMORY_SEGMENT\n" +"CALRAM \"\" DATA FLASH INTERN 0x%08X 0x%08X -1 -1 -1 -1 -1\n" // CALRAM_START, CALRAM_SIZE +"/begin IF_DATA XCP\n" +"/begin SEGMENT 0x01 0x02 0x00 0x00 0x00 \n" +"/begin CHECKSUM XCP_ADD_44 MAX_BLOCK_SIZE 0xFFFF EXTERNAL_FUNCTION \"\" /end CHECKSUM\n" +"/begin PAGE 0x01 ECU_ACCESS_WITH_XCP_ONLY XCP_READ_ACCESS_WITH_ECU_ONLY XCP_WRITE_ACCESS_NOT_ALLOWED /end PAGE\n" +"/begin PAGE 0x00 ECU_ACCESS_WITH_XCP_ONLY XCP_READ_ACCESS_WITH_ECU_ONLY XCP_WRITE_ACCESS_WITH_ECU_ONLY /end PAGE\n" +"/end SEGMENT\n" +"/end IF_DATA\n" +"/end MEMORY_SEGMENT\n"; + +//---------------------------------------------------------------------------------- +static const char* const gA2lIfDataBegin = +"\n/begin IF_DATA XCP\n"; + +//---------------------------------------------------------------------------------- +static const char* gA2lIfDataProtocolLayer = // Parameter: XCP_PROTOCOL_LAYER_VERSION, MAX_CTO, MAX_DTO +"/begin PROTOCOL_LAYER\n" +" 0x%04X" // XCP_PROTOCOL_LAYER_VERSION +" 1000 2000 0 0 0 0 0" // Timeouts T1-T7 +" %u %u " // MAX_CTO, MAX_DTO +"BYTE_ORDER_MSB_LAST ADDRESS_GRANULARITY_BYTE\n" // Intel and BYTE pointers +"OPTIONAL_CMD GET_COMM_MODE_INFO\n" // Optional commands +"OPTIONAL_CMD GET_ID\n" +"OPTIONAL_CMD SET_MTA\n" +"OPTIONAL_CMD UPLOAD\n" +"OPTIONAL_CMD SHORT_UPLOAD\n" +"OPTIONAL_CMD DOWNLOAD\n" +"OPTIONAL_CMD SHORT_DOWNLOAD\n" +#ifdef XCP_ENABLE_CAL_PAGE +"OPTIONAL_CMD GET_CAL_PAGE\n" +"OPTIONAL_CMD SET_CAL_PAGE\n" +//"OPTIONAL_CMD CC_GET_PAG_PROCESSOR_INFO\n" +//"OPTIONAL_CMD CC_GET_SEGMENT_INFO\n" +//"OPTIONAL_CMD CC_GET_PAGE_INFO\n" +//"OPTIONAL_CMD CC_SET_SEGMENT_MODE\n" +//"OPTIONAL_CMD CC_GET_SEGMENT_MODE\n" +//"OPTIONAL_CMD CC_COPY_CAL_PAGE\n" +#endif +#ifdef XCP_ENABLE_CHECKSUM +"OPTIONAL_CMD BUILD_CHECKSUM\n" +#endif +//"OPTIONAL_CMD TRANSPORT_LAYER_CMD\n" +//"OPTIONAL_CMD USER_CMD\n" +"OPTIONAL_CMD GET_DAQ_RESOLUTION_INFO\n" +"OPTIONAL_CMD GET_DAQ_PROCESSOR_INFO\n" +#ifdef XCP_ENABLE_DAQ_EVENT_INFO +"OPTIONAL_CMD GET_DAQ_EVENT_INFO\n" +#endif +//"OPTIONAL_CMD GET_DAQ_LIST_INFO\n" +"OPTIONAL_CMD FREE_DAQ\n" +"OPTIONAL_CMD ALLOC_DAQ\n" +"OPTIONAL_CMD ALLOC_ODT\n" +"OPTIONAL_CMD ALLOC_ODT_ENTRY\n" +//"OPTIONAL_CMD CLEAR_DAQ_LIST\n" +//"OPTIONAL_CMD READ_DAQ\n" +"OPTIONAL_CMD SET_DAQ_PTR\n" +"OPTIONAL_CMD WRITE_DAQ\n" +"OPTIONAL_CMD GET_DAQ_LIST_MODE\n" +"OPTIONAL_CMD SET_DAQ_LIST_MODE\n" +"OPTIONAL_CMD START_STOP_SYNCH\n" +"OPTIONAL_CMD START_STOP_DAQ_LIST\n" +"OPTIONAL_CMD GET_DAQ_CLOCK\n" +#if XCP_TRANSPORT_LAYER_TYPE == XCP_TRANSPORT_LAYER_ETH +"OPTIONAL_CMD WRITE_DAQ_MULTIPLE\n" +#if XCP_PROTOCOL_LAYER_VERSION >= 0x0103 +"OPTIONAL_CMD TIME_CORRELATION_PROPERTIES\n" +//"OPTIONAL_CMD DTO_CTR_PROPERTIES\n" +#endif +#if XCP_PROTOCOL_LAYER_VERSION >= 0x0104 +"OPTIONAL_LEVEL1_CMD GET_VERSION\n" +#ifdef XCP_ENABLE_PACKED_MODE +"OPTIONAL_LEVEL1_CMD SET_DAQ_PACKED_MODE\n" +"OPTIONAL_LEVEL1_CMD GET_DAQ_PACKED_MODE\n" +#endif +#endif +#if XCP_PROTOCOL_LAYER_VERSION >= 0x0150 +//"OPTIONAL_LEVEL1_CMD SW_DBG_COMMAND_SPACE\n" +//"OPTIONAL_LEVEL1_CMD POD_COMMAND_SPACE\n" +#endif +#endif // ETH +"/end PROTOCOL_LAYER\n" + +#if XCP_PROTOCOL_LAYER_VERSION >= 0x0103 +/* +"/begin TIME_CORRELATION\n" // TIME +"/end TIME_CORRELATION\n" +*/ +#endif +; + +//---------------------------------------------------------------------------------- +static const char* gA2lIfDataBeginDAQ = // Parameter: %u max event, %s timestamp unit +"/begin DAQ\n" +"DYNAMIC 0 %u 0 OPTIMISATION_TYPE_DEFAULT ADDRESS_EXTENSION_FREE IDENTIFICATION_FIELD_TYPE_RELATIVE_BYTE GRANULARITY_ODT_ENTRY_SIZE_DAQ_BYTE 0xF8 OVERLOAD_INDICATION_PID\n" +"/begin TIMESTAMP_SUPPORTED\n" +"0x01 SIZE_DWORD %s TIMESTAMP_FIXED\n" +"/end TIMESTAMP_SUPPORTED\n"; + +// ... Event list follows, before EndDaq + +//---------------------------------------------------------------------------------- +static const char * const gA2lIfDataEndDAQ = +"/end DAQ\n"; + + +//---------------------------------------------------------------------------------- +// XCP_ON_ETH +static const char* gA2lIfDataEth = // Parameter: %s TCP or UDP, %04X tl version, %u port, %s ip address string, %s TCP or UDP +"/begin XCP_ON_%s_IP\n" // Transport Layer +" 0x%04X %u ADDRESS \"%s\"\n" +//"OPTIONAL_TL_SUBCMD GET_SERVER_ID\n" +//"OPTIONAL_TL_SUBCMD GET_DAQ_ID\n" +//"OPTIONAL_TL_SUBCMD SET_DAQ_ID\n" +#if defined(XCPTL_ENABLE_MULTICAST) && defined(XCP_ENABLE_DAQ_CLOCK_MULTICAST) +" OPTIONAL_TL_SUBCMD GET_DAQ_CLOCK_MULTICAST\n" +#endif +"/end XCP_ON_%s_IP\n" // Transport Layer +; + +//---------------------------------------------------------------------------------- +// XCP_ON_CAN (CAN_FD not implemented yet) +static const char* gA2lIfDataCan = // Parameter: TRANSPORT_LAYER_VERSION, CRO_ID, DTO_ID, BITRATE +"/begin XCP_ON_CAN\n" // Transport Layer +" 0x%04X\n" +" CAN_ID_MASTER 0x%x\n" +" CAN_ID_SLAVE 0x%x\n" +" BAUDRATE %u\n" +" SAMPLE_POINT 0x4B\n" +" SAMPLE_RATE SINGLE\n" +" BTL_CYCLES 0x08\n" +" SJW 0x02\n" +" SYNC_EDGE SINGLE\n" +"/end XCP_ON_CAN\n"; + + +//---------------------------------------------------------------------------------- +static const char* const gA2lIfDataEnd = +"/end IF_DATA\n\n"; + + +//---------------------------------------------------------------------------------- +static const char* const gA2lFooter = + "/end MODULE\n" + "/end PROJECT\n"; + + + +#define printPhysUnit(unit) if (unit != NULL && strlen(unit) > 0) fprintf(gA2lFile, " PHYS_UNIT \"%s\"", unit); +#define printAddrExt(ext) if (ext>0) fprintf(gA2lFile, " ECU_ADDRESS_EXTENSION %u",ext); + +const char* A2lGetSymbolName(const char* instanceName, const char* name) { + static char s[256]; + if (instanceName != NULL && strlen(instanceName) > 0) { + SNPRINTF(s, 256, "%s.%s", instanceName, name); + return s; + } + else { + return name; + } +} + +static const char* getType(int32_t type) { + const char* types; + switch (type) { + case A2L_TYPE_INT8: types = "SBYTE"; break; + case A2L_TYPE_INT16: types = "SWORD"; break; + case A2L_TYPE_INT32: types = "SLONG"; break; + case A2L_TYPE_INT64: types = "A_INT64"; break; + case A2L_TYPE_UINT8: types = "UBYTE"; break; + case A2L_TYPE_UINT16: types = "UWORD"; break; + case A2L_TYPE_UINT32: types = "ULONG"; break; + case A2L_TYPE_UINT64: types = "A_UINT64"; break; + case A2L_TYPE_FLOAT: types = "FLOAT32_IEEE"; break; + case A2L_TYPE_DOUBLE: types = "FLOAT64_IEEE"; break; + default: + types = NULL; + } + return types; +} + +static const char* getTypeMin(int32_t type) { + const char* min; + switch (type) { + case A2L_TYPE_INT8: min = "-128"; break; + case A2L_TYPE_INT16: min = "-32768"; break; + case A2L_TYPE_INT32: min = "-2147483648"; break; + case A2L_TYPE_INT64: min = "-1E12"; break; + case A2L_TYPE_FLOAT: min = "-1E12"; break; + case A2L_TYPE_DOUBLE: min = "-1E12"; break; + default: min = "0"; + } + return min; +} + +static const char* getTypeMax(int32_t type) { + const char* max; + switch (type) { + case A2L_TYPE_INT8: max = "127"; break; + case A2L_TYPE_INT16: max = "32767"; break; + case A2L_TYPE_INT32: max = "2147483647"; break; + case A2L_TYPE_UINT8: max = "255"; break; + case A2L_TYPE_UINT16: max = "65535"; break; + case A2L_TYPE_UINT32: max = "4294967295"; break; + default: max = "1E12"; + } + return max; +} + +static const char* getPhysMin(int32_t type, double factor, double offset) { + double value = 0.0; + switch (type) { + case A2L_TYPE_INT8: value = -128; break; + case A2L_TYPE_INT16: value = -32768; break; + case A2L_TYPE_INT32: value = -(double)2147483648; break; + case A2L_TYPE_INT64: value = -1E12; break; + case A2L_TYPE_FLOAT: value = -1E12; break; + case A2L_TYPE_DOUBLE: value = -1E12; break; + default: value = 0.0; + } + + static char str[20]; + snprintf(str, 20, "%f", factor * value + offset); + return str; +} + +static const char* getPhysMax(int32_t type, double factor, double offset) { + double value = 0.0; + switch (type) { + case A2L_TYPE_INT8: value = 127; break; + case A2L_TYPE_INT16: value = 32767; break; + case A2L_TYPE_INT32: value = 2147483647; break; + case A2L_TYPE_UINT8: value = 255; break; + case A2L_TYPE_UINT16: value = 65535; break; + case A2L_TYPE_UINT32: value = 4294967295; break; + default: value = 1E12; + } + static char str[20]; + snprintf(str, 20, "%f", factor * value + offset); + return str; +} + + +BOOL A2lOpen(const char *filename, const char* projectName ) { + + DBG_PRINTF1("\nCreate A2L %s\n", filename); + gA2lFile = NULL; + gA2lFixedEvent = XCP_INVALID_EVENT; + gA2lMeasurements = gA2lParameters = gA2lTypedefs = gA2lInstances = gA2lConversions = gA2lComponents = 0; + gA2lFile = fopen(filename, "w"); + if (gA2lFile == 0) { + DBG_PRINTF_ERROR("ERROR: Could not create A2L file %s!\n", filename); + return FALSE; + } + + // Create header + fprintf(gA2lFile, gA2lHeader, projectName, projectName); + + // Create standard record layouts for elementary types + for (int i = -10; i <= +10; i++) { + const char* t = getType(i); + if (t != NULL) { + fprintf(gA2lFile, "/begin RECORD_LAYOUT R_%s FNC_VALUES 1 %s ROW_DIR DIRECT /end RECORD_LAYOUT\n", t, t); + fprintf(gA2lFile, "/begin TYPEDEF_MEASUREMENT M_%s \"\" %s NO_COMPU_METHOD 0 0 %s %s /end TYPEDEF_MEASUREMENT\n", t, t, getTypeMin(i), getTypeMax(i)); + fprintf(gA2lFile, "/begin TYPEDEF_CHARACTERISTIC C_%s \"\" VALUE R_%s 0 NO_COMPU_METHOD %s %s /end TYPEDEF_CHARACTERISTIC\n", t, t, getTypeMin(i), getTypeMax(i)); + } + } + fprintf(gA2lFile, "\n"); + + return TRUE; +} + +// Memory segments +void A2lCreate_MOD_PAR(uint32_t startAddr, uint32_t size, char *epk) { + + assert(gA2lFile != NULL); + fprintf(gA2lFile, "/begin MOD_PAR \"\"\n"); + fprintf(gA2lFile, "EPK \"%s\"\n", epk); + fprintf(gA2lFile, "ADDR_EPK 0x%08X\n", ApplXcpGetAddr((uint8_t*)epk)); + fprintf(gA2lFile, gA2lMemorySegment, startAddr, size); + DBG_PRINTF1(" A2L MOD_PAR MEMORY_SEGMENT 1: 0x%08X %u\n", startAddr, size); + fprintf(gA2lFile, "/end MOD_PAR\n\n"); +#if OPTION_ENABLE_DBG_PRINTS + if (epk) DBG_PRINTF1(" A2L MOD_PAR EPK \"%s\" 0x%08X\n", epk, ApplXcpGetAddr((uint8_t*)epk)); +#endif +} + + +static void A2lCreate_IF_DATA_DAQ() { + + assert(gA2lFile != NULL); + +#if defined( XCP_ENABLE_DAQ_EVENT_LIST ) && !defined( XCP_ENABLE_DAQ_EVENT_INFO ) + tXcpEvent* eventList; +#endif + uint16_t eventCount = 0; + +#if (XCP_TIMESTAMP_UNIT==DAQ_TIMESTAMP_UNIT_1NS) +#define XCP_TIMESTAMP_UNIT_S "UNIT_1NS" +#elif (XCP_TIMESTAMP_UNIT==DAQ_TIMESTAMP_UNIT_1US) +#define XCP_TIMESTAMP_UNIT_S "UNIT_1US" +#else +#error +#endif + + // Event list in A2L file (if event info by XCP is not active) +#if defined( XCP_ENABLE_DAQ_EVENT_LIST ) && !defined( XCP_ENABLE_DAQ_EVENT_INFO ) + eventList = XcpGetEventList(&eventCount); +#endif + + fprintf(gA2lFile, gA2lIfDataBeginDAQ, eventCount, XCP_TIMESTAMP_UNIT_S); + + // Eventlist +#if defined( XCP_ENABLE_DAQ_EVENT_LIST ) && !defined( XCP_ENABLE_DAQ_EVENT_INFO ) + for (uint32_t i = 0; i < eventCount; i++) { + + fprintf(gA2lFile, "/begin EVENT \"%s\" \"%s\" 0x%X DAQ 0xFF %u %u %u CONSISTENCY EVENT", eventList[i].shortName, eventList[i].shortName, i, eventList[i].timeCycle, eventList[i].timeUnit, eventList[i].priority); +#ifdef XCP_ENABLE_PACKED_MODE + if (eventList[i].sampleCount != 0) { + fprintf(gA2lFile, " /begin DAQ_PACKED_MODE ELEMENT_GROUPED STS_LAST MANDATORY %u /end DAQ_PACKED_MODE", eventList[i].sampleCount); + } +#endif + fprintf(gA2lFile, " /end EVENT\n"); + } +#endif + + fprintf(gA2lFile, gA2lIfDataEndDAQ); + +} + +void A2lCreate_ETH_IF_DATA(BOOL useTCP, const uint8_t* addr, uint16_t port) { + + fprintf(gA2lFile, gA2lIfDataBegin); + + // Protocol Layer info + fprintf(gA2lFile, gA2lIfDataProtocolLayer, XCP_PROTOCOL_LAYER_VERSION, XCPTL_MAX_CTO_SIZE, XCPTL_MAX_DTO_SIZE); + + // DAQ info + A2lCreate_IF_DATA_DAQ(); + + // Transport Layer info + uint8_t addr0[] = { 127,0,0,1 }; // Use localhost if no other option + if (addr != NULL && addr[0] != 0) { + memcpy(addr0, addr, 4); + } else { + socketGetLocalAddr(NULL, addr0); + } + char addrs[17]; + SPRINTF(addrs, "%u.%u.%u.%u", addr0[0], addr0[1], addr0[2], addr0[3]); + char* prot = useTCP ? (char*)"TCP" : (char*)"UDP"; + fprintf(gA2lFile, gA2lIfDataEth, prot, XCP_TRANSPORT_LAYER_VERSION, port, addrs, prot); + + fprintf(gA2lFile, gA2lIfDataEnd); + + DBG_PRINTF1(" IF_DATA XCP_ON_%s, ip=%s, port=%u\n", prot, addrs, port); +} + +void A2lCreate_CAN_IF_DATA(BOOL useCANFD, uint16_t croId, uint16_t dtoId, uint32_t bitRate) { + + (void)useCANFD; + + fprintf(gA2lFile, gA2lIfDataBegin); + + // Protocol Layer info + fprintf(gA2lFile, gA2lIfDataProtocolLayer, XCP_PROTOCOL_LAYER_VERSION, XCPTL_MAX_CTO_SIZE, XCPTL_MAX_DTO_SIZE); + + // DAQ info + A2lCreate_IF_DATA_DAQ(); + + // Transport Layer info + uint32_t _croId = croId; + uint32_t _dtoId = dtoId; + if (useCANFD) { + _croId |= 0x40000000; + _dtoId |= 0x40000000; + } + fprintf(gA2lFile, gA2lIfDataCan, XCP_TRANSPORT_LAYER_VERSION, _croId, _dtoId, bitRate); + + fprintf(gA2lFile, gA2lIfDataEnd); + + DBG_PRINTF1(" IF_DATA XCP_ON_CAN, CRO=%u, DTO=%u, BITRATE=%u\n", croId, dtoId, bitRate); +} + + +void A2lCreateMeasurement_IF_DATA() { + + assert(gA2lFile != NULL); + if (gA2lFixedEvent != XCP_INVALID_EVENT) { + fprintf(gA2lFile, " /begin IF_DATA XCP /begin DAQ_EVENT FIXED_EVENT_LIST EVENT 0x%X /end DAQ_EVENT /end IF_DATA", gA2lFixedEvent); + } + else if (gA2lDefaultEvent != XCP_INVALID_EVENT) { + fprintf(gA2lFile, " /begin IF_DATA XCP /begin DAQ_EVENT VARIABLE DEFAULT_EVENT_LIST EVENT 0x%X /end DAQ_EVENT /end IF_DATA", gA2lDefaultEvent); + } +} + + +void A2lSetDefaultEvent(uint16_t event) { + +#if defined( XCP_ENABLE_DAQ_EVENT_LIST ) && !defined( XCP_ENABLE_DAQ_EVENT_INFO ) + uint16_t eventCount = 0; + XcpGetEventList(&eventCount); + assert(event >= 0 && event < eventCount); +#endif + + A2lRstFixedEvent(); + gA2lDefaultEvent = event; +} + +void A2lSetFixedEvent(uint16_t event) { + +#if defined( XCP_ENABLE_DAQ_EVENT_LIST ) && !defined( XCP_ENABLE_DAQ_EVENT_INFO ) + uint16_t eventCount = 0; + XcpGetEventList(&eventCount); + assert(event >= 0 && event < eventCount); +#endif + + gA2lFixedEvent = event; +} + +uint16_t A2lGetFixedEvent() { + return gA2lFixedEvent; +} + +void A2lRstDefaultEvent() { + gA2lDefaultEvent = XCP_INVALID_EVENT; +} + +void A2lRstFixedEvent() { + gA2lFixedEvent = XCP_INVALID_EVENT; +} + + +void A2lTypedefBegin_(const char* name, uint32_t size, const char* comment) { + + assert(gA2lFile != NULL); + fprintf(gA2lFile,"/begin TYPEDEF_STRUCTURE %s \"%s\" 0x%X SYMBOL_TYPE_LINK \"%s\"\n", name, comment, size, name); + gA2lTypedefs++; +} + +void A2lTypedefMeasurementComponent_(const char* name, int32_t type, uint32_t offset) { + + assert(gA2lFile != NULL); + fprintf(gA2lFile, " /begin STRUCTURE_COMPONENT %s M_%s 0x%X SYMBOL_TYPE_LINK \"%s\" /end STRUCTURE_COMPONENT\n", name, getType(type), offset, name); + gA2lComponents++; +} + +void A2lTypedefParameterComponent_(const char* name, int32_t type, uint32_t offset) { + + assert(gA2lFile != NULL); + fprintf(gA2lFile, " /begin STRUCTURE_COMPONENT %s C_%s 0x%X SYMBOL_TYPE_LINK \"%s\" /end STRUCTURE_COMPONENT\n", name, getType(type), offset, name); + gA2lComponents++; +} + +void A2lTypedefEnd_() { + + assert(gA2lFile != NULL); + fprintf(gA2lFile,"/end TYPEDEF_STRUCTURE\n"); +} + + +void A2lCreateTypedefInstance_(const char* instanceName, const char* typeName, uint8_t ext, uint32_t addr, const char* comment) { + + assert(gA2lFile != NULL); + fprintf(gA2lFile, "/begin INSTANCE %s \"%s\" %s 0x%X", instanceName, comment, typeName, addr); + printAddrExt(ext); + A2lCreateMeasurement_IF_DATA(); + fprintf(gA2lFile, " /end INSTANCE\n"); + gA2lInstances++; + +} + + +void A2lCreateMeasurement_(const char* instanceName, const char* name, int32_t type, uint8_t ext, uint32_t addr, double factor, double offset, const char* unit, const char* comment) { + + assert(gA2lFile != NULL); +#ifdef A2L_ENABLE_MEMORY_CHECK + mem_check(name, type, ext, addr); +#endif + if (unit == NULL) unit = ""; + if (comment == NULL) comment = ""; + const char *conv = "NO"; + if (factor != 0.0 || offset != 0.0) { + fprintf(gA2lFile, "/begin COMPU_METHOD %s.Conversion \"\" LINEAR \"%%6.3\" \"%s\" COEFFS_LINEAR %g %g /end COMPU_METHOD\n", name, unit!=NULL?unit:"", factor,offset); + conv = name; + gA2lConversions++; + } + + //fprintf(gA2lFile, "/begin MEASUREMENT %s \"%s\" %s %s.Conversion 0 0 %s %s ECU_ADDRESS 0x%X", A2lGetSymbolName(instanceName, name), comment, getType(type), conv, getTypeMin(type), getTypeMax(type), addr); + fprintf(gA2lFile, "/begin MEASUREMENT %s \"%s\" %s %s.Conversion 0 0 %s %s ECU_ADDRESS 0x%X", A2lGetSymbolName(instanceName, name), comment, getType(type), conv, getPhysMin(type, factor, offset), getPhysMax(type, factor, offset), addr); + printAddrExt(ext); + printPhysUnit(unit); + fprintf(gA2lFile, " READ_WRITE"); +#if OPTION_ENABLE_A2L_SYMBOL_LINKS + fprintf(gA2lFile, " SYMBOL_LINK \"%s\" %u", A2lGetSymbolName(instanceName, name), 0); +#else + (void)symbolLink; +#endif + A2lCreateMeasurement_IF_DATA(); + fprintf(gA2lFile, " /end MEASUREMENT\n"); + gA2lMeasurements++; +} + + +void A2lCreateMeasurementArray_(const char* instanceName, const char* name, int32_t type, int dim, uint8_t ext, uint32_t addr) { + + assert(gA2lFile != NULL); + fprintf(gA2lFile, "/begin CHARACTERISTIC %s \"\" VAL_BLK 0x%X R_%s 0 NO_COMPU_METHOD %s %s MATRIX_DIM %u", A2lGetSymbolName(instanceName, name), addr, getType(type), getTypeMin(type), getTypeMax(type), dim); + printAddrExt(ext); +#if OPTION_ENABLE_A2L_SYMBOL_LINKS + fprintf(gA2lFile, " SYMBOL_LINK \"%s\" %u", A2lGetSymbolName(instanceName, name), 0); +#endif + A2lCreateMeasurement_IF_DATA(); + fprintf(gA2lFile, " /end CHARACTERISTIC\n"); + gA2lMeasurements++; +} + + +void A2lCreateParameterWithLimits_(const char* name, int32_t type, uint8_t ext, uint32_t addr, const char* comment, const char* unit, double min, double max) { + + assert(gA2lFile != NULL); + fprintf(gA2lFile, "/begin CHARACTERISTIC %s \"%s\" VALUE 0x%X R_%s 0 NO_COMPU_METHOD %g %g", name, comment, addr, getType(type), min, max); + printPhysUnit(unit); + printAddrExt(ext); +#if OPTION_ENABLE_A2L_SYMBOL_LINKS + fprintf(gA2lFile, " SYMBOL_LINK \"%s\" %u", name, 0); +#endif + fprintf(gA2lFile, " /end CHARACTERISTIC\n"); + gA2lParameters++; +} + +void A2lCreateParameter_(const char* name, int32_t type, uint8_t ext, uint32_t addr, const char* comment, const char* unit) { + + assert(gA2lFile != NULL); + fprintf(gA2lFile, "/begin CHARACTERISTIC %s \"%s\" VALUE 0x%X R_%s 0 NO_COMPU_METHOD %s %s", name, comment, addr, getType(type), getTypeMin(type), getTypeMax(type)); + printPhysUnit(unit); + printAddrExt(ext); +#if OPTION_ENABLE_A2L_SYMBOL_LINKS + fprintf(gA2lFile, " SYMBOL_LINK \"%s\" %u", name, 0); +#endif + fprintf(gA2lFile, " /end CHARACTERISTIC\n"); + gA2lParameters++; +} + +void A2lCreateMap_(const char* name, int32_t type, uint8_t ext, uint32_t addr, uint32_t xdim, uint32_t ydim, const char* comment, const char* unit) { + + assert(gA2lFile != NULL); + fprintf(gA2lFile, + "/begin CHARACTERISTIC %s \"%s\" MAP 0x%X R_%s 0 NO_COMPU_METHOD %s %s" + " /begin AXIS_DESCR FIX_AXIS NO_INPUT_QUANTITY NO_COMPU_METHOD %u 0 %u FIX_AXIS_PAR_DIST 0 1 %u /end AXIS_DESCR" + " /begin AXIS_DESCR FIX_AXIS NO_INPUT_QUANTITY NO_COMPU_METHOD %u 0 %u FIX_AXIS_PAR_DIST 0 1 %u /end AXIS_DESCR", + name, comment, addr, getType(type), getTypeMin(type), getTypeMax(type), xdim, xdim-1, xdim, ydim, ydim-1, ydim); + printPhysUnit(unit); + printAddrExt(ext); +#if OPTION_ENABLE_A2L_SYMBOL_LINKS + fprintf(gA2lFile, " SYMBOL_LINK \"%s\" %u", name, 0); +#endif + fprintf(gA2lFile, " /end CHARACTERISTIC\n"); + gA2lParameters++; +} + +void A2lCreateCurve_(const char* name, int32_t type, uint8_t ext, uint32_t addr, uint32_t xdim, const char* comment, const char* unit) { + + assert(gA2lFile != NULL); + fprintf(gA2lFile, + "/begin CHARACTERISTIC %s \"%s\" CURVE 0x%X R_%s 0 NO_COMPU_METHOD %s %s" + " /begin AXIS_DESCR FIX_AXIS NO_INPUT_QUANTITY NO_COMPU_METHOD %u 0 %u FIX_AXIS_PAR_DIST 0 1 %u /end AXIS_DESCR", + name, comment, addr, getType(type), getTypeMin(type), getTypeMax(type), xdim, xdim-1, xdim); + printPhysUnit(unit); + printAddrExt(ext); +#if OPTION_ENABLE_A2L_SYMBOL_LINKS + fprintf(gA2lFile, " SYMBOL_LINK \"%s\" %u", name, 0); +#endif + fprintf(gA2lFile, " /end CHARACTERISTIC\n"); + gA2lParameters++; +} + + +void A2lParameterGroup(const char* name, int count, ...) { + + va_list ap; + + assert(gA2lFile != NULL); + fprintf(gA2lFile, "/begin GROUP %s \"\"", name); + fprintf(gA2lFile, " /begin REF_CHARACTERISTIC\n"); + va_start(ap, count); + for (int i = 0; i < count; i++) { + fprintf(gA2lFile, " %s", va_arg(ap, char*)); + } + va_end(ap); + fprintf(gA2lFile, "\n/end REF_CHARACTERISTIC "); + fprintf(gA2lFile, "/end GROUP\n\n"); +} + + +void A2lParameterGroupFromList(const char* name, const char* pNames[], size_t count) { + + assert(gA2lFile != NULL); + fprintf(gA2lFile, "/begin GROUP %s \"\"", name); + fprintf(gA2lFile, " /begin REF_CHARACTERISTIC\n"); + for (size_t i = 0; i < count; i++) { + fprintf(gA2lFile, " %s", pNames[i]); + } + fprintf(gA2lFile, "\n/end REF_CHARACTERISTIC "); + fprintf(gA2lFile, "/end GROUP\n\n"); +} + + +void A2lMeasurementGroup(const char* name, int count, ...) { + + va_list ap; + + assert(gA2lFile != NULL); + fprintf(gA2lFile, "/begin GROUP %s \"\"", name); + fprintf(gA2lFile, " /begin REF_MEASUREMENT"); + va_start(ap, count); + for (int i = 0; i < count; i++) { + fprintf(gA2lFile, " %s", va_arg(ap, char*)); + } + va_end(ap); + fprintf(gA2lFile, " /end REF_MEASUREMENT"); + fprintf(gA2lFile, " /end GROUP\n\n"); +} + + +void A2lMeasurementGroupFromList(const char *name, char* names[], uint32_t count) { + + assert(gA2lFile != NULL); + fprintf(gA2lFile, "/begin GROUP %s \"\" \n", name); + fprintf(gA2lFile, " /begin REF_MEASUREMENT"); + for (uint32_t i1 = 0; i1 < count; i1++) { + fprintf(gA2lFile, " %s", names[i1]); + } + fprintf(gA2lFile, " /end REF_MEASUREMENT"); + fprintf(gA2lFile, "\n/end GROUP\n"); +} + + +void A2lClose() { + + if (gA2lFile != NULL) { + fprintf(gA2lFile, "%s", gA2lFooter); + fclose(gA2lFile); + gA2lFile = NULL; + DBG_PRINTF1("A2L created: %u measurements, %u params, %u typedefs, %u components, %u instances, %u conversions\n\n", + gA2lMeasurements, gA2lParameters, gA2lTypedefs, gA2lComponents, gA2lInstances, gA2lConversions); + } +} + + + + diff --git a/A2lTestDlg/A2lTestDlg/A2L.h b/A2lTestDlg/A2lTestDlg/A2L.h new file mode 100644 index 0000000..a839827 --- /dev/null +++ b/A2lTestDlg/A2lTestDlg/A2L.h @@ -0,0 +1,121 @@ +#pragma once +/* A2L.h */ + +/* Copyright(c) Vector Informatik GmbH.All rights reserved. + Licensed under the MIT license.See LICENSE file in the project root for details. */ + +#define OPTION_ENABLE_A2L_SYMBOL_LINKS ON // Enable generation of symbol links (required for CANape integrated linker map update) + + +#define A2L_TYPE_UINT8 1 +#define A2L_TYPE_UINT16 2 +#define A2L_TYPE_UINT32 4 +#define A2L_TYPE_UINT64 8 +#define A2L_TYPE_INT8 -1 +#define A2L_TYPE_INT16 -2 +#define A2L_TYPE_INT32 -4 +#define A2L_TYPE_INT64 -8 +#define A2L_TYPE_FLOAT -9 +#define A2L_TYPE_DOUBLE -10 + +#define A2L_TYPE_BOOL sizeof(BOOL) + +#ifndef A2lGetAddr + #define A2lGetAddr(p) ApplXcpGetAddr(p) +#endif + +#ifdef __cplusplus + +#include + +#ifndef A2lGetType +#define A2lGetSign_(var) ((int)(typeid(var).name()[0]=='u'?+1:-1)) +#define A2lGetType(var) (A2lGetSign_(var)*(typeid(var).name()[0]=='f'?9:typeid(var).name()[0]=='d'?10:sizeof(var))) +#endif +#ifndef A2lGetOffset +#define A2lGetOffset(var) (uint32_t)((uint8_t*)&(var) - (uint8_t*)this) +#endif + + // Create parameters +#define A2lCreateParameter(name,comment,unit) A2lCreateParameter_(#name, A2lGetType(name), 0, A2lGetAddr((uint8_t*)&name), comment, unit) +#define A2lCreateParameterWithLimits(name,comment,unit,min,max) A2lCreateParameterWithLimits_(#name, A2lGetType(name), 0, A2lGetAddr((uint8_t*)&name), comment, unit, min, max) +#define A2lCreateCurve(name,xdim,comment,unit) A2lCreateCurve_(#name, A2lGetType(name[0]), 0, A2lGetAddr((uint8_t*)&name[0]), xdim, comment, unit) +#define A2lCreateMap(name,xdim,ydim,comment,unit) A2lCreateMap_(#name, A2lGetType(name[0][0]), 0, A2lGetAddr((uint8_t*)&name[0][0]), xdim, ydim, comment, unit) + +// Create measurements +#define A2lCreateMeasurement(name,comment) A2lCreateMeasurement_(NULL, #name, A2lGetType(name), 0, A2lGetAddr((uint8_t*)&(name)), 1.0, 0.0, NULL, comment) +#define A2lCreatePhysMeasurement(name,comment,factor,offset,unit) A2lCreateMeasurement_(NULL, #name, A2lGetType(name), 0, A2lGetAddr((uint8_t*)&name), factor, offset, unit, comment) // unsigned integer (8/16/32) with linear physical conversion rule +#define A2lCreateMeasurementArray(name) A2lCreateMeasurementArray_(NULL,#name, A2lGetType(name[0]), sizeof(name)/sizeof(name[0]), 0, A2lGetAddr((uint8_t*)&name[0])) // unsigned integer (8/16/32) or double array + +// Create typedefs +#define A2lTypedefComponent(name) A2lTypedefMeasurementComponent_(#name, A2lGetType(name), A2lGetOffset(name)) + +#else + +// Create parameters +#define A2lCreateParameter(name,type,comment,unit) A2lCreateParameter_(#name, type, 0, A2lGetAddr((uint8_t*)&name), comment, unit) +#define A2lCreateParameterWithLimits(name,type,comment,unit,min,max) A2lCreateParameterWithLimits_(#name, type, 0, A2lGetAddr((uint8_t*)&name), comment, unit, min, max) +#define A2lCreateCurve(name,type,xdim,comment,unit) A2lCreateCurve_(#name, type, 0, A2lGetAddr((uint8_t*)&name[0]), xdim, comment, unit) +#define A2lCreateMap(name,type,xdim,ydim,comment,unit) A2lCreateMap_(#name, type, 0, A2lGetAddr((uint8_t*)&name[0][0]), xdim, ydim, comment, unit) + +// Create measurements +#define A2lCreateMeasurement(name,type,comment) A2lCreateMeasurement_(NULL,#name,type, 0, A2lGetAddr((uint8_t*)&(name)), 1.0, 0.0, NULL, comment) +#define A2lCreatePhysMeasurement(name,type,comment,factor,offset,unit) A2lCreateMeasurement_(NULL, #name,type, 0, A2lGetAddr((uint8_t*)&name), factor, offset, unit, comment) // unsigned integer (8/16/32) with linear physical conversion rule +#define A2lCreateMeasurementArray(name,type) A2lCreateMeasurementArray_(NULL, #name, type, sizeof(name)/sizeof(name[0]), 0, A2lGetAddr((uint8_t*)&name[0])) // unsigned integer (8/16/32) or double array + +// Create typedefs +#define A2lTypedefComponent(name,type,offset) A2lTypedefMeasurementComponent_(#name, type, offset) + +#endif + +#define A2lTypedefBegin(name,comment) A2lTypedefBegin_(#name,(uint32_t)sizeof(name),comment) +#define A2lTypedefEnd() A2lTypedefEnd_() +#define A2lCreateTypedefInstance(instanceName, typeName, addr, comment) A2lCreateTypedefInstance_(instanceName, typeName, 0, A2lGetAddr((uint8_t*)&instanceName), comment) +#define A2lCreateDynTypedefInstance(instanceName, typeName, comment) A2lCreateTypedefInstance_(instanceName, typeName, 1, 0, comment) + +// Init A2L generation +extern BOOL A2lOpen(const char *filename, const char* projectName); + +// Create memory segments +extern void A2lCreate_MOD_PAR( uint32_t startAddr, uint32_t size, char* epk); + +// Create XCP IF_DATA +extern void A2lCreate_ETH_IF_DATA(BOOL useTCP, const uint8_t* addr, uint16_t port); +extern void A2lCreate_CAN_IF_DATA(BOOL useCANFD, uint16_t croId, uint16_t dtoId, uint32_t bitRate); + +// Set fixec or default event for all following creates +extern void A2lSetFixedEvent(uint16_t event); +extern void A2lRstFixedEvent(); +extern void A2lSetDefaultEvent(uint16_t event); +extern void A2lRstDefaultEvent(); + +// Create measurements +extern void A2lCreateMeasurement_(const char* instanceName, const char* name, int32_t type, uint8_t ext, uint32_t addr, double factor, double offset, const char* unit, const char* comment); +extern void A2lCreateMeasurementArray_(const char* instanceName, const char* name, int32_t type, int dim, uint8_t ext, uint32_t addr); + +// Create typedefs +void A2lTypedefBegin_(const char* name, uint32_t size, const char* comment); +void A2lTypedefMeasurementComponent_(const char* name, int32_t type, uint32_t offset); +void A2lTypedefParameterComponent_(const char* name, int32_t type, uint32_t offset); +void A2lTypedefEnd_(); +void A2lCreateTypedefInstance_(const char* instanceName, const char* typeName, uint8_t ext, uint32_t addr, const char* comment); + +// Create parameters +void A2lCreateParameter_(const char* name, int32_t type, uint8_t ext, uint32_t addr, const char* comment, const char* unit); +void A2lCreateParameterWithLimits_(const char* name, int32_t type, uint8_t ext, uint32_t addr, const char* comment, const char* unit, double min, double max); +void A2lCreateMap_(const char* name, int32_t type, uint8_t ext, uint32_t addr, uint32_t xdim, uint32_t ydim, const char* comment, const char* unit); +void A2lCreateCurve_(const char* name, int32_t type, uint8_t ext, uint32_t addr, uint32_t xdim, const char* comment, const char* unit); + +// Create groups +void A2lParameterGroup(const char* name, int count, ...); +void A2lParameterGroupFromList(const char* name, const char* pNames[], size_t count); +void A2lMeasurementGroup(const char* name, int count, ...); +void A2lMeasurementGroupFromList(const char *name, char* names[], uint32_t count); + +// Finish A2L generation +extern void A2lClose(); + + +// For A2L.CPP +extern const char* A2lGetSymbolName(const char* instanceName, const char* name); +extern uint16_t A2lGetFixedEvent(); diff --git a/A2lTestDlg/A2lTestDlg/A2Lpp.cpp b/A2lTestDlg/A2lTestDlg/A2Lpp.cpp new file mode 100644 index 0000000..5f832b7 --- /dev/null +++ b/A2lTestDlg/A2lTestDlg/A2Lpp.cpp @@ -0,0 +1,124 @@ +/*---------------------------------------------------------------------------- +| File: +| A2L.cpp +| +| Description: +| Create A2L file +| +| Copyright (c) Vector Informatik GmbH. All rights reserved. +| Licensed under the MIT license. See LICENSE file in the project root for details. +| + ----------------------------------------------------------------------------*/ + +#include "main.h" +#include "platform.h" +#include "xcp.hpp" +#include "A2L.h" +#include "A2Lpp.hpp" + + //--------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + + A2L::A2L(const char * name) { + + filename = name; + } + + A2L::~A2L() { + + close(); + } + +void A2L::close() { + + A2lClose(); + } + +BOOL A2L::open(const char *projectName) { + + return A2lOpen(filename, projectName); +} + +// Create memory segments +void A2L::create_MOD_PAR(uint32_t startAddr, uint32_t size) { + A2lCreate_MOD_PAR(startAddr, size, NULL); +} + +// Create XCP IF_DATA +void A2L::create_XCP_IF_DATA(BOOL tcp, const uint8_t* addr, uint16_t port) { + + A2lCreate_ETH_IF_DATA(tcp, addr, port); +} + + +//--------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + +void A2L::setDefaultEvent(uint16_t e) { + A2lSetDefaultEvent(e); +} + +void A2L::setFixedEvent(uint16_t e) { + A2lSetFixedEvent(e); +} + +void A2L::rstFixedEvent() { + A2lRstFixedEvent(); +} + +uint16_t A2L::getFixedEvent() { + return A2lGetFixedEvent(); +} + + //--------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + + void A2L::createTypedefBegin_(const char* name, int32_t size, const char* comment) { + A2lTypedefBegin_(name,size,comment); +} + + void A2L::createTypedefMeasurementComponent_(const char* name, int32_t type, uint32_t offset) { + A2lTypedefMeasurementComponent_(name,type,offset); + } + + void A2L::createTypedefParameterComponent_(const char* name, int32_t type, uint32_t offset) { + A2lTypedefParameterComponent_(name, type, offset); + } + + void A2L::createTypedefEnd_() { + A2lTypedefEnd_(); +} + + + void A2L::createTypedefInstance_(const char* instanceName, const char* typeName, uint8_t ext, uint32_t addr, const char* comment) { + A2lCreateTypedefInstance_(instanceName, typeName, ext, addr, comment); +} + + //--------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + + void A2L::createMeasurement_(const char* instanceName, const char* name, int32_t type, uint8_t ext, uint32_t addr, double factor, double offset, const char* unit, const char* comment) { + A2lCreateMeasurement_(instanceName, name, type, ext, addr, factor, offset, unit, comment); +} + + void A2L::createMeasurementArray_(const char* instanceName, const char* name, int32_t type, int dim, uint8_t ext, uint32_t addr) { + A2lCreateMeasurementArray_(instanceName, name, type, dim, ext, addr); +} + + //--------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + + void A2L::createParameterWithLimits_(const char* instanceName, const char* name, int32_t type, uint8_t ext, uint32_t addr, const char* comment, const char* unit, double min, double max) { + A2lCreateParameterWithLimits_(A2lGetSymbolName(instanceName, name), type, ext, addr, comment, unit, min, max); +} + + + void A2L::createParameter_(const char* instanceName, const char* name, int32_t type, uint8_t ext, uint32_t addr, const char* comment, const char* unit) { + A2lCreateParameter_(A2lGetSymbolName(instanceName, name), type, ext, addr, comment, unit); +} + + void A2L::createMap_(const char* instanceName, const char* name, int32_t type, uint8_t ext, uint32_t addr, uint32_t xdim, uint32_t ydim, const char* comment, const char* unit) { + A2lCreateMap_(A2lGetSymbolName(instanceName, name), type, ext, addr, xdim, ydim, comment, unit); +} + + void A2L::createCurve_(const char* instanceName, const char* name, int32_t type, uint8_t ext, uint32_t addr, uint32_t xdim, const char* comment, const char* unit) { + A2lCreateCurve_(A2lGetSymbolName(instanceName, name), type, ext, addr, xdim, comment, unit); +} + + + \ No newline at end of file diff --git a/A2lTestDlg/A2lTestDlg/A2Lpp.hpp b/A2lTestDlg/A2lTestDlg/A2Lpp.hpp new file mode 100644 index 0000000..c9ccb42 --- /dev/null +++ b/A2lTestDlg/A2lTestDlg/A2Lpp.hpp @@ -0,0 +1,122 @@ +#pragma once +/* A2L.h - A2L Generator */ + +/* Copyright(c) Vector Informatik GmbH.All rights reserved. + Licensed under the MIT license.See LICENSE file in the project root for details. */ + +#ifndef __cplusplus +#error +#endif + +#include "A2L.h" + + +#define A2lGetSign_(var) ((int)(typeid(var).name()[0]=='u'?+1:-1)) +#define A2lGetType_(var) (A2lGetSign_(var)*(typeid(var).name()[0]=='f'?9:typeid(var).name()[0]=='d'?10:sizeof(var))) +#define A2lGetAddr_(var) Xcp::getInstance()->getA2lAddr((uint8_t*)&var) +#define A2lGetOffset_(struct_name,full_name) (uint16_t)((uint8_t*)&(full_name) - (uint8_t*)&struct_name) + + +//--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + +// Create typedefs +#define createTypedefBegin(name,comment) createTypedefBegin_(#name,(int)sizeof(name),comment) +#define createTypedefParameterComponent(struct_name,var_name) createTypedefParameterComponent_(#var_name,A2lGetType_(struct_name.var_name),A2lGetOffset_(struct_name,struct_name.var_name)) +#define createTypedefMeasurementComponent(struct_name,var_name) createTypedefMeasurementComponent_(#var_name,A2lGetType_(struct_name.var_name),A2lGetOffset_(struct_name,struct_name.var_name)) +#define createTypedefEnd() createTypedefEnd_() + +// Create measurement or parameter from typedef +#define createTypedefInstance(instanceName,typeName,comment) createTypedefInstance_(#instanceName, #typeName, 0, A2lGetAddr_(instanceName), comment) + +// Create measurements +#define createMeasurement(name,comment) createMeasurement_(NULL,#name,A2lGetType_(name),0,A2lGetAddr_(name),1.0,0.0,NULL,comment) +#define createPhysMeasurement(name,comment,factor,offset,unit) createMeasurement_(NULL,#name,A2lGetType_(name),0,A2lGetAddr_(name),factor,offset,unit,comment) // unsigned integer (8/16/32) with linear physical conversion rule +#define createMeasurementArray(name) createMeasurementArray_(NULL,#name,A2lGetType_(name[0]),sizeof(name)/sizeof(name[0]),0,A2lGetAddr_(name[0])) // unsigned integer (8/16/32) or double array + +// Create parameters +#define createParameter(name,comment,unit) createParameter_(NULL,#name,A2lGetType_(name),0,A2lGetAddr_(name),comment,unit) +#define createParameterWithLimits(name,comment,unit,min,max) createParameterWithLimits_(NULL,#name, A2lGetType_(name), 0, A2lGetAddr_(name), comment, unit, min, max) +#define createCurve(name,xdim,comment,unit) createCurve_(NULL,#name, A2lGetType_(name[0]), 0, A2lGetAddr_(name[0]), xdim, comment, unit) +#define createMap(name,xdim,ydim,comment,unit) createMap_(NULL,#name, A2lGetType_(name[0][0]), 0, A2lGetAddr_(name[0][0]), xdim, ydim, comment, unit) + + +//--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + +// The functions below are assumed to be called from methods of classes derived from XcpObject ! + +#define A2lGetDynAddr_(var) xcpGetA2lDynAddr(A2lGetDynOffset_(var)) +#define A2lGetDynBaseAddr_() xcpGetA2lDynAddr(0) +#define A2lGetDynOffset_(var) (uint16_t)((uint8_t*)&(var) - (uint8_t*)this) // object data size limited to 64K ! + +// Create measurement or parameter from typedef +#define createDynTypedefInstance(instanceName,typeName,comment) createTypedefInstance_(instanceName, typeName, 1, A2lGetDynBaseAddr_(), comment) +#define createDynTypedefParameterComponent(name) createTypedefParameterComponent_(#name,A2lGetType_(name),A2lGetDynOffset_(name)) +#define createDynTypedefMeasurementComponent(name) createTypedefMeasurementComponent_(#name,A2lGetType_(name),A2lGetDynOffset_(name)) + +// Create measurements +#define createDynMeasurement(instanceName,name,comment) createMeasurement_(instanceName,#name,A2lGetType_(name),1,A2lGetDynAddr_(name),1.0,0.0,NULL,comment) +#define createDynPhysMeasurement(instanceName,name,var,comment,factor,offset,unit) createMeasurement_(instanceName,name,A2lGetType_(var),1,A2lGetDynAddr_(name),factor,offset,unit,comment) // named unsigned integer (8/16/32) with linear physical conversion rule +#define createDynMeasurementArray(name) createMeasurementArray_(NULL,#name,A2lGetType_(name[0]),sizeof(name)/sizeof(name[0]),0,A2lGetDynAddr_(name[0])) // unsigned integer (8/16/32) or double array + +// Create parameters +#define createDynParameter(instanceName,name,comment,unit) createParameter_(instanceName,#name,A2lGetType_(name),1,A2lGetDynAddr_(name),comment,unit) +#define createDynParameterWithLimits(instanceName,name,comment,unit,min,max) createParameterWithLimits_(instanceName,#name, A2lGetType_(name), 1, A2lGetDynAddr_(name), comment, unit, min, max) +#define createDynCurve(instanceName,name,xdim,comment,unit) createCurve_(instanceName,#name, A2lGetType_(name[0]), 0, A2lGetDynAddr_(name[0]), xdim, comment, unit) +#define createDynMap(instanceName,name,xdim,ydim,comment,unit) createMap_(instanceName,#name, A2lGetType_(name[0][0]), 1, A2lGetDynAddr_(name[0][0]), xdim, ydim, comment, unit) + + + + +//--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + + +class A2L { + +private: + + const char* filename; + +public: + + + A2L(const char* filename); + ~A2L(); + + // Start A2L generation + BOOL open(const char* projectName); + + // Create memory segments + void create_MOD_PAR(uint32_t startAddr, uint32_t size); + + // Create IF_DATA for XCP + // All XCP events must have been be created before + void create_XCP_IF_DATA(BOOL tcp, const uint8_t* addr, uint16_t port); + + // Set XCP events for all following creates + void setFixedEvent(uint16_t xcp_event); + void setDefaultEvent(uint16_t xcp_event); + void rstFixedEvent(); + uint16_t getFixedEvent(); + + // Create measurements + void createMeasurement_(const char* instanceName, const char* name, int32_t type, uint8_t ext, uint32_t addr, double factor, double offset, const char* unit, const char* comment); + void createMeasurementArray_(const char* instanceName, const char* name, int32_t type, int32_t dim, uint8_t ext, uint32_t addr); + + // Create typedefs + void createTypedefBegin_(const char* name, int32_t size, const char* comment); + void createTypedefParameterComponent_(const char* name, int32_t type, uint32_t offset); + void createTypedefMeasurementComponent_(const char* name, int32_t type, uint32_t offset); + void createTypedefEnd_(); + void createTypedefInstance_(const char* instanceName, const char* typeName, uint8_t ext, uint32_t addr, const char* comment); + + // Create parameters + void createParameter_(const char* instanceName, const char* name, int32_t type, uint8_t ext, uint32_t addr, const char* comment, const char* unit); + void createParameterWithLimits_(const char* instanceName, const char* name, int32_t type, uint8_t ext, uint32_t addr, const char* comment, const char* unit, double min, double max); + void createMap_(const char* instanceName, const char* name, int32_t type, uint8_t ext, uint32_t addr, uint32_t xdim, uint32_t ydim, const char* comment, const char* unit); + void createCurve_(const char* instanceName, const char* name, int32_t type, uint8_t ext, uint32_t addr, uint32_t xdim, const char* comment, const char* unit); + + // Finalize and close A2L file + void close(); +}; + + diff --git a/A2lTestDlg/A2lTestDlg/A2lTestDlg.cpp b/A2lTestDlg/A2lTestDlg/A2lTestDlg.cpp new file mode 100644 index 0000000..70136fa --- /dev/null +++ b/A2lTestDlg/A2lTestDlg/A2lTestDlg.cpp @@ -0,0 +1,153 @@ + +// A2lTestDlg.cpp : Defines the class behaviors for the application. +// + +#include "pch.h" +#include "framework.h" +#include "A2lTestDlg.h" +#include "A2lTestDlgDlg.h" + +#ifdef _DEBUG +#define new DEBUG_NEW +#endif + + +// CA2lTestDlgApp + +BEGIN_MESSAGE_MAP(CA2lTestDlgApp, CWinApp) + ON_COMMAND(ID_HELP, &CWinApp::OnHelp) +END_MESSAGE_MAP() + + +// CA2lTestDlgApp construction + +CA2lTestDlgApp::CA2lTestDlgApp() +{ + // support Restart Manager + m_dwRestartManagerSupportFlags = AFX_RESTART_MANAGER_SUPPORT_RESTART; + + // TODO: add construction code here, + // Place all significant initialization in InitInstance +} + + +// The one and only CA2lTestDlgApp object + +CA2lTestDlgApp theApp; + +const GUID CDECL BASED_CODE _tlid = + {0xaacf2bb9,0x0c94,0x4623,{0x8c,0x20,0xbb,0xe3,0x07,0x07,0x21,0xea}}; +const WORD _wVerMajor = 1; +const WORD _wVerMinor = 0; + + +// CA2lTestDlgApp initialization + +BOOL CA2lTestDlgApp::InitInstance() +{ + // InitCommonControlsEx() is required on Windows XP if an application + // manifest specifies use of ComCtl32.dll version 6 or later to enable + // visual styles. Otherwise, any window creation will fail. + INITCOMMONCONTROLSEX InitCtrls; + InitCtrls.dwSize = sizeof(InitCtrls); + // Set this to include all the common control classes you want to use + // in your application. + InitCtrls.dwICC = ICC_WIN95_CLASSES; + InitCommonControlsEx(&InitCtrls); + + CWinApp::InitInstance(); + + + // Initialize OLE libraries + if (!AfxOleInit()) + { + AfxMessageBox(IDP_OLE_INIT_FAILED); + return FALSE; + } + + AfxEnableControlContainer(); + + // Create the shell manager, in case the dialog contains + // any shell tree view or shell list view controls. + CShellManager *pShellManager = new CShellManager; + + // Activate "Windows Native" visual manager for enabling themes in MFC controls + CMFCVisualManager::SetDefaultManager(RUNTIME_CLASS(CMFCVisualManagerWindows)); + + // Standard initialization + // If you are not using these features and wish to reduce the size + // of your final executable, you should remove from the following + // the specific initialization routines you do not need + // Change the registry key under which our settings are stored + // TODO: You should modify this string to be something appropriate + // such as the name of your company or organization + SetRegistryKey(_T("Local AppWizard-Generated Applications")); + // Parse command line for automation or reg/unreg switches. + CCommandLineInfo cmdInfo; + ParseCommandLine(cmdInfo); + + // App was launched with /Embedding or /Automation switch. + // Run app as automation server. + if (cmdInfo.m_bRunEmbedded || cmdInfo.m_bRunAutomated) + { + // Register class factories via CoRegisterClassObject(). + COleTemplateServer::RegisterAll(); + } + // App was launched with /Unregserver or /Unregister switch. Remove + // entries from the registry. + else if (cmdInfo.m_nShellCommand == CCommandLineInfo::AppUnregister) + { + COleObjectFactory::UpdateRegistryAll(FALSE); + AfxOleUnregisterTypeLib(_tlid, _wVerMajor, _wVerMinor); + return FALSE; + } + // App was launched standalone or with other switches (e.g. /Register + // or /Regserver). Update registry entries, including typelibrary. + else + { + COleObjectFactory::UpdateRegistryAll(); + AfxOleRegisterTypeLib(AfxGetInstanceHandle(), _tlid); + if (cmdInfo.m_nShellCommand == CCommandLineInfo::AppRegister) + return FALSE; + } + + CA2lTestDlgDlg dlg; + m_pMainWnd = &dlg; + INT_PTR nResponse = dlg.DoModal(); + if (nResponse == IDOK) + { + // TODO: Place code here to handle when the dialog is + // dismissed with OK + } + else if (nResponse == IDCANCEL) + { + // TODO: Place code here to handle when the dialog is + // dismissed with Cancel + } + else if (nResponse == -1) + { + TRACE(traceAppMsg, 0, "Warning: dialog creation failed, so application is terminating unexpectedly.\n"); + TRACE(traceAppMsg, 0, "Warning: if you are using MFC controls on the dialog, you cannot #define _AFX_NO_MFC_CONTROLS_IN_DIALOGS.\n"); + } + + // Delete the shell manager created above. + if (pShellManager != nullptr) + { + delete pShellManager; + } + +#if !defined(_AFXDLL) && !defined(_AFX_NO_MFC_CONTROLS_IN_DIALOGS) + ControlBarCleanUp(); +#endif + + // Since the dialog has been closed, return FALSE so that we exit the + // application, rather than start the application's message pump. + return FALSE; +} + +int CA2lTestDlgApp::ExitInstance() +{ + AfxOleTerm(FALSE); + + return CWinApp::ExitInstance(); +} diff --git a/A2lTestDlg/A2lTestDlg/A2lTestDlg.h b/A2lTestDlg/A2lTestDlg/A2lTestDlg.h new file mode 100644 index 0000000..3bf400a --- /dev/null +++ b/A2lTestDlg/A2lTestDlg/A2lTestDlg.h @@ -0,0 +1,33 @@ + +// A2lTestDlg.h : main header file for the PROJECT_NAME application +// + +#pragma once + +#ifndef __AFXWIN_H__ + #error "include 'pch.h' before including this file for PCH" +#endif + +#include "resource.h" // main symbols + + +// CA2lTestDlgApp: +// See A2lTestDlg.cpp for the implementation of this class +// + +class CA2lTestDlgApp : public CWinApp +{ +public: + CA2lTestDlgApp(); + +// Overrides +public: + virtual BOOL InitInstance(); + virtual int ExitInstance(); + +// Implementation + + DECLARE_MESSAGE_MAP() +}; + +extern CA2lTestDlgApp theApp; diff --git a/A2lTestDlg/A2lTestDlg/A2lTestDlg.idl b/A2lTestDlg/A2lTestDlg/A2lTestDlg.idl new file mode 100644 index 0000000..e53307d --- /dev/null +++ b/A2lTestDlg/A2lTestDlg/A2lTestDlg.idl @@ -0,0 +1,29 @@ +// A2lTestDlg.idl : type library source for A2lTestDlg.exe + +// This file will be processed by the MIDL compiler to produce the +// type library (A2lTestDlg.tlb). + +[ uuid(aacf2bb9-0c94-4623-8c20-bbe3070721ea), version(1.0) ] +library A2lTestDlg +{ + importlib("stdole32.tlb"); + importlib("stdole2.tlb"); + + // Primary dispatch interface for CA2lTestDlgDoc + + [ uuid(9fc78fa1-82e8-4469-9a9f-60c6d387b64a) ] + dispinterface IA2lTestDlg + { + properties: + + methods: + }; + + // Class information for CA2lTestDlgDoc + + [ uuid(04615303-44d9-45b7-b802-02b06c0dde4f) ] + coclass A2lTestDlg + { + [default] dispinterface IA2lTestDlg; + }; +}; diff --git a/A2lTestDlg/A2lTestDlg/A2lTestDlg.rc b/A2lTestDlg/A2lTestDlg/A2lTestDlg.rc new file mode 100644 index 0000000000000000000000000000000000000000..56f3261d88497bab7fbbd0c22fd31d54de65ea18 GIT binary patch literal 12482 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 PyVQ-pXdtn4*(~+HTwV~3 literal 0 HcmV?d00001 diff --git a/A2lTestDlg/A2lTestDlg/A2lTestDlg.reg b/A2lTestDlg/A2lTestDlg/A2lTestDlg.reg new file mode 100644 index 0000000..6976ebb --- /dev/null +++ b/A2lTestDlg/A2lTestDlg/A2lTestDlg.reg @@ -0,0 +1,17 @@ +REGEDIT +; This .REG file may be used by your SETUP program. +; If a SETUP program is not available, the entries below will be +; registered in your InitInstance automatically with a call to +; CWinApp::RegisterShellFileTypes and COleObjectFactory::UpdateRegistryAll. + + +HKEY_CLASSES_ROOT\A2lTestDlg.Application = A2lTestDlg Application + + +HKEY_CLASSES_ROOT\A2lTestDlg.Application\CLSID = {04615303-44d9-45b7-b802-02b06c0dde4f} + +HKEY_CLASSES_ROOT\CLSID\{04615303-44d9-45b7-b802-02b06c0dde4f} = A2lTestDlg Application +HKEY_CLASSES_ROOT\CLSID\{04615303-44d9-45b7-b802-02b06c0dde4f}\ProgId = A2lTestDlg.Application + + +HKEY_CLASSES_ROOT\CLSID\{04615303-44d9-45b7-b802-02b06c0dde4f}\LocalServer32 = A2lTestDlg.EXE diff --git a/A2lTestDlg/A2lTestDlg/A2lTestDlg.vcxproj b/A2lTestDlg/A2lTestDlg/A2lTestDlg.vcxproj new file mode 100644 index 0000000..0b7cef4 --- /dev/null +++ b/A2lTestDlg/A2lTestDlg/A2lTestDlg.vcxproj @@ -0,0 +1,252 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + 16.0 + {86752C60-05E4-465C-9D79-876C97ABD2BA} + MFCProj + A2lTestDlg + 10.0 + + + + Application + true + v142 + Unicode + Dynamic + + + Application + false + v142 + true + Unicode + Dynamic + + + Application + true + v142 + Unicode + Dynamic + + + Application + false + v142 + true + Unicode + Dynamic + + + + + + + + + + + + + + + + + + + + + true + + + true + + + false + + + false + + + + Use + Level3 + true + WIN32;_WINDOWS;_DEBUG;%(PreprocessorDefinitions) + pch.h + CompileAsCpp + + + Windows + true + + + false + true + _DEBUG;%(PreprocessorDefinitions) + $(IntDir)A2lTestDlg.tlb + A2lTestDlg_h.h + + + 0x0409 + _DEBUG;%(PreprocessorDefinitions) + $(IntDir);%(AdditionalIncludeDirectories) + + + + + Use + Level3 + true + _WINDOWS;_DEBUG;%(PreprocessorDefinitions) + pch.h + + + Windows + true + + + false + true + _DEBUG;%(PreprocessorDefinitions) + $(IntDir)A2lTestDlg.tlb + A2lTestDlg_h.h + + + 0x0409 + _DEBUG;%(PreprocessorDefinitions) + $(IntDir);%(AdditionalIncludeDirectories) + + + + + Use + Level3 + true + true + true + WIN32;_WINDOWS;NDEBUG;%(PreprocessorDefinitions) + pch.h + stdcpp20 + stdc17 + CompileAsCpp + + + Windows + true + true + true + + + false + true + NDEBUG;%(PreprocessorDefinitions) + $(IntDir)A2lTestDlg.tlb + A2lTestDlg_h.h + + + 0x0409 + NDEBUG;%(PreprocessorDefinitions) + $(IntDir);%(AdditionalIncludeDirectories) + + + + + Use + Level3 + true + true + true + _WINDOWS;NDEBUG;%(PreprocessorDefinitions) + pch.h + + + Windows + true + true + true + + + false + true + NDEBUG;%(PreprocessorDefinitions) + $(IntDir)A2lTestDlg.tlb + A2lTestDlg_h.h + + + 0x0409 + NDEBUG;%(PreprocessorDefinitions) + $(IntDir);%(AdditionalIncludeDirectories) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Create + Create + Create + Create + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/A2lTestDlg/A2lTestDlg/A2lTestDlg.vcxproj.filters b/A2lTestDlg/A2lTestDlg/A2lTestDlg.vcxproj.filters new file mode 100644 index 0000000..4b07686 --- /dev/null +++ b/A2lTestDlg/A2lTestDlg/A2lTestDlg.vcxproj.filters @@ -0,0 +1,118 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + + + Source Files + + + + + + Resource Files + + + + + + Resource Files + + + + + Resource Files + + + \ No newline at end of file diff --git a/A2lTestDlg/A2lTestDlg/A2lTestDlg.vcxproj.user b/A2lTestDlg/A2lTestDlg/A2lTestDlg.vcxproj.user new file mode 100644 index 0000000..d2bbed9 --- /dev/null +++ b/A2lTestDlg/A2lTestDlg/A2lTestDlg.vcxproj.user @@ -0,0 +1,6 @@ + + + + A2lTestDlg.rc + + \ No newline at end of file diff --git a/A2lTestDlg/A2lTestDlg/A2lTestDlgDlg.cpp b/A2lTestDlg/A2lTestDlg/A2lTestDlgDlg.cpp new file mode 100644 index 0000000..54f7d60 --- /dev/null +++ b/A2lTestDlg/A2lTestDlg/A2lTestDlgDlg.cpp @@ -0,0 +1,252 @@ + +// A2lTestDlgDlg.cpp : implementation file +// + +#include "pch.h" +#include "framework.h" +#include "A2lTestDlg.h" +#include "A2lTestDlgDlg.h" +#include "DlgProxy.h" +#include "afxdialogex.h" + +#include + +#ifdef _DEBUG +#define new DEBUG_NEW +#endif + +//template +//std::wstring wstring_format(const std::wstring& format, Args ... args); +template +std::string string_format(const std::string& format, Args ... args) +{ + size_t size = snprintf(nullptr, 0, format.c_str(), args ...) + 1; // Extra space for '\0' + if (size <= 0) { + throw std::runtime_error("Error during formatting."); + } + std::unique_ptr buf(new char[size]); + snprintf(buf.get(), size, format.c_str(), args ...); + return std::string(buf.get(), buf.get() + size - 1); // We don't want the '\0' inside } +} + + + +// CAboutDlg dialog used for App About + +class CAboutDlg : public CDialogEx +{ +public: + CAboutDlg(); + +// Dialog Data +#ifdef AFX_DESIGN_TIME + enum { IDD = IDD_ABOUTBOX }; +#endif + + protected: + virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support + +// Implementation +protected: + DECLARE_MESSAGE_MAP() +}; + +CAboutDlg::CAboutDlg() : CDialogEx(IDD_ABOUTBOX) +{ +} + +void CAboutDlg::DoDataExchange(CDataExchange* pDX) +{ + CDialogEx::DoDataExchange(pDX); +} + +BEGIN_MESSAGE_MAP(CAboutDlg, CDialogEx) +END_MESSAGE_MAP() + + +// CA2lTestDlgDlg dialog + + +IMPLEMENT_DYNAMIC(CA2lTestDlgDlg, CDialogEx); + +CA2lTestDlgDlg::CA2lTestDlgDlg(CWnd* pParent /*=nullptr*/) + : CDialogEx(IDD_A2LTESTDLG_DIALOG, pParent) +{ + m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME); + m_pAutoProxy = nullptr; +} + +CA2lTestDlgDlg::~CA2lTestDlgDlg() +{ + // If there is an automation proxy for this dialog, set + // its back pointer to this dialog to null, so it knows + // the dialog has been deleted. + if (m_pAutoProxy != nullptr) + m_pAutoProxy->m_pDialog = nullptr; +} + +void CA2lTestDlgDlg::DoDataExchange(CDataExchange* pDX) +{ + CDialogEx::DoDataExchange(pDX); +} + +BEGIN_MESSAGE_MAP(CA2lTestDlgDlg, CDialogEx) + ON_WM_SYSCOMMAND() + ON_WM_CLOSE() + ON_WM_PAINT() + ON_WM_QUERYDRAGICON() + ON_BN_CLICKED(IDC_BUTTON_OPEN, &CA2lTestDlgDlg::OnBnClickedButtonOpen) +END_MESSAGE_MAP() + + +// CA2lTestDlgDlg message handlers + +BOOL CA2lTestDlgDlg::OnInitDialog() +{ + CDialogEx::OnInitDialog(); + + // Add "About..." menu item to system menu. + + // IDM_ABOUTBOX must be in the system command range. + ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX); + ASSERT(IDM_ABOUTBOX < 0xF000); + + CMenu* pSysMenu = GetSystemMenu(FALSE); + if (pSysMenu != nullptr) + { + BOOL bNameValid; + CString strAboutMenu; + bNameValid = strAboutMenu.LoadString(IDS_ABOUTBOX); + ASSERT(bNameValid); + if (!strAboutMenu.IsEmpty()) + { + pSysMenu->AppendMenu(MF_SEPARATOR); + pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu); + } + } + + // Set the icon for this dialog. The framework does this automatically + // when the application's main window is not a dialog + SetIcon(m_hIcon, TRUE); // Set big icon + SetIcon(m_hIcon, FALSE); // Set small icon + + // TODO: Add extra initialization here + + return TRUE; // return TRUE unless you set the focus to a control +} + +void CA2lTestDlgDlg::OnSysCommand(UINT nID, LPARAM lParam) +{ + if ((nID & 0xFFF0) == IDM_ABOUTBOX) + { + CAboutDlg dlgAbout; + dlgAbout.DoModal(); + } + else + { + CDialogEx::OnSysCommand(nID, lParam); + } +} + +// If you add a minimize button to your dialog, you will need the code below +// to draw the icon. For MFC applications using the document/view model, +// this is automatically done for you by the framework. + +void CA2lTestDlgDlg::OnPaint() +{ + if (IsIconic()) + { + CPaintDC dc(this); // device context for painting + + SendMessage(WM_ICONERASEBKGND, reinterpret_cast(dc.GetSafeHdc()), 0); + + // Center icon in client rectangle + int cxIcon = GetSystemMetrics(SM_CXICON); + int cyIcon = GetSystemMetrics(SM_CYICON); + CRect rect; + GetClientRect(&rect); + int x = (rect.Width() - cxIcon + 1) / 2; + int y = (rect.Height() - cyIcon + 1) / 2; + + // Draw the icon + dc.DrawIcon(x, y, m_hIcon); + } + else + { + CDialogEx::OnPaint(); + } +} + +// The system calls this function to obtain the cursor to display while the user drags +// the minimized window. +HCURSOR CA2lTestDlgDlg::OnQueryDragIcon() +{ + return static_cast(m_hIcon); +} + +// Automation servers should not exit when a user closes the UI +// if a controller still holds on to one of its objects. These +// message handlers make sure that if the proxy is still in use, +// then the UI is hidden but the dialog remains around if it +// is dismissed. + +void CA2lTestDlgDlg::OnClose() +{ + if (CanExit()) + CDialogEx::OnClose(); +} + +void CA2lTestDlgDlg::OnOK() +{ + if (CanExit()) + CDialogEx::OnOK(); +} + +void CA2lTestDlgDlg::OnCancel() +{ + if (CanExit()) + CDialogEx::OnCancel(); +} + +BOOL CA2lTestDlgDlg::CanExit() +{ + // If the proxy object is still around, then the automation + // controller is still holding on to this application. Leave + // the dialog around, but hide its UI. + if (m_pAutoProxy != nullptr) + { + ShowWindow(SW_HIDE); + return FALSE; + } + + return TRUE; +} + + + +void CA2lTestDlgDlg::OnBnClickedButtonOpen() +{ + // TODO: Add your control notification handler code here + // TODO: ¿©±â¿¡ ÄÁÆ®·Ñ ¾Ë¸² 󸮱â Äڵ带 Ãß°¡ÇÕ´Ï´Ù. + TCHAR a2lExt[] = _T("*.a2l"); + TCHAR a2lBaseFilter[] = _T("A2L file(*.A2L) | *.a2l;*.A2L | ¸ðµçÆÄÀÏ(*.*) | *.* ||"); + CFileDialog dlg(TRUE, a2lExt, NULL, OFN_HIDEREADONLY, a2lBaseFilter); + + if (dlg.DoModal() == IDOK) { + std::wstring strPath = dlg.GetPathName().GetBuffer(); + + std::string strA2lPath; + strA2lPath.assign(strPath.begin(), strPath.end()); + + loadA2lFile(strA2lPath.c_str()); + } +} + +void CA2lTestDlgDlg::AddLogString(std::string strMessage) +{ + CListBox* pListBox = (CListBox*)GetDlgItem(IDC_LIST_DATA); + std::wstring message_w; + message_w.assign(strMessage.begin(), strMessage.end()); + + pListBox->AddString(message_w.c_str()); +} \ No newline at end of file diff --git a/A2lTestDlg/A2lTestDlg/A2lTestDlgDlg.h b/A2lTestDlg/A2lTestDlg/A2lTestDlgDlg.h new file mode 100644 index 0000000..bf0a035 --- /dev/null +++ b/A2lTestDlg/A2lTestDlg/A2lTestDlgDlg.h @@ -0,0 +1,60 @@ + +// A2lTestDlgDlg.h : header file +// + + +#pragma once + +#include +#include +#include +#include + +#include "A2Lpp.hpp" // A2L generator + +class CA2lTestDlgDlgAutoProxy; + + +// CA2lTestDlgDlg dialog +class CA2lTestDlgDlg : public CDialogEx +{ + DECLARE_DYNAMIC(CA2lTestDlgDlg); + friend class CA2lTestDlgDlgAutoProxy; + +// Construction +public: + CA2lTestDlgDlg(CWnd* pParent = nullptr); // standard constructor + virtual ~CA2lTestDlgDlg(); + +// Dialog Data +#ifdef AFX_DESIGN_TIME + enum { IDD = IDD_A2LTESTDLG_DIALOG }; +#endif + + protected: + virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support + + +// Implementation +protected: + CA2lTestDlgDlgAutoProxy* m_pAutoProxy; + HICON m_hIcon; + + BOOL CanExit(); + + // Generated message map functions + virtual BOOL OnInitDialog(); + afx_msg void OnSysCommand(UINT nID, LPARAM lParam); + afx_msg void OnPaint(); + afx_msg HCURSOR OnQueryDragIcon(); + afx_msg void OnClose(); + virtual void OnOK(); + virtual void OnCancel(); + DECLARE_MESSAGE_MAP() +public: + afx_msg void OnBnClickedButtonOpen(); + + void AddLogString(std::string strMessage); + + A2L* a2lFile; +}; diff --git a/A2lTestDlg/A2lTestDlg/A2lTestDlg_h.h b/A2lTestDlg/A2lTestDlg/A2lTestDlg_h.h new file mode 100644 index 0000000..708bc1c --- /dev/null +++ b/A2lTestDlg/A2lTestDlg/A2lTestDlg_h.h @@ -0,0 +1,226 @@ + + +/* this ALWAYS GENERATED file contains the definitions for the interfaces */ + + + /* File created by MIDL compiler version 8.01.0628 */ +/* at Tue Jan 19 12:14:07 2038 + */ +/* Compiler settings for A2lTestDlg.idl: + Oicf, W1, Zp8, env=Win32 (32b run), target_arch=X86 8.01.0628 + protocol : dce , ms_ext, c_ext, robust + error checks: allocation ref bounds_check enum stub_data + VC __declspec() decoration level: + __declspec(uuid()), __declspec(selectany), __declspec(novtable) + DECLSPEC_UUID(), MIDL_INTERFACE() +*/ +/* @@MIDL_FILE_HEADING( ) */ + + + +/* verify that the version is high enough to compile this file*/ +#ifndef __REQUIRED_RPCNDR_H_VERSION__ +#define __REQUIRED_RPCNDR_H_VERSION__ 500 +#endif + +#include "rpc.h" +#include "rpcndr.h" + +#ifndef __RPCNDR_H_VERSION__ +#error this stub requires an updated version of +#endif /* __RPCNDR_H_VERSION__ */ + + +#ifndef __A2lTestDlg_h_h__ +#define __A2lTestDlg_h_h__ + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +#pragma once +#endif + +#ifndef DECLSPEC_XFGVIRT +#if defined(_CONTROL_FLOW_GUARD_XFG) +#define DECLSPEC_XFGVIRT(base, func) __declspec(xfg_virtual(base, func)) +#else +#define DECLSPEC_XFGVIRT(base, func) +#endif +#endif + +/* Forward Declarations */ + +#ifndef __IA2lTestDlg_FWD_DEFINED__ +#define __IA2lTestDlg_FWD_DEFINED__ +typedef interface IA2lTestDlg IA2lTestDlg; + +#endif /* __IA2lTestDlg_FWD_DEFINED__ */ + + +#ifndef __A2lTestDlg_FWD_DEFINED__ +#define __A2lTestDlg_FWD_DEFINED__ + +#ifdef __cplusplus +typedef class A2lTestDlg A2lTestDlg; +#else +typedef struct A2lTestDlg A2lTestDlg; +#endif /* __cplusplus */ + +#endif /* __A2lTestDlg_FWD_DEFINED__ */ + + +#ifdef __cplusplus +extern "C"{ +#endif + + + +#ifndef __A2lTestDlg_LIBRARY_DEFINED__ +#define __A2lTestDlg_LIBRARY_DEFINED__ + +/* library A2lTestDlg */ +/* [version][uuid] */ + + +EXTERN_C const IID LIBID_A2lTestDlg; + +#ifndef __IA2lTestDlg_DISPINTERFACE_DEFINED__ +#define __IA2lTestDlg_DISPINTERFACE_DEFINED__ + +/* dispinterface IA2lTestDlg */ +/* [uuid] */ + + +EXTERN_C const IID DIID_IA2lTestDlg; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("9fc78fa1-82e8-4469-9a9f-60c6d387b64a") + IA2lTestDlg : public IDispatch + { + }; + +#else /* C style interface */ + + typedef struct IA2lTestDlgVtbl + { + BEGIN_INTERFACE + + DECLSPEC_XFGVIRT(IUnknown, QueryInterface) + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + IA2lTestDlg * This, + /* [in] */ REFIID riid, + /* [annotation][iid_is][out] */ + _COM_Outptr_ void **ppvObject); + + DECLSPEC_XFGVIRT(IUnknown, AddRef) + ULONG ( STDMETHODCALLTYPE *AddRef )( + IA2lTestDlg * This); + + DECLSPEC_XFGVIRT(IUnknown, Release) + ULONG ( STDMETHODCALLTYPE *Release )( + IA2lTestDlg * This); + + DECLSPEC_XFGVIRT(IDispatch, GetTypeInfoCount) + HRESULT ( STDMETHODCALLTYPE *GetTypeInfoCount )( + IA2lTestDlg * This, + /* [out] */ UINT *pctinfo); + + DECLSPEC_XFGVIRT(IDispatch, GetTypeInfo) + HRESULT ( STDMETHODCALLTYPE *GetTypeInfo )( + IA2lTestDlg * This, + /* [in] */ UINT iTInfo, + /* [in] */ LCID lcid, + /* [out] */ ITypeInfo **ppTInfo); + + DECLSPEC_XFGVIRT(IDispatch, GetIDsOfNames) + HRESULT ( STDMETHODCALLTYPE *GetIDsOfNames )( + IA2lTestDlg * This, + /* [in] */ REFIID riid, + /* [size_is][in] */ LPOLESTR *rgszNames, + /* [range][in] */ UINT cNames, + /* [in] */ LCID lcid, + /* [size_is][out] */ DISPID *rgDispId); + + DECLSPEC_XFGVIRT(IDispatch, Invoke) + /* [local] */ HRESULT ( STDMETHODCALLTYPE *Invoke )( + IA2lTestDlg * This, + /* [annotation][in] */ + _In_ DISPID dispIdMember, + /* [annotation][in] */ + _In_ REFIID riid, + /* [annotation][in] */ + _In_ LCID lcid, + /* [annotation][in] */ + _In_ WORD wFlags, + /* [annotation][out][in] */ + _In_ DISPPARAMS *pDispParams, + /* [annotation][out] */ + _Out_opt_ VARIANT *pVarResult, + /* [annotation][out] */ + _Out_opt_ EXCEPINFO *pExcepInfo, + /* [annotation][out] */ + _Out_opt_ UINT *puArgErr); + + END_INTERFACE + } IA2lTestDlgVtbl; + + interface IA2lTestDlg + { + CONST_VTBL struct IA2lTestDlgVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define IA2lTestDlg_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define IA2lTestDlg_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define IA2lTestDlg_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define IA2lTestDlg_GetTypeInfoCount(This,pctinfo) \ + ( (This)->lpVtbl -> GetTypeInfoCount(This,pctinfo) ) + +#define IA2lTestDlg_GetTypeInfo(This,iTInfo,lcid,ppTInfo) \ + ( (This)->lpVtbl -> GetTypeInfo(This,iTInfo,lcid,ppTInfo) ) + +#define IA2lTestDlg_GetIDsOfNames(This,riid,rgszNames,cNames,lcid,rgDispId) \ + ( (This)->lpVtbl -> GetIDsOfNames(This,riid,rgszNames,cNames,lcid,rgDispId) ) + +#define IA2lTestDlg_Invoke(This,dispIdMember,riid,lcid,wFlags,pDispParams,pVarResult,pExcepInfo,puArgErr) \ + ( (This)->lpVtbl -> Invoke(This,dispIdMember,riid,lcid,wFlags,pDispParams,pVarResult,pExcepInfo,puArgErr) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + +#endif /* __IA2lTestDlg_DISPINTERFACE_DEFINED__ */ + + +EXTERN_C const CLSID CLSID_A2lTestDlg; + +#ifdef __cplusplus + +class DECLSPEC_UUID("04615303-44d9-45b7-b802-02b06c0dde4f") +A2lTestDlg; +#endif +#endif /* __A2lTestDlg_LIBRARY_DEFINED__ */ + +/* Additional Prototypes for ALL interfaces */ + +/* end of Additional Prototypes */ + +#ifdef __cplusplus +} +#endif + +#endif + + diff --git a/A2lTestDlg/A2lTestDlg/A2lTestDlg_i.c b/A2lTestDlg/A2lTestDlg/A2lTestDlg_i.c new file mode 100644 index 0000000..6f52ad9 --- /dev/null +++ b/A2lTestDlg/A2lTestDlg/A2lTestDlg_i.c @@ -0,0 +1,84 @@ + + +/* this ALWAYS GENERATED file contains the IIDs and CLSIDs */ + +/* link this file in with the server and any clients */ + + + /* File created by MIDL compiler version 8.01.0628 */ +/* at Tue Jan 19 12:14:07 2038 + */ +/* Compiler settings for A2lTestDlg.idl: + Oicf, W1, Zp8, env=Win32 (32b run), target_arch=X86 8.01.0628 + protocol : dce , ms_ext, c_ext, robust + error checks: allocation ref bounds_check enum stub_data + VC __declspec() decoration level: + __declspec(uuid()), __declspec(selectany), __declspec(novtable) + DECLSPEC_UUID(), MIDL_INTERFACE() +*/ +/* @@MIDL_FILE_HEADING( ) */ + + + +#ifdef __cplusplus +extern "C"{ +#endif + + +#include +#include + +#ifdef _MIDL_USE_GUIDDEF_ + +#ifndef INITGUID +#define INITGUID +#include +#undef INITGUID +#else +#include +#endif + +#define MIDL_DEFINE_GUID(type,name,l,w1,w2,b1,b2,b3,b4,b5,b6,b7,b8) \ + DEFINE_GUID(name,l,w1,w2,b1,b2,b3,b4,b5,b6,b7,b8) + +#else // !_MIDL_USE_GUIDDEF_ + +#ifndef __IID_DEFINED__ +#define __IID_DEFINED__ + +typedef struct _IID +{ + unsigned long x; + unsigned short s1; + unsigned short s2; + unsigned char c[8]; +} IID; + +#endif // __IID_DEFINED__ + +#ifndef CLSID_DEFINED +#define CLSID_DEFINED +typedef IID CLSID; +#endif // CLSID_DEFINED + +#define MIDL_DEFINE_GUID(type,name,l,w1,w2,b1,b2,b3,b4,b5,b6,b7,b8) \ + EXTERN_C __declspec(selectany) const type name = {l,w1,w2,{b1,b2,b3,b4,b5,b6,b7,b8}} + +#endif // !_MIDL_USE_GUIDDEF_ + +MIDL_DEFINE_GUID(IID, LIBID_A2lTestDlg,0xaacf2bb9,0x0c94,0x4623,0x8c,0x20,0xbb,0xe3,0x07,0x07,0x21,0xea); + + +MIDL_DEFINE_GUID(IID, DIID_IA2lTestDlg,0x9fc78fa1,0x82e8,0x4469,0x9a,0x9f,0x60,0xc6,0xd3,0x87,0xb6,0x4a); + + +MIDL_DEFINE_GUID(CLSID, CLSID_A2lTestDlg,0x04615303,0x44d9,0x45b7,0xb8,0x02,0x02,0xb0,0x6c,0x0d,0xde,0x4f); + +#undef MIDL_DEFINE_GUID + +#ifdef __cplusplus +} +#endif + + + diff --git a/A2lTestDlg/A2lTestDlg/DlgProxy.cpp b/A2lTestDlg/A2lTestDlg/DlgProxy.cpp new file mode 100644 index 0000000..b128141 --- /dev/null +++ b/A2lTestDlg/A2lTestDlg/DlgProxy.cpp @@ -0,0 +1,87 @@ + +// DlgProxy.cpp : implementation file +// + +#include "pch.h" +#include "framework.h" +#include "A2lTestDlg.h" +#include "DlgProxy.h" +#include "A2lTestDlgDlg.h" + +#ifdef _DEBUG +#define new DEBUG_NEW +#endif + + +// CA2lTestDlgDlgAutoProxy + +IMPLEMENT_DYNCREATE(CA2lTestDlgDlgAutoProxy, CCmdTarget) + +CA2lTestDlgDlgAutoProxy::CA2lTestDlgDlgAutoProxy() +{ + EnableAutomation(); + + // To keep the application running as long as an automation + // object is active, the constructor calls AfxOleLockApp. + AfxOleLockApp(); + + // Get access to the dialog through the application's + // main window pointer. Set the proxy's internal pointer + // to point to the dialog, and set the dialog's back pointer to + // this proxy. + ASSERT_VALID(AfxGetApp()->m_pMainWnd); + if (AfxGetApp()->m_pMainWnd) + { + ASSERT_KINDOF(CA2lTestDlgDlg, AfxGetApp()->m_pMainWnd); + if (AfxGetApp()->m_pMainWnd->IsKindOf(RUNTIME_CLASS(CA2lTestDlgDlg))) + { + m_pDialog = reinterpret_cast(AfxGetApp()->m_pMainWnd); + m_pDialog->m_pAutoProxy = this; + } + } +} + +CA2lTestDlgDlgAutoProxy::~CA2lTestDlgDlgAutoProxy() +{ + // To terminate the application when all objects created with + // with automation, the destructor calls AfxOleUnlockApp. + // Among other things, this will destroy the main dialog + if (m_pDialog != nullptr) + m_pDialog->m_pAutoProxy = nullptr; + AfxOleUnlockApp(); +} + +void CA2lTestDlgDlgAutoProxy::OnFinalRelease() +{ + // When the last reference for an automation object is released + // OnFinalRelease is called. The base class will automatically + // deletes the object. Add additional cleanup required for your + // object before calling the base class. + + CCmdTarget::OnFinalRelease(); +} + +BEGIN_MESSAGE_MAP(CA2lTestDlgDlgAutoProxy, CCmdTarget) +END_MESSAGE_MAP() + +BEGIN_DISPATCH_MAP(CA2lTestDlgDlgAutoProxy, CCmdTarget) +END_DISPATCH_MAP() + +// Note: we add support for IID_IA2lTestDlg to support typesafe binding +// from VBA. This IID must match the GUID that is attached to the +// dispinterface in the .IDL file. + +// {9fc78fa1-82e8-4469-9a9f-60c6d387b64a} +static const IID IID_IA2lTestDlg = +{0x9fc78fa1,0x82e8,0x4469,{0x9a,0x9f,0x60,0xc6,0xd3,0x87,0xb6,0x4a}}; + +BEGIN_INTERFACE_MAP(CA2lTestDlgDlgAutoProxy, CCmdTarget) + INTERFACE_PART(CA2lTestDlgDlgAutoProxy, IID_IA2lTestDlg, Dispatch) +END_INTERFACE_MAP() + +// The IMPLEMENT_OLECREATE2 macro is defined in pch.h of this project +// {04615303-44d9-45b7-b802-02b06c0dde4f} +IMPLEMENT_OLECREATE2(CA2lTestDlgDlgAutoProxy, "A2lTestDlg.Application", 0x04615303,0x44d9,0x45b7,0xb8,0x02,0x02,0xb0,0x6c,0x0d,0xde,0x4f) + + +// CA2lTestDlgDlgAutoProxy message handlers diff --git a/A2lTestDlg/A2lTestDlg/DlgProxy.h b/A2lTestDlg/A2lTestDlg/DlgProxy.h new file mode 100644 index 0000000..539960d --- /dev/null +++ b/A2lTestDlg/A2lTestDlg/DlgProxy.h @@ -0,0 +1,43 @@ + +// DlgProxy.h: header file +// + +#pragma once + +class CA2lTestDlgDlg; + + +// CA2lTestDlgDlgAutoProxy command target + +class CA2lTestDlgDlgAutoProxy : public CCmdTarget +{ + DECLARE_DYNCREATE(CA2lTestDlgDlgAutoProxy) + + CA2lTestDlgDlgAutoProxy(); // protected constructor used by dynamic creation + +// Attributes +public: + CA2lTestDlgDlg* m_pDialog; + +// Operations +public: + +// Overrides + public: + virtual void OnFinalRelease(); + +// Implementation +protected: + virtual ~CA2lTestDlgDlgAutoProxy(); + + // Generated message map functions + + DECLARE_MESSAGE_MAP() + DECLARE_OLECREATE(CA2lTestDlgDlgAutoProxy) + + // Generated OLE dispatch map functions + + DECLARE_DISPATCH_MAP() + DECLARE_INTERFACE_MAP() +}; + diff --git a/A2lTestDlg/A2lTestDlg/dbg_print.h b/A2lTestDlg/A2lTestDlg/dbg_print.h new file mode 100644 index 0000000..c2ec327 --- /dev/null +++ b/A2lTestDlg/A2lTestDlg/dbg_print.h @@ -0,0 +1,50 @@ +#pragma once + +/* dbg_print.h */ +/* +| Code released into public domain, no attribution required +*/ + + +//------------------------------------------------------------------------------- +// Debug print + +#if OPTION_ENABLE_DBG_PRINTS + +extern unsigned int gDebugLevel; +#define DBG_LEVEL gDebugLevel + +#define DBG_PRINTF_ERROR(format, ...) printf(format, __VA_ARGS__) +#define DBG_PRINTF(level, format, ...) if (DBG_LEVEL>=level) printf(format, __VA_ARGS__) +#define DBG_PRINTF1(format, ...) if (DBG_LEVEL>=1) printf(format, __VA_ARGS__) +#define DBG_PRINTF2(format, ...) if (DBG_LEVEL>=2) printf(format, __VA_ARGS__) +#define DBG_PRINTF3(format, ...) if (DBG_LEVEL>=3) printf(format, __VA_ARGS__) +#define DBG_PRINTF4(format, ...) if (DBG_LEVEL>=4) printf(format, __VA_ARGS__) + +#define DBG_PRINT_ERROR(format) printf(format) +#define DBG_PRINT(level, format) if (DBG_LEVEL>=level) printf(format) +#define DBG_PRINT1(format) if (DBG_LEVEL>=1) printf(format) +#define DBG_PRINT2(format) if (DBG_LEVEL>=2) printf(format) +#define DBG_PRINT3(format) if (DBG_LEVEL>=3) printf(format) +#define DBG_PRINT4(format) if (DBG_LEVEL>=4) printf(format) + +#else + +#undef DBG_LEVEL + +#define DBG_PRINTF_ERROR(s, ...) // printf(s,__VA_ARGS__) +#define DBG_PRINTF(level, s, ...) +#define DBG_PRINTF1(s, ...) +#define DBG_PRINTF2(s, ...) +#define DBG_PRINTF3(s, ...) +#define DBG_PRINTF4(s, ...) + +#define DBG_PRINT_ERROR(s, ...) // printf(s,__VA_ARGS__) +#define DBG_PRINT(level, s, ...) +#define DBG_PRINT1(s, ...) +#define DBG_PRINT2(s, ...) +#define DBG_PRINT3(s, ...) +#define DBG_PRINT4(s, ...) + +#endif + diff --git a/A2lTestDlg/A2lTestDlg/framework.h b/A2lTestDlg/A2lTestDlg/framework.h new file mode 100644 index 0000000..52ad5d8 --- /dev/null +++ b/A2lTestDlg/A2lTestDlg/framework.h @@ -0,0 +1,60 @@ +#pragma once + +#ifndef VC_EXTRALEAN +#define VC_EXTRALEAN // Exclude rarely-used stuff from Windows headers +#endif + +#include "targetver.h" + +#define _ATL_CSTRING_EXPLICIT_CONSTRUCTORS // some CString constructors will be explicit + +// turns off MFC's hiding of some common and often safely ignored warning messages +#define _AFX_ALL_WARNINGS + +#include // MFC core and standard components +#include // MFC extensions + + +#include // MFC Automation classes + + + +#ifndef _AFX_NO_OLE_SUPPORT +#include // MFC support for Internet Explorer 4 Common Controls +#endif +#ifndef _AFX_NO_AFXCMN_SUPPORT +#include // MFC support for Windows Common Controls +#endif // _AFX_NO_AFXCMN_SUPPORT + +#include // MFC support for ribbons and control bars + + + + + + + + +// This macro is the same as IMPLEMENT_OLECREATE, except it passes TRUE +// for the bMultiInstance parameter to the COleObjectFactory constructor. +// We want a separate instance of this application to be launched for +// each automation proxy object requested by automation controllers. +#ifndef IMPLEMENT_OLECREATE2 +#define IMPLEMENT_OLECREATE2(class_name, external_name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) \ + AFX_DATADEF COleObjectFactory class_name::factory(class_name::guid, \ + RUNTIME_CLASS(class_name), TRUE, _T(external_name)); \ + const AFX_DATADEF GUID class_name::guid = \ + { l, w1, w2, { b1, b2, b3, b4, b5, b6, b7, b8 } }; +#endif // IMPLEMENT_OLECREATE2 + +#ifdef _UNICODE +#if defined _M_IX86 +#pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='x86' publicKeyToken='6595b64144ccf1df' language='*'\"") +#elif defined _M_X64 +#pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='amd64' publicKeyToken='6595b64144ccf1df' language='*'\"") +#else +#pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"") +#endif +#endif + + diff --git a/A2lTestDlg/A2lTestDlg/main.h b/A2lTestDlg/A2lTestDlg/main.h new file mode 100644 index 0000000..7ed8265 --- /dev/null +++ b/A2lTestDlg/A2lTestDlg/main.h @@ -0,0 +1,95 @@ +#pragma once + +/* main.h */ +/* +| Code released into public domain, no attribution required +*/ + +// Windows or Linux ? +#if defined(_WIN32) || defined(_WIN64) + #define _WIN + #if defined(_WIN32) && defined(_WIN64) + #undef _WIN32 + #endif + #if defined(_LINUX) || defined(_LINUX64)|| defined(_LINUX32) + #error + #endif +#else + #define _LINUX + #if defined (_ix64_) || defined (__x86_64__) || defined (__aarch64__) + #define _LINUX64 + #else + #define _LINUX32 + #endif + #if defined(_WIN) || defined(_WIN64)|| defined(_WIN32) + #error + #endif +#endif + + +#ifdef _WIN +#define WIN32_LEAN_AND_MEAN +#define _CRT_SECURE_NO_WARNINGS +#else +#define _DEFAULT_SOURCE +#endif + + +#include +#include +#include +#include +#include + +#ifdef _WIN +#define M_PI 3.14159265358979323846 +#endif +#define M_2PI (M_PI*2) + +#include + +#ifndef _WIN // Linux + +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#define MAX_PATH 256 +#define BOOL int +#define FALSE 0 +#define TRUE 1 + +#else // Windows + +#include +#include +#include + +#define BOOL int +#define FALSE 0 +#define TRUE 1 + +#endif + +#ifdef __cplusplus +#include +#include +#include +#include +#endif + +#include "main_cfg.h" + diff --git a/A2lTestDlg/A2lTestDlg/main_cfg.h b/A2lTestDlg/A2lTestDlg/main_cfg.h new file mode 100644 index 0000000..1dadbcc --- /dev/null +++ b/A2lTestDlg/A2lTestDlg/main_cfg.h @@ -0,0 +1,48 @@ +#pragma once + +// main_cfg.h +// CPP_Demo + +/* Copyright(c) Vector Informatik GmbH.All rights reserved. + Licensed under the MIT license.See LICENSE file in the project root for details. */ + +// Application configuration: +// XCP configuration is in xcp_cfg.h (Protocol Layer) and xcptl_cfg.h (Transport Layer) + + +#define ON 1 +#define OFF 0 + + +// Debug prints +#define OPTION_ENABLE_DBG_PRINTS ON +#define OPTION_DEBUG_LEVEL 2 +#define OPTION_UDP_DEBUG_LEVEL 0 + + +// Enable C++ class wrapper +#define OPTION_ENABLE_XCP_CLASS ON + +// Enable demo how to measure dynamic instances +#define OPTION_ENABLE_DYNAMIC_DEMO ON + + +// A2L generation +#define OPTION_ENABLE_A2L_GEN ON // Enable A2L generation +#if OPTION_ENABLE_A2L_GEN + #define OPTION_A2L_NAME "CPP_Demo" // A2L name + #define OPTION_A2L_FILE_NAME "CPP_Demo.a2l" // A2L filename +#endif + + +// Set clock resolution (for clock function in platform.c) +#define CLOCK_USE_APP_TIME_US +//#define CLOCK_USE_UTC_TIME_NS + + +// Ethernet Transport Layer +#define OPTION_USE_TCP OFF +#define OPTION_MTU 1500 // Ethernet MTU +#define OPTION_SERVER_PORT 5555 // Default UDP port +#define OPTION_SERVER_ADDR {127,0,0,1} // IP addr to bind, 0.0.0.0 = ANY + diff --git a/A2lTestDlg/A2lTestDlg/main_cfg.h.in b/A2lTestDlg/A2lTestDlg/main_cfg.h.in new file mode 100644 index 0000000..4a3f597 --- /dev/null +++ b/A2lTestDlg/A2lTestDlg/main_cfg.h.in @@ -0,0 +1,39 @@ +#pragma once + +// main_cfg.h +// CPP_Demo + +/* Copyright(c) Vector Informatik GmbH.All rights reserved. + Licensed under the MIT license.See LICENSE file in the project root for details. */ + +#define APP_CPP_Demo + +#define APP_NAME "CPP_Demo" +#define APP_VERSION_MAJOR @CPP_Demo_VERSION_MAJOR@ +#define APP_VERSION_MINOR @CPP_Demo_VERSION_MINOR@ + +//----------------------------------------------------------------------------------------------------- +// Application configuration: +// XCP configuration is in xcp_cfg.h (Protocol Layer) and xcptl_cfg.h (Transport Layer) + +#define ON 1 +#define OFF 0 + +#define OPTION_DEBUG_LEVEL @OPTION_DEBUG_LEVEL@ + +// A2L generation +#define OPTION_ENABLE_A2L_GEN ON // Enable A2L generation +#if OPTION_ENABLE_A2L_GEN +#define OPTION_ENABLE_A2L_SYMBOL_LINKS ON // Enable generation of symbol links (required for CANape integrated linker map update) +#define OPTION_A2L_NAME "CPP_Demo" // A2L name +#define OPTION_A2L_FILE_NAME "CPP_Demo.a2l" // A2L filename +#define OPTION_A2L_PROJECT_NAME "CPP_Demo" // A2L project name +#endif + +// Default communication parameters +#define OPTION_ENABLE_TCP @OPTION_ENABLE_TCP@ // Enable TCP support +#define OPTION_USE_TCP @OPTION_USE_TCP@ // Default +#define OPTION_MTU @OPTION_MTU@ // Ethernet MTU +#define OPTION_SERVER_PORT @OPTION_SERVER_PORT@ // Default UDP port, overwritten by commandline option -port +#define OPTION_SERVER_ADDR @OPTION_SERVER_ADDR@ // Default IP addr to bind, 0.0.0.0 = ANY, overwritten by commandline option -bind x.x.x.x + diff --git a/A2lTestDlg/A2lTestDlg/pch.cpp b/A2lTestDlg/A2lTestDlg/pch.cpp new file mode 100644 index 0000000..64b7eef --- /dev/null +++ b/A2lTestDlg/A2lTestDlg/pch.cpp @@ -0,0 +1,5 @@ +// pch.cpp: source file corresponding to the pre-compiled header + +#include "pch.h" + +// When you are using pre-compiled headers, this source file is necessary for compilation to succeed. diff --git a/A2lTestDlg/A2lTestDlg/pch.h b/A2lTestDlg/A2lTestDlg/pch.h new file mode 100644 index 0000000..885d5d6 --- /dev/null +++ b/A2lTestDlg/A2lTestDlg/pch.h @@ -0,0 +1,13 @@ +// pch.h: This is a precompiled header file. +// Files listed below are compiled only once, improving build performance for future builds. +// This also affects IntelliSense performance, including code completion and many code browsing features. +// However, files listed here are ALL re-compiled if any one of them is updated between builds. +// Do not add files here that you will be updating frequently as this negates the performance advantage. + +#ifndef PCH_H +#define PCH_H + +// add headers that you want to pre-compile here +#include "framework.h" + +#endif //PCH_H diff --git a/A2lTestDlg/A2lTestDlg/platform.h b/A2lTestDlg/A2lTestDlg/platform.h new file mode 100644 index 0000000..3ff2579 --- /dev/null +++ b/A2lTestDlg/A2lTestDlg/platform.h @@ -0,0 +1,183 @@ +#pragma once +/* platform.h */ +/* +| Code released into public domain, no attribution required +*/ + + +//------------------------------------------------------------------------------- +// Keyboard + +#ifdef _LINUX + +#include + +extern int _getch(); +extern int _kbhit(); + +#endif + + +//------------------------------------------------------------------------------- +// Safe sprintf + +#if defined(_WIN) // Windows +#define SPRINTF(dest,format,...) sprintf_s((char*)dest,sizeof(dest),format,__VA_ARGS__) +#define SNPRINTF(dest,len,format,...) sprintf_s((char*)dest,len,format,__VA_ARGS__) +#elif defined(_LINUX) // Linux +#define SPRINTF(dest,format,...) snprintf((char*)dest,sizeof(dest),format,__VA_ARGS__) +#define SNPRINTF(dest,len,format,...) snprintf((char*)dest,len,format,__VA_ARGS__) +#endif + + +//------------------------------------------------------------------------------- +// Delay + +// Delay based on clock +extern void sleepNs(uint32_t ns); + +// Delay - Less precise and less CPU load, not based on clock, time domain different +extern void sleepMs(uint32_t ms); + + +//------------------------------------------------------------------------------- +// Mutex + + +#if defined(_WIN) // Windows + +#define MUTEX CRITICAL_SECTION +#define mutexLock EnterCriticalSection +#define mutexUnlock LeaveCriticalSection + +#elif defined(_LINUX) // Linux + +#define MUTEX pthread_mutex_t +#define MUTEX_INTIALIZER PTHREAD_MUTEX_INITIALIZER +#define mutexLock pthread_mutex_lock +#define mutexUnlock pthread_mutex_unlock + +#endif + +void mutexInit(MUTEX* m, BOOL recursive, uint32_t spinCount); +void mutexDestroy(MUTEX* m); + + +//------------------------------------------------------------------------------- +// Threads + +#if defined(_WIN) // Windows + +typedef HANDLE tXcpThread; +#define create_thread(h,t) *h = CreateThread(0, 0, t, NULL, 0, NULL) +#define join_thread(h) WaitForSingleObject(h, INFINITE); +#define terminate_thread(h) { TerminateThread(h,0); WaitForSingleObject(h,1000); CloseHandle(h); } +#define cancel_thread terminate_thread + +#elif defined(_LINUX) // Linux + +typedef pthread_t tXcpThread; +#define create_thread(h,t) pthread_create(h, NULL, t, NULL); +#define join_thread(h) pthread_join(h,NULL); +#define detach_thread(h) { pthread_detach(h); pthread_cancel(h); } +#define cancel_thread detach_thread + +#endif + + +//------------------------------------------------------------------------------- +// Platform independant socket functions + +#ifdef _LINUX // Linux sockets + +#define SOCKET int +#define INVALID_SOCKET (-1) + +#define SOCKADDR_IN struct sockaddr_in +#define SOCKADDR struct sockaddr + +#define SOCKET_ERROR_ABORT EBADF +#define SOCKET_ERROR_RESET EBADF +#define SOCKET_ERROR_INTR EBADF +#define SOCKET_ERROR_WBLOCK EAGAIN + +#undef htonll +#define htonll(val) ((((uint64_t)htonl((uint32_t)val)) << 32) + htonl((uint32_t)(val >> 32))) + + +#define socketGetLastError() errno + +#endif + +#if defined(_WIN) // Windows // Windows sockets or XL-API + +#include +#include + +#define SOCKET_ERROR_OTHER 1 +#define SOCKET_ERROR_WBLOCK WSAEWOULDBLOCK +#define SOCKET_ERROR_ABORT WSAECONNABORTED +#define SOCKET_ERROR_RESET WSAECONNRESET +#define SOCKET_ERROR_INTR WSAEINTR + +#endif + +// Timestamp mode +#define SOCKET_TIMESTAMP_NONE 0 // No timestamps +#define SOCKET_TIMESTAMP_HW 1 // Hardware clock +#define SOCKET_TIMESTAMP_HW_SYNT 2 // Hardware clock syntonized to PC clock +#define SOCKET_TIMESTAMP_PC 3 // PC clock + +// Clock mode +#define SOCKET_TIMESTAMP_FREE_RUNNING 0 +#define SOCKET_TIMESTAMP_SOFTWARE_SYNC 1 + +extern BOOL socketStartup(); +extern int32_t socketGetLastError(); +extern void socketCleanup(); +extern BOOL socketOpen(SOCKET* sp, BOOL useTCP, BOOL nonBlocking, BOOL reuseaddr, BOOL timestamps); +extern BOOL socketBind(SOCKET sock, uint8_t* addr, uint16_t port); +extern BOOL socketJoin(SOCKET sock, uint8_t* maddr); +extern BOOL socketListen(SOCKET sock); +extern SOCKET socketAccept(SOCKET sock, uint8_t addr[]); +extern int16_t socketRecv(SOCKET sock, uint8_t* buffer, uint16_t bufferSize, BOOL waitAll); +extern int16_t socketRecvFrom(SOCKET sock, uint8_t* buffer, uint16_t bufferSize, uint8_t* srcAddr, uint16_t* srcPort, uint64_t *time); +extern int16_t socketSend(SOCKET sock, const uint8_t* buffer, uint16_t bufferSize); +extern int16_t socketSendTo(SOCKET sock, const uint8_t* buffer, uint16_t bufferSize, const uint8_t* addr, uint16_t port, uint64_t *time); +extern BOOL socketShutdown(SOCKET sock); +extern BOOL socketClose(SOCKET* sp); +extern BOOL socketGetLocalAddr(uint8_t* mac, uint8_t* addr); + + +//------------------------------------------------------------------------------- +// Clock + +// Clock resolution and epoch +#if !defined(CLOCK_USE_UTC_TIME_NS) && !defined(CLOCK_USE_APP_TIME_US) + // Default + #define CLOCK_USE_UTC_TIME_NS // Use ns timestamps relative to 1.1.1970 (TAI monotonic - no backward jumps) + //#define CLOCK_USE_APP_TIME_US // Use arbitrary us timestamps relative to application start +#endif + +#ifdef CLOCK_USE_UTC_TIME_NS + +#define CLOCK_TICKS_PER_M (1000000000ULL*60) +#define CLOCK_TICKS_PER_S 1000000000 +#define CLOCK_TICKS_PER_MS 1000000 +#define CLOCK_TICKS_PER_US 1000 +#define CLOCK_TICKS_PER_NS 1 + +#else + +#define CLOCK_TICKS_PER_S 1000000 +#define CLOCK_TICKS_PER_MS 1000 +#define CLOCK_TICKS_PER_US 1 + +#endif + +// Clock +extern BOOL clockInit(); +extern uint64_t clockGet(); +extern uint64_t clockGetLast(); +extern char* clockGetString(char* s, uint32_t l, uint64_t c); +extern char* clockGetTimeString(char* s, uint32_t l, int64_t c); diff --git a/A2lTestDlg/A2lTestDlg/res/A2lTestDlg.ico b/A2lTestDlg/A2lTestDlg/res/A2lTestDlg.ico new file mode 100644 index 0000000000000000000000000000000000000000..d56fbcdfdf6eac0f4727c34770c26689271d96af GIT binary patch literal 67777 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 NK9A-8OQnhX{{?OVn?wKr literal 0 HcmV?d00001 diff --git a/A2lTestDlg/A2lTestDlg/res/A2lTestDlg.rc2 b/A2lTestDlg/A2lTestDlg/res/A2lTestDlg.rc2 new file mode 100644 index 0000000000000000000000000000000000000000..9c3dc677a02618c72fb669fc8db239c0d9fa29ad GIT binary patch literal 804 zcmdUt%W48a5Jk^Akbfx1GQC$&B0sO*+rA)V;ZiBOrn??p zr@CgdE-1L=M!Fz)q|Jgpi6twZwV%AddbpDH>@oAjLzkq$)pN{=t;H&yM? z;YGGxM$(PuYLu~Jo|!`Vr79%Z%ozM-88X`YN8&iYzeCL`_hd@H>N%u`9vy#~VnUPo g diff --git a/A2lTestDlg/A2lTestDlg/xcp.h b/A2lTestDlg/A2lTestDlg/xcp.h new file mode 100644 index 0000000..ff355b9 --- /dev/null +++ b/A2lTestDlg/A2lTestDlg/xcp.h @@ -0,0 +1,1235 @@ +#pragma once + +/* xcp.h */ + +/* Copyright(c) Vector Informatik GmbH.All rights reserved. + Licensed under the MIT license.See LICENSE file in the project root for details. */ + + +/***************************************************************************/ +/* Commands */ +/***************************************************************************/ + +/*-------------------------------------------------------------------------*/ +/* Standard Commands */ + +#define CC_CONNECT 0xFF +#define CC_DISCONNECT 0xFE +#define CC_GET_STATUS 0xFD +#define CC_SYNCH 0xFC + +#define CC_GET_COMM_MODE_INFO 0xFB +#define CC_GET_ID 0xFA +#define CC_SET_REQUEST 0xF9 +#define CC_GET_SEED 0xF8 +#define CC_UNLOCK 0xF7 +#define CC_SET_MTA 0xF6 +#define CC_UPLOAD 0xF5 +#define CC_SHORT_UPLOAD 0xF4 +#define CC_BUILD_CHECKSUM 0xF3 + +#define CC_TRANSPORT_LAYER_CMD 0xF2 +#define CC_USER_CMD 0xF1 + + +/*-------------------------------------------------------------------------*/ +/* Calibration Commands*/ + +#define CC_DOWNLOAD 0xF0 + +#define CC_DOWNLOAD_NEXT 0xEF +#define CC_DOWNLOAD_MAX 0xEE +#define CC_SHORT_DOWNLOAD 0xED +#define CC_MODIFY_BITS 0xEC + + +/*-------------------------------------------------------------------------*/ +/* Page switching Commands (PAG) */ + +#define CC_SET_CAL_PAGE 0xEB +#define CC_GET_CAL_PAGE 0xEA + +#define CC_GET_PAG_PROCESSOR_INFO 0xE9 +#define CC_GET_SEGMENT_INFO 0xE8 +#define CC_GET_PAGE_INFO 0xE7 +#define CC_SET_SEGMENT_MODE 0xE6 +#define CC_GET_SEGMENT_MODE 0xE5 +#define CC_COPY_CAL_PAGE 0xE4 + + +/*-------------------------------------------------------------------------*/ +/* Data acquisition and Stimulation Commands (DAQ/STIM) */ + +#define CC_CLEAR_DAQ_LIST 0xE3 +#define CC_SET_DAQ_PTR 0xE2 +#define CC_WRITE_DAQ 0xE1 +#define CC_SET_DAQ_LIST_MODE 0xE0 +#define CC_GET_DAQ_LIST_MODE 0xDF +#define CC_START_STOP_DAQ_LIST 0xDE +#define CC_START_STOP_SYNCH 0xDD + +#define CC_GET_DAQ_CLOCK 0xDC +#define CC_READ_DAQ 0xDB +#define CC_GET_DAQ_PROCESSOR_INFO 0xDA +#define CC_GET_DAQ_RESOLUTION_INFO 0xD9 +#define CC_GET_DAQ_LIST_INFO 0xD8 +#define CC_GET_DAQ_EVENT_INFO 0xD7 + +#define CC_FREE_DAQ 0xD6 +#define CC_ALLOC_DAQ 0xD5 +#define CC_ALLOC_ODT 0xD4 +#define CC_ALLOC_ODT_ENTRY 0xD3 + + +/*-------------------------------------------------------------------------*/ +/* Non volatile memory Programming Commands PGM */ + +#define CC_PROGRAM_START 0xD2 +#define CC_PROGRAM_CLEAR 0xD1 +#define CC_PROGRAM 0xD0 +#define CC_PROGRAM_RESET 0xCF +#define CC_GET_PGM_PROCESSOR_INFO 0xCE +#define CC_GET_SECTOR_INFO 0xCD +#define CC_PROGRAM_PREPARE 0xCC +#define CC_PROGRAM_FORMAT 0xCB +#define CC_PROGRAM_NEXT 0xCA +#define CC_PROGRAM_MAX 0xC9 +#define CC_PROGRAM_VERIFY 0xC8 + +/*-------------------------------------------------------------------------*/ +/* XCP >= V1.1 Commands */ +# define CC_WRITE_DAQ_MULTIPLE 0xC7 /* XCP V1.1 specific commands */ + +/*-------------------------------------------------------------------------*/ +/* XCP >= V1.3 Commands */ +#if XCP_PROTOCOL_LAYER_VERSION >= 0x0103 +# define CC_TIME_CORRELATION_PROPERTIES 0xC6 /* XCP V1.3 specific commands */ +#endif + +/*-------------------------------------------------------------------------*/ +/* XCP >= V1.4 Commands */ +#if XCP_PROTOCOL_LAYER_VERSION >= 0x0104 +#define CC_LEVEL_1_COMMAND 0xC0 /* XCP V1.4 Level 1 Commands: */ +#define CC_GET_VERSION 0x00 +#define CC_SET_DAQ_LIST_PACKED_MODE 0x01 +#define CC_GET_DAQ_LIST_PACKED_MODE 0x02 +#define CC_SW_DBG_OVER_XCP 0xFC +#endif + +/*-------------------------------------------------------------------------*/ +/* Packet Identifiers Server -> Master */ +#define PID_RES 0xFF /* response packet */ +#define PID_ERR 0xFE /* error packet */ +#define PID_EV 0xFD /* event packet */ +#define PID_SERV 0xFC /* service request packet */ + + +/*-------------------------------------------------------------------------*/ +/* Command Return Codes */ + +#define CRC_CMD_SYNCH 0x00 +#define CRC_CMD_PENDING 0x01 +#define CRC_CMD_BUSY 0x10 +#define CRC_DAQ_ACTIVE 0x11 +#define CRC_PRM_ACTIVE 0x12 +#define CRC_CMD_UNKNOWN 0x20 +#define CRC_CMD_SYNTAX 0x21 +#define CRC_OUT_OF_RANGE 0x22 +#define CRC_WRITE_PROTECTED 0x23 +#define CRC_ACCESS_DENIED 0x24 +#define CRC_ACCESS_LOCKED 0x25 +#define CRC_PAGE_NOT_VALID 0x26 +#define CRC_PAGE_MODE_NOT_VALID 0x27 +#define CRC_SEGMENT_NOT_VALID 0x28 +#define CRC_SEQUENCE 0x29 +#define CRC_DAQ_CONFIG 0x2A +#define CRC_MEMORY_OVERFLOW 0x30 +#define CRC_GENERIC 0x31 +#define CRC_VERIFY 0x32 +#define CRC_RESOURCE_TEMPORARY_NOT_ACCESSIBLE 0x33 +#define CRC_SUBCMD_UNKNOWN 0x34 +#define CRC_TIMECORR_STATE_CHANGE 0x35 + + +/*-------------------------------------------------------------------------*/ +/* Event Codes */ + +#define EVC_RESUME_MODE 0x00 +#define EVC_CLEAR_DAQ 0x01 +#define EVC_STORE_DAQ 0x02 +#define EVC_STORE_CAL 0x03 +#define EVC_CMD_PENDING 0x05 +#define EVC_DAQ_OVERLOAD 0x06 +#define EVC_SESSION_TERMINATED 0x07 +#define EVC_TIME_SYNCH 0x08 +#define EVC_STIM_TIMEOUT 0x09 +#define EVC_SLEEP 0x0A +#define EVC_WAKEUP 0x0B +#define EVC_ECU_STATE 0x0C +#define EVC_USER 0xFE +#define EVC_TRANSPORT 0xFF + + +/*-------------------------------------------------------------------------*/ +/* Service Request Codes */ + +#define SERV_RESET 0x00 /* Server requesting to be reset */ +#define SERV_TEXT 0x01 /* Plain ASCII text null terminated */ + + + + +/***************************************************************************/ +/* Definitions */ +/***************************************************************************/ + +/*-------------------------------------------------------------------------*/ +/* ResourceMask (CONNECT) */ + +#define RM_CAL_PAG 0x01 +#define RM_DAQ 0x04 +#define RM_STIM 0x08 +#define RM_PGM 0x10 +#define RM_DBG 0x20 + + +/*-------------------------------------------------------------------------*/ +/* CommModeBasic (CONNECT) */ + +#define PI_MOTOROLA 0x01 + +#define CMB_BYTE_ORDER (0x01u<<0) +#define CMB_ADDRESS_GRANULARITY (0x03u<<1) +#define CMB_SERVER_BLOCK_MODE (0x01u<<6) +#define CMB_OPTIONAL (0x01u<<7) + +#define CMB_ADDRESS_GRANULARITY_BYTE (0<<1) +#define CMB_ADDRESS_GRANULARITY_WORD (1<<1) +#define CMB_ADDRESS_GRANULARITY_DWORD (2<<1) +#define CMB_ADDRESS_GRANULARITY_QWORD (3<<1) + + +/*-------------------------------------------------------------------------*/ +/* Protocol Info (GET_COMM_MODE_INFO - COMM_OPTIONAL) */ + +#define CMO_MASTER_BLOCK_MODE 0x01 +#define CMO_INTERLEAVED_MODE 0x02 + + +/*-------------------------------------------------------------------------*/ +/* Session Status (GET_STATUS and SET_REQUEST) */ + +// XCP states (low byte) */ +#define SS_STORE_CAL_REQ ((uint16_t)0x0001) +#define SS_STORE_DAQ_REQ ((uint16_t)0x0004) +#define SS_CLEAR_DAQ_REQ ((uint16_t)0x0008) +#define SS_DAQ ((uint16_t)0x0040) +#define SS_RESUME ((uint16_t)0x0080) + +// Internal states (high byte) */ +#define SS_BLOCK_UPLOAD ((uint16_t)0x0100) /* Block upload in progress */ +#define SS_LEGACY_MODE ((uint16_t)0x0200) /* XCP 1.3 legacy mode */ +#define SS_CMD_PENDING ((uint16_t)0x0800) /* async comand pending */ +#define SS_INITIALIZED ((uint16_t)0x8000) /* initialized */ +#define SS_STARTED ((uint16_t)0x4000) /* started*/ +#define SS_CONNECTED ((uint16_t)0x2000) /* connected */ + + +/*-------------------------------------------------------------------------*/ +/* Identifier Type (GET_ID) */ + +#define IDT_ASCII 0 +#define IDT_ASAM_NAME 1 +#define IDT_ASAM_PATH 2 +#define IDT_ASAM_URL 3 +#define IDT_ASAM_UPLOAD 4 +#define IDT_ASAM_EPK 5 +#define IDT_ASAM_ECU 6 +#define IDT_ASAM_SYSID 7 + +/*-------------------------------------------------------------------------*/ +/* Checksum Types (BUILD_CHECKSUM) */ + +#define XCP_CHECKSUM_TYPE_ADD11 0x01 /* Add BYTE into a BYTE checksum, ignore overflows */ +#define XCP_CHECKSUM_TYPE_ADD12 0x02 /* Add BYTE into a WORD checksum, ignore overflows */ +#define XCP_CHECKSUM_TYPE_ADD14 0x03 /* Add BYTE into a DWORD checksum, ignore overflows */ +#define XCP_CHECKSUM_TYPE_ADD22 0x04 /* Add WORD into a WORD checksum, ignore overflows, blocksize must be modulo 2 */ +#define XCP_CHECKSUM_TYPE_ADD24 0x05 /* Add WORD into a DWORD checksum, ignore overflows, blocksize must be modulo 2 */ +#define XCP_CHECKSUM_TYPE_ADD44 0x06 /* Add DWORD into DWORD, ignore overflows, blocksize must be modulo 4 */ +#define XCP_CHECKSUM_TYPE_CRC16 0x07 /* See CRC error detection algorithms */ +#define XCP_CHECKSUM_TYPE_CRC16CCITT 0x08 /* See CRC error detection algorithms */ +#define XCP_CHECKSUM_TYPE_CRC32 0x09 /* See CRC error detection algorithms */ +#define XCP_CHECKSUM_TYPE_DLL 0xFF /* User defined, ASAM MCD 2MC DLL Interface */ + + +/*-------------------------------------------------------------------------*/ +/* Page Mode (SET_CAL_PAGE) */ + +#define CAL_PAGE_MODE_ECU 0x01 +#define CAL_PAGE_MODE_XCP 0x02 +#define CAL_PAGE_MODE_ALL 0x80 + + +/*-------------------------------------------------------------------------*/ +/* PAG_PROPERTIES (GET_PAG_PROCESSOR_INFO) */ + +#define PAG_PROPERTY_FREEZE 0x01 + + +/*-------------------------------------------------------------------------*/ +/* PAGE_PROPERTIES (GET_PAGE_INFO)*/ + +#define ECU_ACCESS_TYPE 0x03 +#define XCP_READ_ACCESS_TYPE 0x0C +#define XCP_WRITE_ACCESS_TYPE 0x30 + +/* ECU_ACCESS_TYPE */ +#define ECU_ACCESS_NONE (0<<0) +#define ECU_ACCESS_WITHOUT (1<<0) +#define ECU_ACCESS_WITH (2<<0) +#define ECU_ACCESS_DONT_CARE (3<<0) + +/* XCP_READ_ACCESS_TYPE */ +#define XCP_READ_ACCESS_NONE (0<<2) +#define XCP_READ_ACCESS_WITHOUT (1<<2) +#define XCP_READ_ACCESS_WITH (2<<2) +#define XCP_READ_ACCESS_DONT_CARE (3<<2) + +/* XCP_WRITE_ACCESS_TYPE */ +#define XCP_WRITE_ACCESS_NONE (0<<4) +#define XCP_WRITE_ACCESS_WITHOUT (1<<4) +#define XCP_WRITE_ACCESS_WITH (2<<4) +#define XCP_WRITE_ACCESS_DONT_CARE (3<<4) + + +/*-------------------------------------------------------------------------*/ +/* SEGMENT_MODE (GET_SEGMENT_MODE, SET_SEGMENT_MODE) */ + +#define SEGMENT_FLAG_FREEZE 0x01 /* */ + + +/*-------------------------------------------------------------------------*/ +/* DAQ list flags (from GET_DAQ_LIST_MODE, SET_DAQ_LIST_MODE) */ + +// DAQ list mode bit mask coding +#define DAQ_MODE_ALTERNATING ((uint8_t)0x01) /* Bit0 - Enable/disable alternating display mode */ +#define DAQ_MODE_DIRECTION ((uint8_t)0x02) /* Bit1 - DAQ list stim mode */ +#define DAQ_MODE_RESERVED2 ((uint8_t)0x04) /* Bit2 - Not used */ +#define DAQ_MODE_DTO_CTR ((uint8_t)0x08) /* Bit3 - Use DTO CTR field */ +#define DAQ_MODE_TIMESTAMP ((uint8_t)0x10) /* Bit4 - Enable timestamp */ +#define DAQ_MODE_PID_OFF ((uint8_t)0x20) /* Bit5 - Disable PID */ +#define DAQ_MODE_RESERVED6 ((uint8_t)0x40) /* Bit6 - Not used */ +#define DAQ_MODE_RESERVED7 ((uint8_t)0x80) /* Bit7 - Not used */ + + +/*-------------------------------------------------------------------------*/ +/* DAQ list state */ + +// DAQ list state bit mask coding +#define DAQ_STATE_STOPPED_UNSELECTED ((uint8_t)0x00) /* Not selected, stopped */ +#define DAQ_STATE_SELECTED ((uint8_t)0x01) /* Selected */ +#define DAQ_STATE_RUNNING ((uint8_t)0x02) /* Running */ +#define DAQ_STATE_OVERRUN ((uint8_t)0x04) /* Overrun */ + + + +/*-------------------------------------------------------------------------*/ +/* GET_DAQ_PROCESSOR_INFO */ + +/* DAQ_PROPERTIES */ +#define DAQ_PROPERTY_CONFIG_TYPE 0x01 +#define DAQ_PROPERTY_PRESCALER 0x02 +#define DAQ_PROPERTY_RESUME 0x04 +#define DAQ_PROPERTY_BIT_STIM 0x08 +#define DAQ_PROPERTY_TIMESTAMP 0x10 +#define DAQ_PROPERTY_NO_PID 0x20 +#define DAQ_PROPERTY_OVERLOAD_INDICATION 0xC0 + +/* DAQ Overload Indication Type */ +#define DAQ_OVERLOAD_INDICATION_NONE (0<<6) +#define DAQ_OVERLOAD_INDICATION_PID (1<<6) +#define DAQ_OVERLOAD_INDICATION_EVENT (2<<6) + +/* DAQ_KEY_BYTE */ +#define DAQ_OPT_TYPE 0x0F +#define DAQ_EXT_TYPE 0x30 +#define DAQ_HDR_TYPE 0xC0 + +/* DAQ Optimisation Type */ +#define DAQ_OPT_DEFAULT (0<<0) +#define DAQ_OPT_ODT_16 (1<<0) +#define DAQ_OPT_ODT_32 (2<<0) +#define DAQ_OPT_ODT_64 (3<<0) +#define DAQ_OPT_ALIGNMENT (4<<0) +#define DAQ_OPT_MAX_ENTRY_SIZE (5<<0) + +/* DAQ Address Extension Scope */ +#define DAQ_EXT_FREE (0<<4) +#define DAQ_EXT_ODT (1<<4) +#define DAQ_EXT_DAQ (3<<4) + +/* DAQ Identification Field Type */ +#define DAQ_HDR_PID (0<<6) +#define DAQ_HDR_ODT_DAQB (1<<6) +#define DAQ_HDR_ODT_DAQW (2<<6) +#define DAQ_HDR_ODT_FIL_DAQW (3<<6) + + +/*-------------------------------------------------------------------------*/ +/* GET_DAQ_RESOLUTION_INFO */ + +/* TIMESTAMP_MODE Bitmasks */ +#define DAQ_TIMESTAMP_TYPE 0x07 +#define DAQ_TIMESTAMP_FIXED 0x08 +#define DAQ_TIMESTAMP_UNIT 0xF0 + +/* DAQ Timestamp Type */ +#define DAQ_TIMESTAMP_OFF (0<<0) +#define DAQ_TIMESTAMP_BYTE (1<<0) +#define DAQ_TIMESTAMP_WORD (2<<0) +#define DAQ_TIMESTAMP_DWORD (4<<0) + +/* DAQ Timestamp Unit */ +#define DAQ_TIMESTAMP_UNIT_1NS (0<<4) +#define DAQ_TIMESTAMP_UNIT_10NS (1<<4) +#define DAQ_TIMESTAMP_UNIT_100NS (2<<4) +#define DAQ_TIMESTAMP_UNIT_1US (3<<4) +#define DAQ_TIMESTAMP_UNIT_10US (4<<4) +#define DAQ_TIMESTAMP_UNIT_100US (5<<4) +#define DAQ_TIMESTAMP_UNIT_1MS (6<<4) +#define DAQ_TIMESTAMP_UNIT_10MS (7<<4) +#define DAQ_TIMESTAMP_UNIT_100MS (8<<4) +#define DAQ_TIMESTAMP_UNIT_1S (9<<4) + + +/*-------------------------------------------------------------------------*/ +/* DAQ_LIST_PROPERTIES (GET_DAQ_LIST_INFO) */ + +#define DAQ_LIST_PREDEFINED 0x01 +#define DAQ_LIST_FIXED_EVENT 0x02 +#define DAQ_LIST_DIR_DAQ 0x04 +#define DAQ_LIST_DIR_STIM 0x08 +#define DAQ_LIST_PACKED 0x10 + + +/*-------------------------------------------------------------------------*/ +/* EVENT_PROPERTY (GET_DAQ_EVENT_INFO) */ + +#define DAQ_EVENT_DIRECTION_DAQ 0x04 +#define DAQ_EVENT_DIRECTION_STIM 0x08 +#define DAQ_EVENT_DIRECTION_DAQ_STIM 0x0C + + +/*-------------------------------------------------------------------------*/ +/* Comm mode programming parameter (PROGRAM_START) */ + +#define PI_PGM_BLOCK_DOWNLOAD 0x01 +#define PI_PGM_BLOCK_UPLOAD 0x40 + + +/*-------------------------------------------------------------------------*/ +/* PGM_PROPERTIES (GET_PGM_PROCESSOR_INFO) */ + +#define PGM_ACCESS_TYPE 0x03 +#define PGM_COMPRESSION_TYPE 0x0C +#define PGM_ENCRYPTION_TYPE 0x30 +#define PGM_NON_SEQ_TYPE 0xC0 + +/* PGM Access Mode */ +#define PGM_ACCESS_ABSOLUTE (1<<0) +#define PGM_ACCESS_FUNCTIONAL (2<<0) +#define PGM_ACCESS_FREE (3<<0) + +/* PGM Compression type */ +#define PGM_COMPRESSION_NONE (0<<2) +#define PGM_COMPRESSION_SUPPORTED (1<<2) +#define PGM_COMPRESSION_REQUIRED (3<<2) + +/* PGM Encryption type */ +#define PGM_ENCRYPTION_NONE (0<<4) +#define PGM_ENCRYPTION_SUPPORTED (1<<4) +#define PGM_ENCRYPTION_REQUIRED (3<<4) + +/* PGM non sequential programming type */ +#define PGM_NON_SEQ_NONE (0<<6) +#define PGM_NON_SEQ_SUPPORTED (1<<6) +#define PGM_NON_SEQ_REQUIRED (3<<6) + + +/***************************************************************************/ +/* XCP Protocol Commands and Responces, Type Definition */ +/***************************************************************************/ + +/* Protocol command structure definition */ +#define CRO_CMD CRO_BYTE(0) +#define CRM_CMD CRM_BYTE(0) +#define CRM_ERR CRM_BYTE(1) +#define CRM_EVENTCODE CRM_BYTE(1) + + + +/* CONNECT */ +#define CRO_CONNECT_LEN 2 +#define CRO_CONNECT_MODE CRO_BYTE(1) +#define CRM_CONNECT_LEN 8 +#define CRM_CONNECT_RESOURCE CRM_BYTE(1) +#define CRM_CONNECT_COMM_BASIC CRM_BYTE(2) +#define CRM_CONNECT_MAX_CTO_SIZE CRM_BYTE(3) +#define CRM_CONNECT_MAX_DTO_SIZE CRM_WORD(2) +#define CRM_CONNECT_PROTOCOL_VERSION CRM_BYTE(6) +#define CRM_CONNECT_TRANSPORT_VERSION CRM_BYTE(7) + + +/* DISCONNECT */ +#define CRO_DISCONNECT_LEN 1 +#define CRM_DISCONNECT_LEN 1 + + +/* GET_STATUS */ +#define CRO_GET_STATUS_LEN 1 +#define CRM_GET_STATUS_LEN 6 +#define CRM_GET_STATUS_STATUS CRM_BYTE(1) +#define CRM_GET_STATUS_PROTECTION CRM_BYTE(2) +#define CRM_GET_STATUS_CONFIG_ID CRM_WORD(2) + +/* SYNCH */ +#define CRO_SYNCH_LEN 1 +#define CRM_SYNCH_LEN 2 +#define CRM_SYNCH_RESULT CRM_BYTE(1) + + +/* GET_COMM_MODE_INFO */ +#define CRO_GET_COMM_MODE_INFO_LEN 1 +#define CRM_GET_COMM_MODE_INFO_LEN 8 +#define CRM_GET_COMM_MODE_INFO_COMM_OPTIONAL CRM_BYTE(2) +#define CRM_GET_COMM_MODE_INFO_MAX_BS CRM_BYTE(4) +#define CRM_GET_COMM_MODE_INFO_MIN_ST CRM_BYTE(5) +#define CRM_GET_COMM_MODE_INFO_QUEUE_SIZE CRM_BYTE(6) +#define CRM_GET_COMM_MODE_INFO_DRIVER_VERSION CRM_BYTE(7) + + +/* GET_ID */ +#define CRO_GET_ID_LEN 2 +#define CRO_GET_ID_TYPE CRO_BYTE(1) +#define CRM_GET_ID_LEN 8 +#define CRM_GET_ID_MODE CRM_BYTE(1) +#define CRM_GET_ID_LENGTH CRM_DWORD(1) +#define CRM_GET_ID_DATA (&CRM_BYTE(8)) +#define CRM_GET_ID_DATA_MAX_LEN (sizeof(CRM)-8) + +/* SET_REQUEST */ +#define CRO_SET_REQUEST_LEN 4 +#define CRO_SET_REQUEST_MODE CRO_BYTE(1) +#define CRO_SET_REQUEST_CONFIG_ID CRO_WORD(1) +#define CRM_SET_REQUEST_LEN 1 + + +/* GET_SEED */ +#define CRO_GET_SEED_LEN 3 +#define CRO_GET_SEED_MODE CRO_BYTE(1) +#define CRO_GET_SEED_RESOURCE CRO_BYTE(2) +#define CRM_GET_SEED_LEN (CRM_GET_SEED_LENGTH+2u) +#define CRM_GET_SEED_LENGTH CRM_BYTE(1) +#define CRM_GET_SEED_DATA (&CRM_BYTE(2)) + + +/* UNLOCK */ +#define CRO_UNLOCK_LEN 8 +#define CRO_UNLOCK_LENGTH CRO_BYTE(1) +#define CRO_UNLOCK_KEY (&CRO_BYTE(2)) +#define CRM_UNLOCK_LEN 2 +#define CRM_UNLOCK_PROTECTION CRM_BYTE(1) + + +/* SET_MTA */ +#define CRO_SET_MTA_LEN 8 +#define CRO_SET_MTA_EXT CRO_BYTE(3) +#define CRO_SET_MTA_ADDR CRO_DWORD(1) +#define CRM_SET_MTA_LEN 1 + + +/* UPLOAD */ +#define CRO_UPLOAD_LEN 2 +#define CRO_UPLOAD_SIZE CRO_BYTE(1) +#define CRM_UPLOAD_MAX_SIZE ((uint8_t)(XCPTL_MAX_CTO_SIZE-1)) +#define CRM_UPLOAD_LEN 1 /* +CRO_UPLOAD_SIZE */ +#define CRM_UPLOAD_DATA (&CRM_BYTE(1)) + + +/* SHORT_UPLOAD */ +#define CRO_SHORT_UPLOAD_LEN 8 +#define CRO_SHORT_UPLOAD_SIZE CRO_BYTE(1) +#define CRO_SHORT_UPLOAD_EXT CRO_BYTE(3) +#define CRO_SHORT_UPLOAD_ADDR CRO_DWORD(1) +#define CRM_SHORT_UPLOAD_MAX_SIZE ((uint8_t)(XCPTL_MAX_CTO_SIZE-1)) +#define CRM_SHORT_UPLOAD_LEN 1u /* +CRO_SHORT_UPLOAD_SIZE */ +#define CRM_SHORT_UPLOAD_DATA (&CRM_BYTE(1)) + + +/* BUILD_CHECKSUM */ +#define CRO_BUILD_CHECKSUM_LEN 8 +#define CRO_BUILD_CHECKSUM_SIZE CRO_DWORD(1) +#define CRM_BUILD_CHECKSUM_LEN 8 +#define CRM_BUILD_CHECKSUM_TYPE CRM_BYTE(1) +#define CRM_BUILD_CHECKSUM_RESULT CRM_DWORD(1) + + +/* DOWNLOAD */ +#define CRO_DOWNLOAD_MAX_SIZE ((uint8_t)(XCPTL_MAX_CTO_SIZE-2)) +#define CRO_DOWNLOAD_LEN 2 /* + CRO_DOWNLOAD_SIZE */ +#define CRO_DOWNLOAD_SIZE CRO_BYTE(1) +#define CRO_DOWNLOAD_DATA (&CRO_BYTE(2)) +#define CRM_DOWNLOAD_LEN 1 + + +/* DOWNLOAD_NEXT */ +#define CRO_DOWNLOAD_NEXT_MAX_SIZE ((uint8_t)(XCPTL_MAX_CTO_SIZE-2)) +#define CRO_DOWNLOAD_NEXT_LEN 2 /* + size */ +#define CRO_DOWNLOAD_NEXT_SIZE CRO_BYTE(1) +#define CRO_DOWNLOAD_NEXT_DATA (&CRO_BYTE(2)) +#define CRM_DOWNLOAD_NEXT_LEN 1 + + +/* DOWNLOAD_MAX */ +#define CRO_DOWNLOAD_MAX_MAX_SIZE ((uint8_t)(XCPTL_MAX_CTO_SIZE-1)) +#define CRO_DOWNLOAD_MAX_DATA (&CRO_BYTE(1)) +#define CRM_DOWNLOAD_MAX_LEN 1 + + +/* SHORT_DOWNLOAD */ +#define CRO_SHORT_DOWNLOAD_MAX_SIZE ((uint8_t)(XCPTL_MAX_CTO_SIZE-8)) +#define CRO_SHORT_DOWNLOAD_LEN 8 +#define CRO_SHORT_DOWNLOAD_SIZE CRO_BYTE(1) +#define CRO_SHORT_DOWNLOAD_EXT CRO_BYTE(3) +#define CRO_SHORT_DOWNLOAD_ADDR CRO_DWORD(1) +#define CRO_SHORT_DOWNLOAD_DATA (&CRO_BYTE(8)) +#define CRM_SHORT_DOWNLOAD_LEN 1 /* +CRO_SHORT_UPLOAD_SIZE */ + + +/* MODIFY_BITS */ +#define CRO_MODIFY_BITS_LEN 6 +#define CRO_MODIFY_BITS_SHIFT CRO_BYTE(1) +#define CRO_MODIFY_BITS_AND CRO_WORD(1) +#define CRO_MODIFY_BITS_XOR CRO_WORD(2) +#define CRM_MODIFY_BITS_LEN 1 + + +/* SET_CAL_PAGE */ +#define CRO_SET_CAL_PAGE_LEN 4 +#define CRO_SET_CAL_PAGE_MODE CRO_BYTE(1) +#define CRO_SET_CAL_PAGE_SEGMENT CRO_BYTE(2) +#define CRO_SET_CAL_PAGE_PAGE CRO_BYTE(3) +#define CRM_SET_CAL_PAGE_LEN 1 + + +/* GET_CAL_PAGE */ +#define CRO_GET_CAL_PAGE_LEN 3 +#define CRO_GET_CAL_PAGE_MODE CRO_BYTE(1) +#define CRO_GET_CAL_PAGE_SEGMENT CRO_BYTE(2) +#define CRM_GET_CAL_PAGE_LEN 4 +#define CRM_GET_CAL_PAGE_PAGE CRM_BYTE(3) + + +/* GET_PAG_PROCESSOR_INFO */ +#define CRO_GET_PAG_PROCESSOR_INFO_LEN 1 +#define CRM_GET_PAG_PROCESSOR_INFO_LEN 3 +#define CRM_GET_PAG_PROCESSOR_INFO_MAX_SEGMENT CRM_BYTE(1) +#define CRM_GET_PAG_PROCESSOR_INFO_PROPERTIES CRM_BYTE(2) + + +/* GET_SEGMENT_INFO */ +#define CRO_GET_SEGMENT_INFO_LEN 5 +#define CRO_GET_SEGMENT_INFO_MODE CRO_BYTE(1) +#define CRO_GET_SEGMENT_INFO_NUMBER CRO_BYTE(2) +#define CRO_GET_SEGMENT_INFO_MAPPING_INDEX CRO_BYTE(3) +#define CRO_GET_SEGMENT_INFO_MAPPING CRO_BYTE(4) +#define CRM_GET_SEGMENT_INFO_LEN 8 +#define CRM_GET_SEGMENT_INFO_MAX_PAGES CRM_BYTE(1) +#define CRM_GET_SEGMENT_INFO_ADDRESS_EXTENSION CRM_BYTE(2) +#define CRM_GET_SEGMENT_INFO_MAX_MAPPING CRM_BYTE(3) +#define CRM_GET_SEGMENT_INFO_COMPRESSION CRM_BYTE(4) +#define CRM_GET_SEGMENT_INFO_ENCRYPTION CRM_BYTE(5) +#define CRM_GET_SEGMENT_INFO_MAPPING_INFO CRM_DWORD(1) + + +/* GET_PAGE_INFO */ +#define CRO_GET_PAGE_INFO_LEN 4 +#define CRO_GET_PAGE_INFO_SEGMENT_NUMBER CRO_BYTE(2) +#define CRO_GET_PAGE_INFO_PAGE_NUMBER CRO_BYTE(3) +#define CRM_GET_PAGE_INFO_LEN 3 +#define CRM_GET_PAGE_INFO_PROPERTIES CRM_BYTE(1) +#define CRM_GET_PAGE_INFO_INIT_SEGMENT CRM_BYTE(2) + + +/* SET_SEGMENT_MODE */ +#define CRO_SET_SEGMENT_MODE_LEN 3 +#define CRO_SET_SEGMENT_MODE_MODE CRO_BYTE(1) +#define CRO_SET_SEGMENT_MODE_SEGMENT CRO_BYTE(2) +#define CRM_SET_SEGMENT_MODE_LEN 1 + + +/* GET_SEGMENT_MODE */ +#define CRO_GET_SEGMENT_MODE_LEN 3 +#define CRO_GET_SEGMENT_MODE_SEGMENT CRO_BYTE(2) +#define CRM_GET_SEGMENT_MODE_LEN 3 +#define CRM_GET_SEGMENT_MODE_MODE CRM_BYTE(2) + + +/* COPY_CAL_PAGE */ +#define CRO_COPY_CAL_PAGE_LEN 5 +#define CRO_COPY_CAL_PAGE_SRC_SEGMENT CRO_BYTE(1) +#define CRO_COPY_CAL_PAGE_SRC_PAGE CRO_BYTE(2) +#define CRO_COPY_CAL_PAGE_DEST_SEGMENT CRO_BYTE(3) +#define CRO_COPY_CAL_PAGE_DEST_PAGE CRO_BYTE(4) +#define CRM_COPY_CAL_PAGE_LEN 1 + + +/* CLEAR_DAQ_LIST */ +#define CRO_CLEAR_DAQ_LIST_LEN 4 +#define CRO_CLEAR_DAQ_LIST_DAQ CRO_WORD(1) +#define CRM_CLEAR_DAQ_LIST_LEN 1 + + +/* SET_DAQ_PTR */ +#define CRO_SET_DAQ_PTR_LEN 6 +#define CRO_SET_DAQ_PTR_DAQ CRO_WORD(1) +#define CRO_SET_DAQ_PTR_ODT CRO_BYTE(4) +#define CRO_SET_DAQ_PTR_IDX CRO_BYTE(5) +#define CRM_SET_DAQ_PTR_LEN 1 + + +/* WRITE_DAQ */ +#define CRO_WRITE_DAQ_LEN 8 +#define CRO_WRITE_DAQ_BITOFFSET CRO_BYTE(1) +#define CRO_WRITE_DAQ_SIZE CRO_BYTE(2) +#define CRO_WRITE_DAQ_EXT CRO_BYTE(3) +#define CRO_WRITE_DAQ_ADDR CRO_DWORD(1) +#define CRM_WRITE_DAQ_LEN 1 + + +/* WRITE_DAQ_MULTIPLE */ +#define CRO_WRITE_DAQ_MULTIPLE_LEN(n) (2+(n)*8) +#define CRO_WRITE_DAQ_MULTIPLE_NODAQ CRO_BYTE(1) +#define CRO_WRITE_DAQ_MULTIPLE_BITOFFSET(i) CRO_BYTE(2 + (8*(i))) +#define CRO_WRITE_DAQ_MULTIPLE_SIZE(i) CRO_BYTE(3 + (8*(i))) +#define CRO_WRITE_DAQ_MULTIPLE_ADDR(i) CRO_DWORD(1 + (2*(i))) +#define CRO_WRITE_DAQ_MULTIPLE_EXT(i) CRO_BYTE(8 + (8*(i))) +#define CRM_WRITE_DAQ_MULTIPLE_LEN 1 + + +/* SET_DAQ_LIST_MODE */ +#define CRO_SET_DAQ_LIST_MODE_LEN 8 +#define CRO_SET_DAQ_LIST_MODE_MODE CRO_BYTE(1) +#define CRO_SET_DAQ_LIST_MODE_DAQ CRO_WORD(1) +#define CRO_SET_DAQ_LIST_MODE_EVENTCHANNEL CRO_WORD(2) +#define CRO_SET_DAQ_LIST_MODE_PRESCALER CRO_BYTE(6) +#define CRO_SET_DAQ_LIST_MODE_PRIORITY CRO_BYTE(7) +#define CRM_SET_DAQ_LIST_MODE_LEN 6 + + +/* GET_DAQ_LIST_MODE */ +#define CRO_GET_DAQ_LIST_MODE_LEN 4 +#define CRO_GET_DAQ_LIST_MODE_DAQ CRO_WORD(1) +#define CRM_GET_DAQ_LIST_MODE_LEN 8 +#define CRM_GET_DAQ_LIST_MODE_MODE CRM_BYTE(1) +#define CRM_GET_DAQ_LIST_MODE_EVENTCHANNEL CRM_WORD(2) +#define CRM_GET_DAQ_LIST_MODE_PRESCALER CRM_BYTE(6) +#define CRM_GET_DAQ_LIST_MODE_PRIORITY CRM_BYTE(7) + + +/* START_STOP_DAQ_LIST */ +#define CRO_START_STOP_DAQ_LIST_LEN 4 +#define CRO_START_STOP_DAQ_LIST_MODE CRO_BYTE(1) +#define CRO_START_STOP_DAQ_LIST_DAQ CRO_WORD(1) +#define CRM_START_STOP_DAQ_LIST_LEN 2 +#define CRM_START_STOP_DAQ_LIST_FIRST_PID CRM_BYTE(1) + + +/* START_STOP_SYNCH */ +#define CRO_START_STOP_SYNCH_LEN 2 +#define CRO_START_STOP_SYNCH_MODE CRO_BYTE(1) +#define CRM_START_STOP_SYNCH_LEN 1 + + +/* GET_DAQ_CLOCK */ +#define CRO_GET_DAQ_CLOCK_LEN 1 +#define CRM_GET_DAQ_CLOCK_LEN 8 + +#if XCP_PROTOCOL_LAYER_VERSION >= 0x0103 +#define CRM_GET_DAQ_CLOCK_RES1 CRM_BYTE(1) // 1 +#define CRM_GET_DAQ_CLOCK_TRIGGER_INFO CRM_BYTE(2) // 2 +#define CRM_GET_DAQ_CLOCK_PAYLOAD_FMT CRM_BYTE(3) // 3 + +#define CRM_GET_DAQ_CLOCK_TIME CRM_DWORD(1) // 4 +#define CRM_GET_DAQ_CLOCK_SYNCH_STATE CRM_BYTE(8) // 8 + +#define CRM_GET_DAQ_CLOCK_TIME64_LOW CRM_DWORD(1) // 4 +#define CRM_GET_DAQ_CLOCK_TIME64_HIGH CRM_DWORD(2) // 8 +#define CRM_GET_DAQ_CLOCK_SYNCH_STATE64 CRM_BYTE(12) // 12 +#else +#define CRM_GET_DAQ_CLOCK_TIME CRM_DWORD(1) // 4 +#endif + +#define DAQ_CLOCK_PAYLOAD_FMT_SLV_32 (1<<0) +#define DAQ_CLOCK_PAYLOAD_FMT_SLV_64 (2<<0) +#define DAQ_CLOCK_PAYLOAD_FMT_ID (1<<6) + +/* GET_DAQ_CLOCK_MULTICAST */ +#if XCP_PROTOCOL_LAYER_VERSION >= 0x0103 +#define CRO_GET_DAQ_CLOC_MCAST_LEN 4 +#define CRM_GET_DAQ_CLOCK_MCAST_LEN 8 + +#define CRO_GET_DAQ_CLOCK_MCAST_CLUSTER_IDENTIFIER CRO_WORD(1) +#define CRO_GET_DAQ_CLOCK_MCAST_COUNTER CRO_BYTE(4) + +#define CRM_GET_DAQ_CLOCK_MCAST_TRIGGER_INFO CRM_BYTE(2) // 2 +#define CRM_GET_DAQ_CLOCK_MCAST_PAYLOAD_FMT CRM_BYTE(3) // 3 + +#define CRM_GET_DAQ_CLOCK_MCAST_TIME CRM_DWORD(1) // 4 +#define CRM_GET_DAQ_CLOCK_MCAST_CLUSTER_IDENTIFIER CRM_WORD(4) // 8 +#define CRM_GET_DAQ_CLOCK_MCAST_COUNTER CRM_BYTE(10) // 10 +#define CRM_GET_DAQ_CLOCK_MCAST_SYNCH_STATE CRM_BYTE(11) // 11 + +#define CRM_GET_DAQ_CLOCK_MCAST_TIME64_LOW CRM_DWORD(1) // 4 +#define CRM_GET_DAQ_CLOCK_MCAST_TIME64_HIGH CRM_DWORD(2) // 8 +#define CRM_GET_DAQ_CLOCK_MCAST_CLUSTER_IDENTIFIER64 CRM_WORD(6) // 12 +#define CRM_GET_DAQ_CLOCK_MCAST_COUNTER64 CRM_BYTE(14) // 14 +#define CRM_GET_DAQ_CLOCK_MCAST_SYNCH_STATE64 CRM_BYTE(15) // 15 +#endif + +/* READ_DAQ */ +#define CRO_READ_DAQ_LEN 1 +#define CRM_READ_DAQ_LEN 8 +#define CRM_READ_DAQ_BITOFFSET CRM_BYTE(1) +#define CRM_READ_DAQ_SIZE CRM_BYTE(2) +#define CRM_READ_DAQ_EXT CRM_BYTE(3) +#define CRM_READ_DAQ_ADDR CRM_DWORD(1) + + +/* GET_DAQ_PROCESSOR_INFO */ +#define CRO_GET_DAQ_PROCESSOR_INFO_LEN 1 +#define CRM_GET_DAQ_PROCESSOR_INFO_LEN 8 +#define CRM_GET_DAQ_PROCESSOR_INFO_PROPERTIES CRM_BYTE(1) +#define CRM_GET_DAQ_PROCESSOR_INFO_MAX_DAQ CRM_WORD(1) +#define CRM_GET_DAQ_PROCESSOR_INFO_MAX_EVENT CRM_WORD(2) +#define CRM_GET_DAQ_PROCESSOR_INFO_MIN_DAQ CRM_BYTE(6) +#define CRM_GET_DAQ_PROCESSOR_INFO_DAQ_KEY_BYTE CRM_BYTE(7) + + +/* GET_DAQ_RESOLUTION_INFO */ +#define CRO_GET_DAQ_RESOLUTION_INFO_LEN 1 +#define CRM_GET_DAQ_RESOLUTION_INFO_LEN 8 +#define CRM_GET_DAQ_RESOLUTION_INFO_GRANULARITY_DAQ CRM_BYTE(1) +#define CRM_GET_DAQ_RESOLUTION_INFO_MAX_SIZE_DAQ CRM_BYTE(2) +#define CRM_GET_DAQ_RESOLUTION_INFO_GRANULARITY_STIM CRM_BYTE(3) +#define CRM_GET_DAQ_RESOLUTION_INFO_MAX_SIZE_STIM CRM_BYTE(4) +#define CRM_GET_DAQ_RESOLUTION_INFO_TIMESTAMP_MODE CRM_BYTE(5) +#define CRM_GET_DAQ_RESOLUTION_INFO_TIMESTAMP_TICKS CRM_WORD(3) +#define CRM_GET_DAQ_RESOLUTION_INFO_TIMESTAMP_TICKS_WRITE(ticks) CRM_WORD_WRITE(3, ticks) + + +/* GET_DAQ_LIST_INFO */ +#define CRO_GET_DAQ_LIST_INFO_LEN 4 +#define CRO_GET_DAQ_LIST_INFO_DAQ CRO_WORD(1) +#define CRM_GET_DAQ_LIST_INFO_LEN 6 +#define CRM_GET_DAQ_LIST_INFO_PROPERTIES CRM_BYTE(1) +#define CRM_GET_DAQ_LIST_INFO_MAX_ODT CRM_BYTE(2) +#define CRM_GET_DAQ_LIST_INFO_MAX_ODT_ENTRY CRM_BYTE(3) +#define CRM_GET_DAQ_LIST_INFO_FIXED_EVENT CRM_WORD(2) + + +/* GET_DAQ_EVENT_INFO */ +#define CRO_GET_DAQ_EVENT_INFO_LEN 4 +#define CRO_GET_DAQ_EVENT_INFO_EVENT CRO_WORD(1) +#define CRM_GET_DAQ_EVENT_INFO_LEN 7 +#define CRM_GET_DAQ_EVENT_INFO_PROPERTIES CRM_BYTE(1) +#define CRM_GET_DAQ_EVENT_INFO_MAX_DAQ_LIST CRM_BYTE(2) +#define CRM_GET_DAQ_EVENT_INFO_NAME_LENGTH CRM_BYTE(3) +#define CRM_GET_DAQ_EVENT_INFO_TIME_CYCLE CRM_BYTE(4) +#define CRM_GET_DAQ_EVENT_INFO_TIME_UNIT CRM_BYTE(5) +#define CRM_GET_DAQ_EVENT_INFO_PRIORITY CRM_BYTE(6) + + +#define DAQ_EVENT_PROPERTIES_DAQ 0x04 +#define DAQ_EVENT_PROPERTIES_STIM 0x08 +#define DAQ_EVENT_PROPERTIES_PACKED 0x10 +#define DAQ_EVENT_PROPERTIES_EVENT_CONSISTENCY 0x80 + + +/* FREE_DAQ */ +#define CRO_FREE_DAQ_LEN 1 +#define CRM_FREE_DAQ_LEN 1 + + +/* ALLOC_DAQ */ +#define CRO_ALLOC_DAQ_LEN 4 +#define CRO_ALLOC_DAQ_COUNT CRO_WORD(1) +#define CRM_ALLOC_DAQ_LEN 1 + + +/* ALLOC_ODT */ +#define _CRO_ALLOC_ODT_LEN 3 +#define _CRO_ALLOC_ODT_DAQ CRO_WORD(1) +#define _CRO_ALLOC_ODT_COUNT CRO_BYTE(1) +#define CRO_ALLOC_ODT_LEN 5 +#define CRO_ALLOC_ODT_DAQ CRO_WORD(1) +#define CRO_ALLOC_ODT_COUNT CRO_BYTE(4) +#define CRM_ALLOC_ODT_LEN 1 + + +/* ALLOC_ODT_ENTRY */ +#define CRO_ALLOC_ODT_ENTRY_LEN 6 +#define CRO_ALLOC_ODT_ENTRY_DAQ CRO_WORD(1) +#define CRO_ALLOC_ODT_ENTRY_ODT CRO_BYTE(4) +#define CRO_ALLOC_ODT_ENTRY_COUNT CRO_BYTE(5) +#define CRM_ALLOC_ODT_ENTRY_LEN 1 + + +/* PROGRAM_START */ +#define CRO_PROGRAM_START_LEN 1 +#define CRM_PROGRAM_START_LEN 7 +#define CRM_PROGRAM_COMM_MODE_PGM CRM_BYTE(2) +#define CRM_PROGRAM_MAX_CTO_PGM CRM_BYTE(3) +#define CRM_PROGRAM_MAX_BS_PGM CRM_BYTE(4) +#define CRM_PROGRAM_MIN_ST_PGM CRM_BYTE(5) +#define CRM_PROGRAM_QUEUE_SIZE_PGM CRM_BYTE(6) + + +/* PROGRAM_CLEAR */ +#define CRO_PROGRAM_CLEAR_LEN 8 +#define CRO_PROGRAM_CLEAR_MODE CRO_BYTE(1) +#define CRO_PROGRAM_CLEAR_SIZE CRO_DWORD(1) +#define CRM_PROGRAM_CLEAR_LEN 1 + + +/* PROGRAM */ +#define CRO_PROGRAM_MAX_SIZE ((uint8_t)(XCPTL_MAX_CTO_SIZE-2)) +#define CRO_PROGRAM_LEN 2 /* + CRO_PROGRAM_SIZE */ +#define CRO_PROGRAM_SIZE CRO_BYTE(1) +#define CRO_PROGRAM_DATA (&CRO_BYTE(2)) +#define CRM_PROGRAM_LEN 1 + + +/* PROGRAM RESET */ +#define CRO_PROGRAM_RESET_LEN 1 +#define CRM_PROGRAM_RESET_LEN 1 + + +/* GET_PGM_PROCESSOR_INFO*/ +#define CRO_GET_PGM_PROCESSOR_INFO_LEN 1 +#define CRM_GET_PGM_PROCESSOR_INFO_LEN 3 +#define CRM_GET_PGM_PROCESSOR_INFO_PROPERTIES CRM_BYTE(1) +#define CRM_GET_PGM_PROCESSOR_INFO_MAX_SECTOR CRM_BYTE(2) + + +/* GET_SECTOR_INFO */ +#define CRO_PROGRAM_GET_SECTOR_INFO_LEN 3 +#define CRO_PROGRAM_GET_SECTOR_INFO_MODE CRO_BYTE(1) +#define CRO_PROGRAM_GET_SECTOR_INFO_NUMBER CRO_BYTE(2) +#define CRM_PROGRAM_GET_SECTOR_INFO_LEN 8 +#define CRM_PROGRAM_GET_SECTOR_CLEAR_SEQ_NUM CRM_BYTE(1) +#define CRM_PROGRAM_GET_SECTOR_PGM_SEQ_NUM CRM_BYTE(2) +#define CRM_PROGRAM_GET_SECTOR_PGM_METHOD CRM_BYTE(3) +#define CRM_PROGRAM_GET_SECTOR_SECTOR_INFO CRM_DWORD(1) +#define CRM_PROGRAM_GET_SECTOR_SECTOR_INFO_WRITE(info) CRM_DWORD_WRITE(1, info) + + +/* PROGRAM_PREPARE */ +#define CRO_PROGRAM_PREPARE_LEN 4 +#define CRO_PROGRAM_PREPARE_SIZE CRO_WORD(1) +#define CRM_PROGRAM_PREPARE_LEN 1 + + +/* PROGRAM_FORMAT */ +#define CRO_PROGRAM_FORMAT_LEN 5 +#define CRO_PROGRAM_FORMAT_COMPRESSION_METHOD CRO_BYTE(1) +#define CRO_PROGRAM_FORMAT_ENCRYPTION_METHOD CRO_BYTE(2) +#define CRO_PROGRAM_FORMAT_PROGRAMMING_METHOD CRO_BYTE(3) +#define CRO_PROGRAM_FORMAT_ACCESS_METHOD CRO_BYTE(4) +#define CRM_PROGRAM_FORMAT_LEN 1 + + +/* PROGRAM_NEXT */ +#define CRO_PROGRAM_NEXT_MAX_SIZE ((uint8_t)(XCPTL_MAX_CTO_SIZE-2)) +#define CRO_PROGRAM_NEXT_LEN 2 /* + size */ +#define CRO_PROGRAM_NEXT_SIZE CRO_BYTE(1) +#define CRO_PROGRAM_NEXT_DATA (&CRO_BYTE(2)) +#define CRM_PROGRAM_NEXT_LEN 3 +#define CRM_PROGRAM_NEXT_ERR_SEQUENCE CRM_BYTE(1) +#define CRM_PROGRAM_NEXT_SIZE_EXPECTED_DATA CRM_BYTE(2) + + +/* PROGRAM_MAX */ +#define CRO_PROGRAM_MAX_MAX_SIZE ((uint8_t)(XCPTL_MAX_CTO_SIZE-1)) +#define CRO_PROGRAM_MAX_DATA (&CRO_BYTE(1)) +#define CRM_PROGRAM_MAX_LEN 1 + + +/* PROGRAM_VERIFY */ +#define CRO_PROGRAM_VERIFY_LEN 8 +#define CRO_PROGRAM_VERIFY_MODE CRO_BYTE(1) +#define CRO_PROGRAM_VERIFY_TYPE CRO_WORD(1) +#define CRO_PROGRAM_VERIFY_VALUE CRO_DWORD(1) +#define CRM_PROGRAM_VERIFY_LEN 1 + + +/* GET_SERVER_ID */ +/* +#define CRO_GET_SERVER_ID_LEN 6 +#define CRO_GET_SERVER_ID_SUB_CODE CRO_BYTE(1) +#define CRO_GET_SERVER_ID_X CRO_BYTE(2) +#define CRO_GET_SERVER_ID_C CRO_BYTE(3) +#define CRO_GET_SERVER_ID_P CRO_BYTE(4) +#define CRO_GET_SERVER_ID_MODE CRO_BYTE(5) +#define CRM_GET_SERVER_ID_LEN 8 +#define CRM_GET_SERVER_ID_X CRM_BYTE(1) +#define CRM_GET_SERVER_ID_C CRM_BYTE(2) +#define CRM_GET_SERVER_ID_P CRM_BYTE(3) +#define CRM_GET_SERVER_ID_CAN_ID_CMD_STIM CRM_DWORD(1) +*/ + +/* GET_DAQ_ID */ +#define CRO_GET_DAQ_ID_LEN 3 +#define CRO_GET_DAQ_ID_SUB_CODE CRO_BYTE(1) +#define CRO_GET_DAQ_ID_DAQ CRO_WORD(1) +#define CRM_GET_DAQ_ID_LEN 8 +#define CRM_GET_DAQ_ID_FIXED CRM_BYTE(1) +#define CRM_GET_DAQ_ID_ID CRM_DWORD(1) + + +/* SET_DAQ_ID */ +#define CRO_SET_DAQ_ID_LEN 8 +#define CRO_SET_DAQ_ID_SUB_CODE CRO_BYTE(1) +#define CRO_SET_DAQ_ID_DAQ CRO_WORD(1) +#define CRO_SET_DAQ_ID_ID CRO_DWORD(1) +#define CRM_SET_DAQ_ID_LEN 1 + + +/* SET_SERVER_PORT */ +#define CRO_SET_SERVER_PORT_LEN 4 +#define CRO_SET_SERVER_PORT_SUB_CODE CRO_BYTE(1) +#define CRO_SET_SERVER_PORT_PORT CRO_WORD(1) +#define CRM_SET_SERVER_PORT 1 + + +/* Level 1 commands */ +#define CRO_LEVEL_1_COMMAND_LEN 2 +#define CRO_LEVEL_1_COMMAND_CODE CRO_BYTE(1) + + +/* GET_VERSION */ +#define CRO_GET_VERSION_LEN 2 +#define CRM_GET_VERSION_LEN 6 +#define CRM_GET_VERSION_RESERVED CRM_BYTE(1) +#define CRM_GET_VERSION_PROTOCOL_VERSION_MAJOR CRM_BYTE(2) +#define CRM_GET_VERSION_PROTOCOL_VERSION_MINOR CRM_BYTE(3) +#define CRM_GET_VERSION_TRANSPORT_VERSION_MAJOR CRM_BYTE(4) +#define CRM_GET_VERSION_TRANSPORT_VERSION_MINOR CRM_BYTE(5) + + +/* GET_DAQ_LIST_PACKED_MODE */ +#define CRO_GET_DAQ_LIST_PACKED_MODE_DAQ CRM_WORD(1) +#define CRM_GET_DAQ_LIST_PACKED_MODE_LEN 8 +#define CRM_GET_DAQ_LIST_PACKED_MODE_MODE CRM_BYTE(2) + + +/* SET_DAQ_LIST_PACKED_MODE */ +#define CRO_SET_DAQ_LIST_PACKED_MODE_DAQ CRO_WORD(1) +#define CRO_SET_DAQ_LIST_PACKED_MODE_MODE CRO_BYTE(4) +#define CRO_SET_DAQ_LIST_PACKED_MODE_TIMEMODE CRO_BYTE(5) +#define CRO_SET_DAQ_LIST_PACKED_MODE_SAMPLECOUNT CRO_WORD(3) + +#define DPM_TIMESTAMP_MODE_LAST 0 +#define DPM_TIMESTAMP_MODE_FIRST 1 + + +/* TIME SYNCHRONIZATION PROPERTIES*/ +#define CRO_TIME_SYNCH_PROPERTIES_LEN 6 +#define CRO_TIME_SYNCH_PROPERTIES_SET_PROPERTIES CRO_BYTE(1) +#define CRO_TIME_SYNCH_PROPERTIES_GET_PROPERTIES_REQUEST CRO_BYTE(2) +#define CRO_TIME_SYNCH_PROPERTIES_CLUSTER_ID CRO_WORD(2) + +/* CRO_TIME_SYNCH_PROPERTIES_SET_PROPERTIES: */ +#define TIME_SYNCH_SET_PROPERTIES_RESPONSE_FMT (3 << 0) +#define TIME_SYNCH_SET_PROPERTIES_TIME_SYNCH_BRIDGE (3 << 2) +#define TIME_SYNCH_SET_PROPERTIES_CLUSTER_ID (1 << 4) + +#define TIME_SYNCH_RESPONSE_FMT_LEGACY 0 +#define TIME_SYNCH_RESPONSE_FMT_TRIGGER_SUBSET 1 +#define TIME_SYNCH_RESPONSE_FMT_TRIGGER_ALL 2 + +/* CRO_TIME_SYNCH_PROPERTIES_GET_PROPERTIES_REQUEST: */ +#define TIME_SYNCH_GET_PROPERTIES_GET_CLK_INFO (1 << 0) + + +#define CRM_TIME_SYNCH_PROPERTIES_LEN 8 +#define CRM_TIME_SYNCH_PROPERTIES_SERVER_CONFIG CRM_BYTE(1) +#define CRM_TIME_SYNCH_PROPERTIES_OBSERVABLE_CLOCKS CRM_BYTE(2) +#define CRM_TIME_SYNCH_PROPERTIES_SYNCH_STATE CRM_BYTE(3) +#define CRM_TIME_SYNCH_PROPERTIES_CLOCK_INFO CRM_BYTE(4) +#define CRM_TIME_SYNCH_PROPERTIES_RESERVED CRM_BYTE(5) +#define CRM_TIME_SYNCH_PROPERTIES_CLUSTER_ID CRM_WORD(3) + +/* CRM_TIME_SYNCH_PROPERTIES_SERVER_CONFIG: */ +#define SERVER_CONFIG_RESPONSE_FMT_LEGACY (0) +#define SERVER_CONFIG_RESPONSE_FMT_ADVANCED (2) +#define SERVER_CONFIG_DAQ_TS_ECU (1 << 2) +#define SERVER_CONFIG_DAQ_TS_SERVER (0 << 2) +#define SERVER_CONFIG_TIME_SYNCH_BRIDGE_NONE (0 << 3) + +/* CRM_TIME_SYNCH_PROPERTIES_OBSERVABLE_CLOCKS: */ +#define LOCAL_CLOCK_FREE_RUNNING (0<<0) +#define LOCAL_CLOCK_SYNCHED (1<<0) +#define LOCAL_CLOCK_NONE (2<<0) +#define GRANDM_CLOCK_NONE (0<<2) +#define GRANDM_CLOCK_READABLE (1<<2) +#define GRANDM_CLOCK_EVENT (2<<2) +#define ECU_CLOCK_NONE (0<<4) +#define ECU_CLOCK_READABLE (1<<4) +#define ECU_CLOCK_EVENT (2<<4) +#define ECU_CLOCK_NOTREADABLE (3<<4) + +/* CRM_TIME_SYNCH_PROPERTIES_SYNCH_STATE: */ +#define LOCAL_CLOCK_STATE_SYNCH_IN_PROGRESS (0 << 0) +#define LOCAL_CLOCK_STATE_SYNCH (1 << 0) +#define LOCAL_CLOCK_STATE_SYNT_IN_PROGRESS (2 << 0) +#define LOCAL_CLOCK_STATE_SYNT (3 << 0) +#define LOCAL_CLOCK_STATE_FREE_RUNNING (7 << 0) +#define GRANDM_CLOCK_STATE_SYNCH_IN_PROGRESS (0 << 3) +#define GRANDM_CLOCK_STATE_SYNCH (1 << 3) + + +/* CRM_TIME_SYNCH_PROPERTIES_CLOCK_INFO: */ +#define CLOCK_INFO_SERVER (1<<0) +#define CLOCK_INFO_GRANDM (1<<1) +#define CLOCK_INFO_RELATION (1<<2) +#define CLOCK_INFO_ECU (1<<3) +#define CLOCK_INFO_ECU_GRANDM (1<<4) + +/* TRIGGER_INITIATOR: + 0 = HW trigger, i.e.Vector Syncline + 1 = Event derived from XCP - independent time synchronization event - e.g.globally synchronized pulse per second signal + 2 = GET_DAQ_CLOCK_MULTICAST + 3 = GET_DAQ_CLOCK_MULTICAST via Time Sync Bridge + 4 = State change in syntonization / synchronization to grandmaster clock(either established or lost, additional information is provided by the SYNCH_STATE field - see Table 236) + 5 = Leap second occurred on grandmaster clock + 6 = release of ECU reset +*/ +#define TRIG_INITIATOR_SYNCH_LINE 0UL +#define TRIG_INITIATOR_XCP_INDEPENDENT 1UL +#define TRIG_INITIATOR_MULTICAST 2UL +#define TRIG_INITIATOR_MULTICAST_TS_BRIDGE 3UL +#define TRIG_INITIATOR_SYNCH_STATE_CHANGE 4UL +#define TRIG_INITIATOR_LEAP_SECOND 5UL +#define TRIG_INITIATOR_ECU_RESET_RELEASE 6UL +#define TRIG_INITIATOR_RESERVED 7UL + + +#define TIME_OF_TS_SAMPLING_PROTOCOL_PROCESSOR 0UL +#define TIME_OF_TS_SAMPLING_LOW_JITTER 1UL +#define TIME_OF_TS_SAMPLING_PHY_TRANSMISSION 2UL +#define TIME_OF_TS_SAMPLING_PHY_RECEPTION 3UL + + +/****************************************************************************/ +/* XCP clock information */ +/****************************************************************************/ + +#define XCP_STRATUM_LEVEL_UNKNOWN 255 // Unknown +#define XCP_STRATUM_LEVEL_RTC 3 // Realtime Clock +#define XCP_STRATUM_LEVEL_GPS 0 // GPS Clock + +#define XCP_EPOCH_TAI 0 // Atomic monotonic time since 1.1.1970 (TAI) +#define XCP_EPOCH_UTC 1 // Universal Coordinated Time (with leap seconds) since 1.1.1970 (UTC) +#define XCP_EPOCH_ARB 2 // Arbitrary (unknown) + +#pragma pack(push, 1) + +typedef struct { + uint8_t UUID[8]; + uint16_t timestampTicks; + uint8_t timestampUnit; + uint8_t stratumLevel; + uint8_t nativeTimestampSize; + uint8_t fill[3]; // for alignment (8 byte) of structure + uint64_t valueBeforeWrapAround; +} T_CLOCK_INFO; + + +#ifdef XCP_ENABLE_PTP + +typedef struct { + uint8_t UUID[8]; + uint16_t timestampTicks; + uint8_t timestampUnit; + uint8_t stratumLevel; + uint8_t nativeTimestampSize; + uint8_t epochOfGrandmaster; + uint8_t fill[2]; // for alignment (8 byte) of structure + uint64_t valueBeforeWrapAround; +} T_CLOCK_INFO_GRANDMASTER; + +typedef struct { + uint64_t timestampOrigin; + uint64_t timestampLocal; +} T_CLOCK_INFO_RELATION; + +#endif + +#pragma pack(pop) + +/***************************************************************************/ +/* XCP Transport Layer Commands and Responces, Type Definition */ +/***************************************************************************/ + + +/* Transport Layer commands */ +#define CC_TL_GET_SERVER_ID 0xFF +#define CC_TL_GET_SERVER_ID_EXTENDED 0xFD +#define CC_TL_SET_SERVER_IP 0xFC +#define CC_TL_GET_DAQ_CLOCK_MULTICAST 0xFA +#define CRO_TL_SUBCOMMAND CRO_BYTE(1) + + +/* GET_SERVER_ID and GET_SERVER_ID_EXTENDED */ +#define CRO_TL_GET_SERVER_ID_LEN 21 +#define CRO_TL_GET_SERVER_ID_PORT CRO_WORD(1) +#define CRO_TL_GET_SERVER_ID_ADDR(n) CRO_BYTE(4+n) +#define CRO_TL_GET_SERVER_ID_MODE CRO_BYTE(20) + +/* GET_SERVER_ID */ +/* +#define CRM_TL_GET_SERVER_ID_LEN(n) (24+1+(n)) +#define CRM_TL_GET_SERVER_ID_ADDR(n) CRM_BYTE(n) +#define CRM_TL_GET_SERVER_ID_PORT CRM_WORD(8) +#define CRM_TL_GET_SERVER_ID_STATUS CRM_BYTE(18) +#define CRM_TL_GET_SERVER_ID_RESOURCE CRM_BYTE(19) +#define CRM_TL_GET_SERVER_ID_ID_LEN CRM_BYTE(20) +#define CRM_TL_GET_SERVER_ID_ID CRM_BYTE(21) +#define CRM_TL_GET_SERVER_ID_MAX_LEN 128 +*/ + +#define GET_SERVER_ID_STATUS_PROTOCOL_TCP 0 +#define GET_SERVER_ID_STATUS_PROTOCOL_UDP 1 +#define GET_SERVER_ID_STATUS_PROTOCOL_TCP_UDP 2 +#define GET_SERVER_ID_STATUS_IP_VERSION_IPV4 (0) +#define GET_SERVER_ID_STATUS_SLV_AVAILABILITY_BUSY (1<<3) +#define GET_SERVER_ID_STATUS_SLV_ID_EXT_SUPPORTED (1<<4) + +/* GET_SERVER_ID_EXT */ +#define CRM_TL_GET_SERVER_ID_LEN(n) (24+1+(n)) +#define CRM_TL_GET_SERVER_ID_ADDR(n) CRM_BYTE(2+n) +#define CRM_TL_GET_SERVER_ID_PORT CRM_WORD(18) +#define CRM_TL_GET_SERVER_ID_STATUS CRM_BYTE(20) +#define CRM_TL_GET_SERVER_ID_RESOURCE CRM_BYTE(21) +#define CRM_TL_GET_SERVER_ID_ID_LEN *(uint32_t*)&(CRM_BYTE(22)) // this is a DWORD on unaligned offset +#define CRM_TL_GET_SERVER_ID_ID CRM_BYTE(26) +#define CRM_TL_GET_SERVER_ID_MAC(n) CRM_BYTE(26+n) /*+CRM_TL_GET_SERVER_ID_ID_LEN*/ + +#define CRM_TL_GET_SERVER_ID_MAX_LEN (XCPTL_MAX_CTO_SIZE-(26+6)) + +/* GET_SERVER_ID_EXTENDED */ +#define TL_SLV_DETECT_STATUS_SLV_ID_EXT_RADAR_DATA (1<<0) +#define TL_SLV_DETECT_STATUS_SLV_ID_EXT_XCP_ON_PCIE (1<<1) + + diff --git a/A2lTestDlg/A2lTestDlg/xcpEthTl.h b/A2lTestDlg/A2lTestDlg/xcpEthTl.h new file mode 100644 index 0000000..b9dee19 --- /dev/null +++ b/A2lTestDlg/A2lTestDlg/xcpEthTl.h @@ -0,0 +1,27 @@ +#pragma once + +/* xcpEthTl.h */ + +/* Copyright(c) Vector Informatik GmbH.All rights reserved. + Licensed under the MIT license.See LICENSE file in the project root for details. */ + +/* ETH transport Layer functions called by application */ +extern BOOL XcpEthTlInit(const uint8_t* addr, uint16_t port, BOOL useTCP, uint16_t segmentSize, BOOL blockingRx); // Start transport layer + +// Test mode +#ifdef XCPTL_ENABLE_SELF_TEST +extern void XcpEthTlCreateA2lDescription(); +extern void XcpEthTlCreateXcpEvents(); +extern uint64_t XcpEthTlGetBytesWritten(); // Get the number of bytes send +#endif + + +/* ETH transport Layer functions called by XCPlite.c */ +extern void XcpEthTlSendMulticastCrm(const uint8_t* data, uint16_t n, const uint8_t* addr, uint16_t port); // Send multicast command response +#ifdef XCPTL_ENABLE_MULTICAST +extern void XcpEthTlSetClusterId(uint16_t clusterId); // Set cluster id for GET_DAQ_CLOCK_MULTICAST reception +#endif + +extern void XcpEthTlGetInfo(BOOL* isTCP, uint8_t* mac, uint8_t* addr, uint16_t* port); + + diff --git a/A2lTestDlg/A2lTestDlg/xcpLite.h b/A2lTestDlg/A2lTestDlg/xcpLite.h new file mode 100644 index 0000000..bf3229e --- /dev/null +++ b/A2lTestDlg/A2lTestDlg/xcpLite.h @@ -0,0 +1,188 @@ +#pragma once +/* xcpLite.h */ + +/* Copyright(c) Vector Informatik GmbH.All rights reserved. + Licensed under the MIT license.See LICENSE file in the project root for details. */ + + +#ifdef __XCPTL_CFG_H__ +#error "Include dependency error!" +#endif +#ifdef __XCP_CFG_H__ +#error "Include dependency error!" +#endif + + +// Transport layer type +// The protocol layer implementation has some dependencies on the transport layer type +// Some XCP commands are only supported on Ethernet and can not be compiled with MAX_CTO == 8 +#define XCP_TRANSPORT_LAYER_ETH 1 +#define XCP_TRANSPORT_LAYER_CAN 0 + +#include "xcptl_cfg.h" // Transport layer configuration + +// Transport layer definitions and configuration +#if XCP_TRANSPORT_LAYER_TYPE==XCP_TRANSPORT_LAYER_ETH +#include "xcpTl.h" +#include "xcpEthTl.h" // Ethernet transport layer specific functions +#elif XCP_TRANSPORT_LAYER_TYPE==XCP_TRANSPORT_LAYER_CAN +#include "xcptl.h" +#include "xcpcantl.h" +#else +#error "Define XCP_TRANSPORT_LAYER_ETH or XCP_TRANSPORT_LAYER_CAN" +#endif + +// Protocol layer definitions and configuration +#include "xcp_cfg.h" // Protocol layer configuration +#include "xcp.h" // XCP protocol defines + + + +/****************************************************************************/ +/* DAQ event information */ +/****************************************************************************/ + +#ifdef XCP_ENABLE_DAQ_EVENT_LIST + +#define XCP_MAX_EVENT_NAME 8 + +typedef struct { + char shortName[XCP_MAX_EVENT_NAME+1]; // A2L XCP IF_DATA short event name, long name not supported + uint32_t size; // ext event size + uint8_t timeUnit; // timeCycle unit, 1ns=0, 10ns=1, 100ns=2, 1us=3, ..., 1ms=6, ... + uint8_t timeCycle; // cycletime in units, 0 = sporadic or unknown + uint16_t sampleCount; // packed event sample count + uint16_t daqList; // associated DAQ list + uint8_t priority; // priority 0 = queued, 1 = pushing, 2 = realtime +#ifdef XCP_ENABLE_MULTITHREAD_EVENTS + MUTEX mutex; +#endif +#ifdef XCP_ENABLE_TEST_CHECKS + uint64_t time; // last event time stamp +#endif +} tXcpEvent; + +#endif + + +/****************************************************************************/ +/* Protocol layer interface */ +/****************************************************************************/ + +/* Initialization for the XCP Protocol Layer */ +extern void XcpInit(void); +extern void XcpStart(void); +extern void XcpDisconnect(); +extern void XcpReset(); + +/* Trigger a XCP data acquisition or stimulation event */ +extern void XcpEvent(uint16_t event); +extern void XcpEventExt(uint16_t event, uint8_t* base); +extern void XcpEventAt(uint16_t event, uint64_t clock); + +/* XCP command processor */ +extern void XcpCommand( const uint32_t* pCommand, uint16_t len ); + +/* Send an XCP event message */ +extern void XcpSendEvent(uint8_t evc, const uint8_t* d, uint8_t l); + +/* Check status */ +extern BOOL XcpIsStarted(); +extern BOOL XcpIsConnected(); +extern BOOL XcpIsDaqRunning(); +extern BOOL XcpIsDaqEventRunning(uint16_t event); +extern uint64_t XcpGetDaqStartTime(); +extern uint32_t XcpGetDaqOverflowCount(); + +/* Time synchronisation */ +#ifdef XCP_ENABLE_DAQ_CLOCK_MULTICAST +extern uint16_t XcpGetClusterId(); +#endif + +// Event list +#ifdef XCP_ENABLE_DAQ_EVENT_LIST + +#define XCP_INVALID_EVENT 0xFFFF + +// Clear event list +extern void XcpClearEventList(); +// Add a measurement event to event list, return event number (0..MAX_EVENT-1) +extern uint16_t XcpCreateEvent(const char* name, uint32_t cycleTimeNs /* ns */, uint8_t priority /* 0-normal, >=1 realtime*/, uint16_t sampleCount, uint32_t size); +// Get event list +extern tXcpEvent* XcpGetEventList(uint16_t* eventCount); +// Lookup event +extern tXcpEvent* XcpGetEvent(uint16_t event); + +#endif + + +/****************************************************************************/ +/* Protocol layer external dependencies */ +/****************************************************************************/ + +// All callback functions supplied by the application +// Must be thread save + +/* Callbacks on connect, measurement prepare, start and stop */ +extern BOOL ApplXcpConnect(); +#if XCP_PROTOCOL_LAYER_VERSION >= 0x0104 +extern BOOL ApplXcpPrepareDaq(); +#endif +extern BOOL ApplXcpStartDaq(); +extern void ApplXcpStopDaq(); + +/* Address conversions from A2L address to pointer and vice versa */ +/* Note that xcpAddrExt 0x01 and 0xFF are reserved for special use cases (0x01 if XCP_ENABLE_DYN_ADDRESSING, 0xFF if XCP_ENABLE_IDT_A2L_UPLOAD) */ +extern uint8_t* ApplXcpGetPointer(uint8_t xcpAddrExt, uint32_t xcpAddr); /* Create a pointer (uint8_t*) from xcpAddrExt and xcpAddr, returns NULL if no access */ +extern uint32_t ApplXcpGetAddr(uint8_t* p); // Calculate the xcpAddr address from a pointer +extern uint8_t *ApplXcpGetBaseAddr(); // Get the base address for DAQ data access */ +/* + Note 1: + For DAQ performance and memory optimization: + XCPlite DAQ tables do not store address extensions and do not use ApplXcpGetPointer(), addr is stored as 32 Bit value and access is hardcoded by *(baseAddr+xcpAddr) + All accesible DAQ data is within a 4GByte range starting at ApplXcpGetBaseAddr() + Address extensions to increase the addressable range are not supported yet + Attempting to setup an ODT entry with address extension != 0 gives a CRC_ACCESS_DENIED error message + + Note 2: + ApplXcpGetPointer may do address transformations according to active calibration page + When measuring calibration variables inswitch +*/ + + +/* Switch calibration pages */ +#ifdef XCP_ENABLE_CAL_PAGE +extern uint8_t ApplXcpGetCalPage(uint8_t segment, uint8_t mode); +extern uint8_t ApplXcpSetCalPage(uint8_t segment, uint8_t page, uint8_t mode); +#endif + +/* DAQ clock */ +extern uint64_t ApplXcpGetClock64(); + +#define CLOCK_STATE_SYNCH_IN_PROGRESS (0) +#define CLOCK_STATE_SYNCH (1) +#define CLOCK_STATE_FREE_RUNNING (7) +#define CLOCK_STATE_GRANDMASTER_STATE_SYNCH (1 << 3) +extern uint8_t ApplXcpGetClockState(); + +#ifdef XCP_ENABLE_PTP +#define CLOCK_STRATUM_LEVEL_UNKNOWN 255 +#define CLOCK_STRATUM_LEVEL_ARB 16 // unsychronized +#define CLOCK_STRATUM_LEVEL_UTC 0 // Atomic reference clock +#define CLOCK_EPOCH_TAI 0 // Atomic monotonic time since 1.1.1970 (TAI) +#define CLOCK_EPOCH_UTC 1 // Universal Coordinated Time (with leap seconds) since 1.1.1970 (UTC) +#define CLOCK_EPOCH_ARB 2 // Arbitrary (epoch unknown) +extern BOOL ApplXcpGetClockInfoGrandmaster(uint8_t* uuid, uint8_t* epoch, uint8_t* stratum); +#endif + +/* Get info for GET_ID command (pointer to and length of data) */ +/* Supports IDT_ASCII, IDT_ASAM_NAME, IDT_ASAM_PATH, IDT_ASAM_URL, IDT_ASAM_EPK and IDT_ASAM_UPLOAD */ +/* Returns 0 if not available */ +extern uint32_t ApplXcpGetId(uint8_t id, uint8_t* buf, uint32_t bufLen); + +/* Read a chunk (offset,size) of the A2L file for upload */ +/* Return FALSE if out of bounds */ +#ifdef XCP_ENABLE_IDT_A2L_UPLOAD // Enable A2L content upload to host (IDT_ASAM_UPLOAD) +extern BOOL ApplXcpReadA2L(uint8_t size, uint32_t offset, uint8_t* data); +#endif + diff --git a/A2lTestDlg/A2lTestDlg/xcpTl.h b/A2lTestDlg/A2lTestDlg/xcpTl.h new file mode 100644 index 0000000..058083d --- /dev/null +++ b/A2lTestDlg/A2lTestDlg/xcpTl.h @@ -0,0 +1,32 @@ +#pragma once +/* xcpTl.h */ + +/* Copyright(c) Vector Informatik GmbH.All rights reserved. + Licensed under the MIT license.See LICENSE file in the project root for details. */ + +#define XCPTL_TIMEOUT_INFINITE 0xFFFFFFFF // Infinite timeout (blocking mode) for XcpTlHandleCommands, XcpTlWaitForTransmitData + + +/* Transport Layer functions called by XCPlite.c */ +extern BOOL XcpTlHandleCommands(uint32_t timeout_ms); // Handle all incoming XCP commands, (wait for at least timeout_ms) +extern void XcpTlSendCrm(const uint8_t* data, uint16_t n); // Send or queue (depending on XCPTL_QUEUED_CRM) a command response +extern uint8_t* XcpTlGetTransmitBuffer(void** par, uint16_t size); // Get a buffer for a message with size +extern void XcpTlCommitTransmitBuffer(void* par, BOOL flush); // Commit a buffer (by handle returned from XcpTlGetTransmitBuffer) +extern void XcpTlFlushTransmitBuffer(); // Finalize the current transmit packet (ETH only) +extern void XcpTlWaitForTransmitQueueEmpty(); // Wait (sleep) until transmit queue is empty + +/* Generic transport Layer functions called by application */ +/* All other application functions functions declared in xcpCanTl.h or xcpEthTl.h */ +extern int32_t XcpTlHandleTransmitQueue(); // Send all outgoing packets in the transmit queue +extern BOOL XcpTlWaitForTransmitData(uint32_t timeout_ms); // Wait for at least timeout_ms, until packets are pending in the transmit queue +extern void XcpTlShutdown(); + +// Get last error code +#define XCPTL_OK 0 +#define XCPTL_ERROR_WOULD_BLOCK 1 +#define XCPTL_ERROR_SEND_FAILED 2 +#define XCPTL_ERROR_INVALID_MASTER 3 +extern int32_t XcpTlGetLastError(); + +// Get transmit queue level +extern int32_t XcpTlGetTransmitQueueLevel(); diff --git a/A2lTestDlg/A2lTestDlg/xcp_cfg.h b/A2lTestDlg/A2lTestDlg/xcp_cfg.h new file mode 100644 index 0000000..7b4a0ce --- /dev/null +++ b/A2lTestDlg/A2lTestDlg/xcp_cfg.h @@ -0,0 +1,104 @@ +#pragma once + +/*---------------------------------------------------------------------------- +| File: +| xcp_cfg.h +| +| Description: +| User configuration file for XCP protocol layer parameters +| +| Code released into public domain, no attribution required +| + ----------------------------------------------------------------------------*/ + + + +/*----------------------------------------------------------------------------*/ +/* Version */ + +// Driver version (GET_COMM_MODE_INFO) +#define XCP_DRIVER_VERSION 0x01 + +// Protocol layer version +// #define XCP_PROTOCOL_LAYER_VERSION 0x0101 +#define XCP_PROTOCOL_LAYER_VERSION 0x0103 // GET_DAQ_CLOCK_MULTICAST, GET_TIME_CORRELATION_PROPERTIES +// #define XCP_PROTOCOL_LAYER_VERSION 0x0104 // PACKED_MODE, CC_START_STOP_SYNCH prepare + + + + + +/*----------------------------------------------------------------------------*/ +/* Driver features */ + +#define XCP_TRANSPORT_LAYER_TYPE XCP_TRANSPORT_LAYER_ETH // Enable ethernet specific commands + +#if OPTION_ENABLE_XCP_CLASS + #define XCP_ENABLE_DYN_ADDRESSING // Enable addr_ext=1 indicating relative addr format (event<<16)|offset +#endif + +/*----------------------------------------------------------------------------*/ +/* Protocol features */ + +//#define XCP_ENABLE_INTERLEAVED +//#define XCP_INTERLEAVED_QUEUE_SIZE 16 + +#define XCP_ENABLE_CHECKSUM // Enable checksum calculation command + +#define XCP_ENABLE_CAL_PAGE // Enable cal page switch + + +/*----------------------------------------------------------------------------*/ +/* GET_ID command */ + +#if OPTION_ENABLE_A2L_GEN +#define XCP_ENABLE_IDT_A2L_UPLOAD // Upload A2L via XCP UPLOAD +#endif + +/*----------------------------------------------------------------------------*/ +/* DAQ features and parameters */ + +// #define XCP_ENABLE_DAQ_EVENT_INFO // Enable XCP_GET_EVENT_INFO, if this is enabled, A2L file event information will be ignored +#define XCP_ENABLE_DAQ_EVENT_LIST // Enable event list +#define XCP_MAX_EVENT 256 // Maximum number of events, size of event table +#define XCP_ENABLE_MULTITHREAD_EVENTS // Make XcpEvent thread safe also for same event from different thread +// #define XCP_ENABLE_PACKED_MODE // Enable packed mode emulation + +#define XCP_DAQ_MEM_SIZE (5*100) // Amount of memory for DAQ tables, each ODT entry (e.g. measurement variable) needs 5 bytes + +// CLOCK_USE_UTC_TIME_NS +// Settings for 64 bit ns since 1.1.1970 TAI clock (CLOCK_USE_UTC_TIME_NS) + +#define XCP_DAQ_CLOCK_64BIT // Use 64 Bit time stamps in GET_DAQ_CLOCK +#define XCP_DAQ_CLOCK_UIID { 0xdc,0xa6,0x32,0xFF,0xFE,0x7e,0x66,0xdc } + +// Server DAQ clock info (mandatory) +#define XCP_TIMESTAMP_UNIT DAQ_TIMESTAMP_UNIT_1NS // unit DAQ_TIMESTAMP_UNIT_xxx +#define XCP_TIMESTAMP_TICKS 1 // ticks per unit +#define XCP_TIMESTAMP_EPOCH XCP_EPOCH_TAI + +// Grandmaster clock (optional, use XcpSetGrandmasterClockInfo, implement ApplXcpGetClockInfoGrandmaster) +// #define XCP_ENABLE_PTP + + +//#define XCP_ENABLE_DAQ_CLOCK_MULTICAST // Enable GET_DAQ_CLOCK_MULTICAST +#ifdef XCP_ENABLE_DAQ_CLOCK_MULTICAST + // XCP default cluster id (multicast addr 239,255,0,1, group 127,0,1 (mac 01-00-5E-7F-00-01) +#define XCP_MULTICAST_CLUSTER_ID 1 +#endif + +#define XCP_TIMESTAMP_TICKS_S CLOCK_TICKS_PER_S // ticks per s (for debug output) + + +//------------------------------------------------------------------------------- +// Debug + +// Debug console prints +#if OPTION_ENABLE_DBG_PRINTS +#define XCP_ENABLE_DEBUG_PRINTS +#define XCP_DBG_LEVEL XCP_DEBUG_LEVEL +#endif + +// Enable extended error checks, performance penalty !!! +#define XCP_ENABLE_TEST_CHECKS + diff --git a/A2lTestDlg/A2lTestDlg/xcptl_cfg.h b/A2lTestDlg/A2lTestDlg/xcptl_cfg.h new file mode 100644 index 0000000..c990486 --- /dev/null +++ b/A2lTestDlg/A2lTestDlg/xcptl_cfg.h @@ -0,0 +1,70 @@ +#pragma once + +/*---------------------------------------------------------------------------- +| File: +| xcptl_cfg.h +| +| Description: +| User configuration file for XCP transport layer parameters +| +| Code released into public domain, no attribution required +| + ----------------------------------------------------------------------------*/ + +// Transport layer +#define XCP_TRANSPORT_LAYER_TYPE XCP_TRANSPORT_LAYER_ETH +#define XCP_TRANSPORT_LAYER_VERSION 0x0104 + +// TCP or/and UDP option enabled +#define XCPTL_ENABLE_TCP +#define XCPTL_ENABLE_UDP + +// Transmit mode +#define XCPTL_QUEUED_CRM // Use transmit queue for command responces +/* +Benefits: +- Unique transport layers message counters for CRM and DTO (CANape default transport layer option is "include command response") +- Transmit queue empty before DAQ is stopped (end of measurement consistent for all event channels) +- socketSendTo needs not to be thread safe for a socket +Drawbacks: +- Increased latency for GET_DAQ_CLOCK response during DAQ running, which impacts time sync quality if XCP 1.3 trigger initiator "sampled on reception" is not supported +- Impact on DAQ performance because transport layer packet is flushed for command responses +- DAQ queue overflow can happen on command responses, CANape aborts when response to GET_DAQ_CLOCK is missing +*/ + +// Transport layer header size +// This is fixed, no other options supported +#define XCPTL_TRANSPORT_LAYER_HEADER_SIZE 4 + +// TL segment size and DTO size +// Segment size is the maximum data buffer size given to send/sendTo, for UDP it is the MTU +#define XCPTL_MAX_SEGMENT_SIZE (OPTION_MTU-20-8) // UDP MTU (MTU - IP-header - UDP-header) +#define XCPTL_MAX_DTO_SIZE (XCPTL_MAX_SEGMENT_SIZE-XCPTL_TRANSPORT_LAYER_HEADER_SIZE) // Normal ETH frame MTU - IPhdr - UDPhdr- XCPhdr, DTO size must be mod 4 +#define XCPTL_PACKET_ALIGNMENT 4 // Packet alignment for multiple XCP transport layer packets in a XCP transport layer message + +// CTO size +// Maximum size of a XCP command +#define XCPTL_MAX_CTO_SIZE 252 // must be mod 4 + +// DAQ transmit queue +// Transmit queue size in segments, should at least be able to hold all data produced until the next call to HandleTransmitQueue +#define XCPTL_QUEUE_SIZE 64 // array[XCPTL_QUEUE_SIZE] of tXcpMessageBuffer (XCPTL_MAX_SEGMENT_SIZE+4) +// Maximum queue trigger event rate +#define XCPTL_QUEUE_TRANSMIT_CYCLE_TIME (1*CLOCK_TICKS_PER_MS) +// Flush cycle +#define XCPTL_QUEUE_FLUSH_CYCLE_MS 50 // Send a DTO packet at least every x ms, XCPTL_TIMEOUT_INFINITE to turn off + +// Transport layer header size +// This is fixed, no other options supported +#define XCPTL_TRANSPORT_LAYER_HEADER_SIZE 4 + +// Multicast (GET_DAQ_CLOCK_MULTICAST) +// Use multicast time synchronisation to improve synchronisation of multiple XCP slaves +// This is standard in XCP V1.3, but it needs to create an additional thread and socket for multicast reception +// Has no benefit with PTP time synchronized slave and is just unnesserary effort +// CANape expects this by default -> adjust setting in device/protocol/event/TIME_CORRELATION_GETDAQCLOCK from "multicast" to "extended response" to switch it of +//#define XCPTL_ENABLE_MULTICAST +#ifdef XCPTL_ENABLE_MULTICAST + #define XCPTL_MULTICAST_PORT 5557 +#endif +