Skip to main content

Migration Guide from S810-MP-SDK2N (CAN/CAN FD)

This page is a migration guide for replacing existing applications created with S810-MP-SDK2N to S810-MX-ADL2N.
Target protocol is CAN/CAN FD only (LIN is out of scope).

Migration Overview

The following five points affect implementation when migrating from SDK2N to ADL2N.

  1. API naming scheme changes (MPCAN* -> MPX* / MPXCAN*)
  2. Device selection model changes (MPCANOpen single target -> MPXOpen enumeration + Serial selection)
  3. CAN parameter setting unified (Simple/Detail -> StMPXCANParam)
  4. Data structure extension (8-byte CAN assumption -> 64-byte CAN FD support)
  5. Log acquisition redesign (MPXSetGetLogMode + MPXGetLog / MPXCANGetLogEx)

Preconditions to Confirm First

  • Old DLL: MPCANCtrl.DLL / MPCANCtrl_x64.DLL
  • New DLL: MPXCtrlFree.DLL / MPXCtrlFree_x64.DLL
  • Some return code (ER) values changed, so numeric comparison code must be updated

API Specification Differences (Old -> New)

Common APIs (Replacement from old CAN-only APIs)

Old SDK2N (Signature)New ADL2N (Signature)Compatibility Impact
ER MPCANGetVersion(StMPCANVersion* Version)ER MPXGetAPIVersion(StMPXAPIVersion* Version)Structure type name changed
ER MPCANOpen(long* Serial)ER MPXOpen(StMPXDeviceInfo* Devices, unsigned char Num, unsigned char* Count)Arguments significantly changed (enumeration model)
ER MPCANClose(void)ER MPXClose(void)Name changed
ER MPCANSetLED(unsigned char Red, unsigned char Green, unsigned char GreenBlink)ER MPXSetLED(unsigned long Serial, unsigned char LEDRed, unsigned char LEDGreen, unsigned char LEDGreenBlink, unsigned char LEDYellow, unsigned char LEDYellowBlink)Serial added, more arguments
ER MPCANGetStatus(unsigned short* Status)ER MPXGetStatus(unsigned long Serial, unsigned short* StatusCh1, unsigned short* StatusCh2)Serial added, per-channel status
ER MPCANMonitorStart(void)ER MPXMonitorStart(unsigned long Serial, unsigned char SyncMode)Serial + SyncMode added
ER MPCANMonitorStop(unsigned long* mSec, unsigned short* uSec)ER MPXMonitorStop(unsigned long Serial, unsigned long* mSec, unsigned short* uSec)Serial added
ER MPCANGetTimeStamp(unsigned long* mSec, unsigned short* uSec)ER MPXGetTimeStamp(unsigned long Serial, unsigned long* mSec, unsigned short* uSec)Serial added
ER MPCANGetLog(StMPCANLog** LogPointer, unsigned long* Count, unsigned char* BufferOver)ER MPXGetLog(unsigned long Serial, unsigned char InnerCh, StMPXLog** Log, unsigned short* Count, unsigned char* BufferOver)Serial/InnerCh added, Count type changed
-ER MPXSetGetLogMode(unsigned long Serial, unsigned char InnerCh, unsigned char Mode)Must be added in migration
-ER MPXSetLogCallBack(...)Use when operating callback mode

CAN/CAN FD APIs

Old SDK2N (Signature)New ADL2N (Signature)Difference
ER MPCANSetParamSimple(unsigned char Mode, unsigned char RecvRemote, unsigned char Baudrate, unsigned char SamplePoint)ER MPXCANSetParam(unsigned long Serial, unsigned char InnerCh, StMPXCANParam* Param)Simple removed, unified into structure
ER MPCANSetParamDetail(unsigned char Mode, unsigned char RecvRemote, unsigned short Brg, unsigned char TSeg1, unsigned char TSeg2, unsigned char Sjw, unsigned char Clock)ER MPXCANSetParam(unsigned long Serial, unsigned char InnerCh, StMPXCANParam* Param)Detail removed, unified into structure
ER MPCANGetLogEx(StMPCANLog* Log, unsigned long* Num, unsigned long* Count, unsigned char* BufferOver)ER MPXCANGetLogEx(unsigned long Serial, unsigned char InnerCh, StMPXCANLog* Log, unsigned short Num, unsigned short* Count, unsigned char* BufferOver)Serial/InnerCh added, Num/Count type changed
ER MPCANSetSlot(StMPCANSlot* Slot, unsigned char Num)ER MPXCANSetSlot(unsigned long Serial, unsigned char InnerCh, StMPXCANSlot* Slots, unsigned char SlotCount)Slot structure expanded
ER MPCANChangeSlotData(unsigned char SlotNo, unsigned char Ena, unsigned char* Data)ER MPXCANChangeSlot(unsigned long Serial, unsigned char InnerCh, unsigned char SlotNo, unsigned char SlotEnabled, unsigned char ReqInfo, StMPXCANFrame* Frame)Scope changed from data-only to request type + full frame
ER MPCANSendSlot(unsigned char SlotNo)ER MPXCANSendSlot(unsigned long Serial, unsigned char InnerCh, unsigned char SlotNo)Serial/InnerCh added
ER MPCANSendDirect(StMPCANFrame Frame) / ER MPCANSendDirectEx(StMPCANFrame* Frame)ER MPXCANDirectSend(unsigned long Serial, unsigned char InnerCh, StMPXCANDirect* Frame)Send info now includes Protocol/BRS

Structure-Level Migration Points

Frame Structure

  • Old: StMPCANFrame
    • Id, IdFormat, Rtr, Dlc, Data[8]
  • New: StMPXCANFrame + StMPXCANFrameType
    • ID (StMPXCANID)
    • DL (0..8,12,16,20,24,32,48,64)
    • Data[64]
    • FrameType.Option.Protocol (CAN/CAN FD)
    • FrameType.Option.BRS (for CAN FD)

Parameter Structure

SDK2N SetParamSimple/Detail settings are consolidated into StMPXCANParam in ADL2N.

Old SettingNew Field
ModeStMPXCANParam.Mode
BaudrateStMPXCANParam.ArbitrationBaudrate
SamplePointStMPXCANParam.ArbitrationSamplepoint
RecvRemoteNo direct counterpart (review behavior under new spec)
Brg/TSeg1/TSeg2/Sjw/ClockDirect value setting not supported; redesign with predefined parameters
-EnableTerminate (termination resistor)
-DataBaudrate / DataSamplepoint (CAN FD)

If you used MPCANSetParamDetail, first migrate to SetParamSimple-equivalent operation (predefined baudrate/samplepoint) for safer transition.
Exact direct porting of Brg/TSeg1/TSeg2/Sjw/Clock is not possible. Use this approach:

  1. Select the closest MPX_CAN_PARAM_ABR_* to old effective baudrate
  2. Select the closest MPX_CAN_PARAM_SP_* to old sample point
  3. Validate acceptable tolerance on real hardware

If strict bit timing match is required, contact support.

Slot Structure (StMPCANSlot -> StMPXCANSlot)

Old StMPCANSlotNew StMPXCANSlotNotes
EnabledFrameType.EnabledHierarchized
EventKindFrameType.FrameTypeHierarchized
Delay (unsigned short)msSendDelay (unsigned long)Type expanded
Cycle (unsigned short)msSendCycle (unsigned long)Type expanded
Offset (unsigned short)msSendOffset (unsigned long)Type expanded
Count (unsigned short)SendCounter (unsigned short)Name changed
Increment (unsigned char)Increment[64]Changed from bit flag to array
-SlotNoAdded (1 to 28)
-TriggerType / TriggerIDAdded (receive trigger)
-msMinTransInterval / usMinTransIntervalAdded (minimum interval)
-usSendDelay / usSendOffset / usSendCycleAdded (microsecond fields)

Slot limit in ADL2N is expanded from 24 -> 28.

EventKind (Frame Type) Value Changes

SDK2NValueADL2NValue
CAN_EVENT_PERIODIC0MPX_CAN_FRAME_TYPE_PERIODIC0
--MPX_CAN_FRAME_TYPE_PERIODIC_TRIGGER1
CAN_EVENT_EVENT1MPX_CAN_FRAME_TYPE_EVENT2
CAN_EVENT_EVENTPERIODIC2MPX_CAN_FRAME_TYPE_EVENTPERIODIC3

If old code hard-codes numeric values for EVENT=1 and EVENTPERIODIC=2, be sure to replace them with constants.
Keeping old values causes different frame-type behavior in ADL2N.

Key Points for StMPXCANFrameType / StMPXCANFrame

SDK2N set Enabled / EventKind / Frame as flat fields, while ADL2N uses nested fields.

// SDK2N
slot.Enabled = CAN_SLOT_ENA;
slot.EventKind = CAN_EVENT_PERIODIC;
slot.Frame.Id = 0x100;
slot.Frame.IdFormat = CAN_ID_STD;
slot.Frame.Rtr = CAN_RTR_DATA;
slot.Frame.Dlc = 8;

// ADL2N
slot.FrameType.Enabled = MPX_CAN_SLOT_ENABLE;
slot.FrameType.FrameType = MPX_CAN_FRAME_TYPE_PERIODIC;
slot.FrameType.Option.Protocol = MPX_CAN_PROTOCOL_CAN; // Use MPX_CAN_PROTOCOL_CANFD for CAN FD
slot.FrameType.Option.BRS = MPX_CAN_BRS_DISABLE; // Valid for CAN FD
slot.FrameType.Option.ErrorAction = MPX_CAN_ERR_BEHAVIOR_ACTIVE;

slot.Frame.ID.ID = 0x100;
slot.Frame.ID.IDE = MPX_CAN_IDE_STD;
slot.Frame.ID.RTR = MPX_CAN_RTR_DATA;
slot.Frame.DL = 8;

Increment Field Migration

Old SDK2N used 8-bit bit flags, ADL2N uses Increment[64] array.

// SDK2N: bit-flag format (example: increment Data1 and Data3)
// slot.Increment = 0x05;

// ADL2N: array format
for (int i = 0; i < 64; i++) {
slot.Increment[i] = MPX_CAN_SIM_INC_FALSE;
}
slot.Increment[0] = MPX_CAN_SIM_INC_TRUE; // D1
slot.Increment[2] = MPX_CAN_SIM_INC_TRUE; // D3

Log Structure (StMPCANLog -> StMPXCANLog)

Old StMPCANLogNew StMPXCANLogNotes
mSecmSecEquivalent
uSecuSecEquivalent
DirDirEquivalent
ErrError + ErrorInfoDetailed
Frame.IdIDFlattened
Frame.IdFormatIDEName changed
Frame.RtrRTRFlattened
Frame.DlcDLCAN FD support
Frame.Data[8]Data[64]Size expanded
-ProtocolAdded (CAN/CAN FD identification)

Revisit buffer design previously based on 8-byte data.

Return Code (ER) Differences

Old SDK2NNew ADL2NNotes
E_OK=0E_OK=0Same
E_PARAM=1E_PARAM=1Same
E_DEVICE=2E_DEVICE=2Same
E_COMM=3E_COMM=3Same
E_TGT=4E_TGT=4Same
E_SLT_BUSY=5-Removed
-E_TRG_BUSY=11Added
E_DCT_FULL=6E_DCT_FULL=12Value changed
E_STS=7E_STATUS=105Value changed
E_OTHER=8E_OTHER=255Value changed
-E_TIMEOUT=202Added

Implementation Procedure (Replacement Flow)

  1. Update DLL references (MPCANCtrl* -> MPXCtrlFree*)
  2. Replace MPCANOpen with MPXOpen and add Serial management
  3. Consolidate old MPCANSetParamSimple/Detail calls into MPXCANSetParam
  4. Replace frame/slot structures to StMPXCAN*
  5. Replace MPCANGetLogEx with MPXCANGetLogEx, and review Num/Count types
  6. Reflect intent of old MPCANChangeSlotData into ReqInfo of MPXCANChangeSlot
  7. Update ER branch conditions to new definitions

Language-Specific Replacement Examples

C/C++ Replacement Example

// SDK2N
long serial = 0;
ER er = MPCANOpen(&serial);
er = MPCANSetParamSimple(CAN_MODE_MONITOR, CAN_REMOTE_DIS, CAN_PARAM_BR_500K, CAN_PARAM_SP_80P);

// ADL2N
StMPXDeviceInfo devices[8] = {};
unsigned char count = 0;
ER er = MPXOpen(devices, 8, &count);
unsigned long serial = (count > 0) ? devices[0].Serial : 0;

StMPXCANParam param = {};
param.EnableTerminate = MPX_CAN_TERMINATE_ENABLE;
param.Mode = MPX_CAN_MODE_MONITOR;
param.ArbitrationBaudrate = MPX_CAN_PARAM_ABR_500K;
param.ArbitrationSamplepoint = MPX_CAN_PARAM_SP_80P;
param.DataBaudrate = MPX_CAN_PARAM_DBR_2M; // set appropriate value when not using CAN FD
param.DataSamplepoint = MPX_CAN_PARAM_SP_80P;

unsigned char innerCh = 1; // target CH (set according to product specification)
er = MPXCANSetParam(serial, innerCh, &param);
er = MPXSetGetLogMode(serial, innerCh, MPX_GETLOGMODE_GETLOGAPI); // newly required in migration

C/C++ CAN Simulation Replacement Example (SetSlot to Start)

// SDK2N (example)
StMPCANSlot oldSlots[2] = {};
oldSlots[0].Enabled = CAN_SLOT_ENA;
oldSlots[0].EventKind = CAN_EVENT_PERIODIC;
oldSlots[0].Frame.Id = 0x100;
oldSlots[0].Frame.IdFormat = CAN_ID_STD;
oldSlots[0].Frame.Rtr = CAN_RTR_DATA;
oldSlots[0].Frame.Dlc = 8;
oldSlots[0].Cycle = 100;
MPCANSetSlot(oldSlots, 2);
MPCANMonitorStart();

// ADL2N (example)
StMPXCANParam simParam = {};
simParam.EnableTerminate = MPX_CAN_TERMINATE_ENABLE;
simParam.Mode = MPX_CAN_MODE_SIM;
simParam.ArbitrationBaudrate = MPX_CAN_PARAM_ABR_500K;
simParam.ArbitrationSamplepoint = MPX_CAN_PARAM_SP_80P;
simParam.DataBaudrate = MPX_CAN_PARAM_DBR_2M;
simParam.DataSamplepoint = MPX_CAN_PARAM_SP_80P;
MPXCANSetParam(serial, innerCh, &simParam);

StMPXCANSlot slots[2] = {};
slots[0].FrameType.Enabled = MPX_CAN_SLOT_ENABLE;
slots[0].FrameType.FrameType = MPX_CAN_FRAME_TYPE_PERIODIC;
slots[0].FrameType.Option.Protocol = MPX_CAN_PROTOCOL_CAN;
slots[0].FrameType.Option.BRS = MPX_CAN_BRS_DISABLE;
slots[0].FrameType.Option.ErrorAction = MPX_CAN_ERR_BEHAVIOR_ACTIVE;
slots[0].msSendCycle = 100;
slots[0].SendCounter = 0; // unlimited
slots[0].Frame.ID.ID = 0x100;
slots[0].Frame.ID.IDE = MPX_CAN_IDE_STD;
slots[0].Frame.ID.RTR = MPX_CAN_RTR_DATA;
slots[0].Frame.DL = 8;
slots[0].Frame.Data[0] = 0x01;
for (int i = 0; i < 64; i++) {
slots[0].Increment[i] = MPX_CAN_SIM_INC_FALSE;
}
slots[0].Increment[0] = MPX_CAN_SIM_INC_TRUE; // increment only D1

slots[1].FrameType.Enabled = MPX_CAN_SLOT_ENABLE;
slots[1].FrameType.FrameType = MPX_CAN_FRAME_TYPE_EVENT;
slots[1].FrameType.Option.Protocol = MPX_CAN_PROTOCOL_CAN;
slots[1].FrameType.Option.BRS = MPX_CAN_BRS_DISABLE;
slots[1].FrameType.Option.ErrorAction = MPX_CAN_ERR_BEHAVIOR_ACTIVE;
slots[1].Frame.ID.ID = 0x200;
slots[1].Frame.ID.IDE = MPX_CAN_IDE_STD;
slots[1].Frame.ID.RTR = MPX_CAN_RTR_DATA;
slots[1].Frame.DL = 8;

MPXCANSetSlot(serial, innerCh, slots, 2);
MPXMonitorStart(serial, MPX_SYNC_MASTER);

C# (P/Invoke) Replacement Example

using System;
using System.Runtime.InteropServices;

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public struct StMPXDeviceInfo
{
public uint Serial;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 64)]
public byte[] Model;
}

[DllImport("MPXCtrlFree.dll", CallingConvention = CallingConvention.StdCall)]
public static extern int MPXOpen(
[In, Out] StMPXDeviceInfo[] devices,
byte num,
ref byte count);

[DllImport("MPXCtrlFree.dll", CallingConvention = CallingConvention.StdCall)]
public static extern int MPXCANSetParam(
uint serial,
byte innerCh,
ref StMPXCANParam param);

[DllImport("MPXCtrlFree.dll", CallingConvention = CallingConvention.StdCall)]
public static extern int MPXSetGetLogMode(
uint serial,
byte innerCh,
byte mode);

// SDK2N MPCANOpen/MPCANSetParamSimple replacement image
var devices = new StMPXDeviceInfo[8];
byte count = 0;
int er = MPXOpen(devices, (byte)devices.Length, ref count);
uint serial = count > 0 ? devices[0].Serial : 0;
byte innerCh = 1;
er = MPXSetGetLogMode(serial, innerCh, 1); // MPX_GETLOGMODE_GETLOGAPI

Key Points for C# CAN Simulation Replacement

// 1) Set Param in SIM mode
param.Mode = MPX_CAN_MODE_SIM;
er = MPXCANSetParam(serial, innerCh, ref param);

// 2) Set Slot (nested FrameType and Frame.ID)
slots[0].FrameType.Enabled = MPX_CAN_SLOT_ENABLE;
slots[0].FrameType.FrameType = MPX_CAN_FRAME_TYPE_PERIODIC;
slots[0].FrameType.Option.Protocol = MPX_CAN_PROTOCOL_CAN;
slots[0].Frame.ID.ID = 0x100;
slots[0].Frame.ID.IDE = MPX_CAN_IDE_STD;
slots[0].Frame.ID.RTR = MPX_CAN_RTR_DATA;
slots[0].Frame.DL = 8;
slots[0].Increment[0] = MPX_CAN_SIM_INC_TRUE;

er = MPXCANSetSlot(serial, innerCh, slots, (byte)slots.Length);

// 3) Start monitoring (slot transmission starts)
er = MPXMonitorStart(serial, MPX_SYNC_MASTER);

Concept is the same when using .NET wrapper DLL (MPXCtrldotNET40Free*.dll).

Excel VBA Replacement Example

' SDK2N
Declare PtrSafe Function MPCANOpen Lib "MPCANCtrl_x64.DLL" (ByRef Serial As Long) As Long
Declare PtrSafe Function MPCANSetParamSimple Lib "MPCANCtrl_x64.DLL" (ByVal Mode As Byte, ByVal RcvRemote As Byte, ByVal Baudrate As Byte, ByVal SamplePoint As Byte) As Long

' ADL2N
Declare PtrSafe Function MPXOpen Lib "MPXCtrlFree_x64.DLL" (ByRef Devices As StMPXDeviceInfo, ByVal Num As Byte, ByRef Count As Byte) As Long
Declare PtrSafe Function MPXCANSetParam Lib "MPXCtrlFree_x64.DLL" (ByVal Serial As Long, ByVal InnerCh As Byte, ByRef Param As StMPXCANParam) As Long
Declare PtrSafe Function MPXSetGetLogMode Lib "MPXCtrlFree_x64.DLL" (ByVal Serial As Long, ByVal InnerCh As Byte, ByVal Mode As Byte) As Long

In VBA, same as old version, it is recommended not to use MPXGetLog / MPXSetLogCallBack directly.
Use MPXCANGetLogEx for log acquisition.

Key Points for Excel VBA CAN Simulation Replacement

' 1) Set SIM mode
Param.Mode = MPX_CAN_MODE_SIM
Ret = MPXCANSetParam(Serial, InnerCh, Param)

' 2) Set slot
Slots(0).FrameType.Enabled = MPX_CAN_SLOT_ENABLE
Slots(0).FrameType.FrameType = MPX_CAN_FRAME_TYPE_PERIODIC
Slots(0).FrameType.Option.Protocol = MPX_CAN_PROTOCOL_CAN
Slots(0).Frame.ID.ID = &H100
Slots(0).Frame.ID.IDE = MPX_CAN_IDE_STD
Slots(0).Frame.ID.RTR = MPX_CAN_RTR_DATA
Slots(0).Frame.DL = 8
Slots(0).Increment(0) = MPX_CAN_SIM_INC_TRUE

Ret = MPXCANSetSlot(Serial, InnerCh, Slots(0), 2)

' 3) Start
Ret = MPXMonitorStart(Serial, MPX_SYNC_MASTER)

Replacement Guidance for APIs with Large Differences

MPCANChangeSlotData -> MPXCANChangeSlot

Old API mainly updated slot data only.
New API explicitly specifies request type with ReqInfo:

  • MPX_CAN_SLOT_REQ_NONE
  • MPX_CAN_SLOT_REQ_DATA
  • MPX_CAN_SLOT_REQ_TRG
  • MPX_CAN_SLOT_REQ_DATA_TRG

Choose ReqInfo according to original behavior intention.

MPCANSendDirect/Ex -> MPXCANDirectSend

In new API, build StMPXCANDirect and explicitly set:

  • Protocol (CAN / CAN FD)
  • BRS (for CAN FD)
  • DL (0..8,12..64)

Do not directly reuse old StMPCANFrame; construct both StMPXCANFrameType and StMPXCANFrame.

Migration Checklist

  • DLL names changed from MPCANCtrl* to MPXCtrlFree*
  • MPCANOpen replaced with MPXOpen (Devices/Num/Count)
  • Serial and InnerCh are correctly specified in all new API calls
  • MPCANSetParamSimple/Detail consolidated into MPXCANSetParam
  • StMPCANFrame/Slot/Log replaced with StMPXCAN*
  • EventKind numeric dependencies are replaced with MPX_CAN_FRAME_TYPE_*
  • CAN simulation start flow replaced to SetParam(SIM) -> SetSlot -> MonitorStart
  • MPCANGetLogEx replaced with MPXCANGetLogEx, buffer design updated for unsigned short
  • MPCANChangeSlotData replaced with MPXCANChangeSlot, ReqInfo designed
  • Old ER numeric branch logic updated to new definitions
  • Protocol / BRS / DL / Data[64] verified for CAN FD usage