191 lines
6.3 KiB
C#
191 lines
6.3 KiB
C#
using System.Runtime.InteropServices;
|
|
|
|
namespace ZB.MOM.WW.OtOpcUa.Driver.FOCAS;
|
|
|
|
/// <summary>
|
|
/// P/Invoke surface for Fanuc FWLIB (<c>Fwlib32.dll</c>). Declarations extracted from
|
|
/// <c>fwlib32.h</c> in the strangesast/fwlib repo; the licensed DLL itself is NOT shipped
|
|
/// with OtOpcUa — the deployment places <c>Fwlib32.dll</c> next to the server executable
|
|
/// or on <c>PATH</c>.
|
|
/// </summary>
|
|
/// <remarks>
|
|
/// Deliberately narrow — only the calls <see cref="FwlibFocasClient"/> actually makes.
|
|
/// FOCAS has 800+ functions in <c>fwlib32.h</c>; pulling in every one would bloat the
|
|
/// P/Invoke surface + signal more coverage than this driver provides. Expand as capabilities
|
|
/// are added.
|
|
/// </remarks>
|
|
internal static class FwlibNative
|
|
{
|
|
private const string Library = "Fwlib32.dll";
|
|
|
|
// ---- Handle lifetime ----
|
|
|
|
/// <summary>Open an Ethernet FWLIB handle. Returns EW_OK (0) on success; handle written out.</summary>
|
|
[DllImport(Library, EntryPoint = "cnc_allclibhndl3", CharSet = CharSet.Ansi, ExactSpelling = true)]
|
|
public static extern short AllcLibHndl3(
|
|
[MarshalAs(UnmanagedType.LPStr)] string ipaddr,
|
|
ushort port,
|
|
int timeout,
|
|
out ushort handle);
|
|
|
|
[DllImport(Library, EntryPoint = "cnc_freelibhndl", ExactSpelling = true)]
|
|
public static extern short FreeLibHndl(ushort handle);
|
|
|
|
// ---- PMC ----
|
|
|
|
/// <summary>PMC range read. <paramref name="addrType"/> is the ADR_* enum; <paramref name="dataType"/> is 0 byte / 1 word / 2 long.</summary>
|
|
[DllImport(Library, EntryPoint = "pmc_rdpmcrng", ExactSpelling = true)]
|
|
public static extern short PmcRdPmcRng(
|
|
ushort handle,
|
|
short addrType,
|
|
short dataType,
|
|
ushort startNumber,
|
|
ushort endNumber,
|
|
ushort length,
|
|
ref IODBPMC buffer);
|
|
|
|
[DllImport(Library, EntryPoint = "pmc_wrpmcrng", ExactSpelling = true)]
|
|
public static extern short PmcWrPmcRng(
|
|
ushort handle,
|
|
ushort length,
|
|
ref IODBPMC buffer);
|
|
|
|
// ---- Parameters ----
|
|
|
|
[DllImport(Library, EntryPoint = "cnc_rdparam", ExactSpelling = true)]
|
|
public static extern short RdParam(
|
|
ushort handle,
|
|
ushort number,
|
|
short axis,
|
|
short length,
|
|
ref IODBPSD buffer);
|
|
|
|
[DllImport(Library, EntryPoint = "cnc_wrparam", ExactSpelling = true)]
|
|
public static extern short WrParam(
|
|
ushort handle,
|
|
short length,
|
|
ref IODBPSD buffer);
|
|
|
|
// ---- Macro variables ----
|
|
|
|
[DllImport(Library, EntryPoint = "cnc_rdmacro", ExactSpelling = true)]
|
|
public static extern short RdMacro(
|
|
ushort handle,
|
|
short number,
|
|
short length,
|
|
ref ODBM buffer);
|
|
|
|
[DllImport(Library, EntryPoint = "cnc_wrmacro", ExactSpelling = true)]
|
|
public static extern short WrMacro(
|
|
ushort handle,
|
|
short number,
|
|
short length,
|
|
int macroValue,
|
|
short decimalPointCount);
|
|
|
|
// ---- Status ----
|
|
|
|
[DllImport(Library, EntryPoint = "cnc_statinfo", ExactSpelling = true)]
|
|
public static extern short StatInfo(ushort handle, ref ODBST buffer);
|
|
|
|
// ---- Structs ----
|
|
|
|
/// <summary>
|
|
/// IODBPMC — PMC range I/O buffer. 8-byte header + 40-byte union. We marshal the union
|
|
/// as a fixed byte buffer + interpret per <see cref="FocasDataType"/> on the managed side.
|
|
/// </summary>
|
|
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
|
public struct IODBPMC
|
|
{
|
|
public short TypeA;
|
|
public short TypeD;
|
|
public ushort DatanoS;
|
|
public ushort DatanoE;
|
|
// 40-byte union: cdata[5] / idata[5] / ldata[5] / fdata[5] / dbdata[5] — dbdata is the widest.
|
|
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 40)]
|
|
public byte[] Data;
|
|
}
|
|
|
|
/// <summary>
|
|
/// IODBPSD — CNC parameter I/O buffer. Axis-aware; for non-axis parameters pass axis=0.
|
|
/// Union payload is bytes / shorts / longs — we marshal 32 bytes as the widest slot.
|
|
/// </summary>
|
|
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
|
public struct IODBPSD
|
|
{
|
|
public short Datano;
|
|
public short Type; // axis index (0 for non-axis)
|
|
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)]
|
|
public byte[] Data;
|
|
}
|
|
|
|
/// <summary>ODBM — macro variable read buffer. Value = <c>McrVal / 10^DecVal</c>.</summary>
|
|
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
|
public struct ODBM
|
|
{
|
|
public short Datano;
|
|
public short Dummy;
|
|
public int McrVal; // long in C; 32-bit signed
|
|
public short DecVal; // decimal-point count
|
|
}
|
|
|
|
/// <summary>ODBST — CNC status info. Machine state, alarm flags, automatic / edit mode.</summary>
|
|
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
|
public struct ODBST
|
|
{
|
|
public short Dummy;
|
|
public short TmMode;
|
|
public short Aut;
|
|
public short Run;
|
|
public short Motion;
|
|
public short Mstb;
|
|
public short Emergency;
|
|
public short Alarm;
|
|
public short Edit;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// PMC address-letter → FOCAS <c>ADR_*</c> numeric code. Per Fanuc FOCAS/2 spec the codes
|
|
/// are: G=0, F=1, Y=2, X=3, A=4, R=5, T=6, K=7, C=8, D=9, E=10. Exposed internally +
|
|
/// tested so the FwlibFocasClient translation is verifiable without the DLL loaded.
|
|
/// </summary>
|
|
internal static class FocasPmcAddrType
|
|
{
|
|
public static short? FromLetter(string letter) => letter.ToUpperInvariant() switch
|
|
{
|
|
"G" => 0,
|
|
"F" => 1,
|
|
"Y" => 2,
|
|
"X" => 3,
|
|
"A" => 4,
|
|
"R" => 5,
|
|
"T" => 6,
|
|
"K" => 7,
|
|
"C" => 8,
|
|
"D" => 9,
|
|
"E" => 10,
|
|
_ => null,
|
|
};
|
|
}
|
|
|
|
/// <summary>PMC data-type numeric codes per FOCAS/2: 0 = byte, 1 = word, 2 = long, 4 = float, 5 = double.</summary>
|
|
internal static class FocasPmcDataType
|
|
{
|
|
public const short Byte = 0;
|
|
public const short Word = 1;
|
|
public const short Long = 2;
|
|
public const short Float = 4;
|
|
public const short Double = 5;
|
|
|
|
public static short FromFocasDataType(FocasDataType t) => t switch
|
|
{
|
|
FocasDataType.Bit or FocasDataType.Byte => Byte,
|
|
FocasDataType.Int16 => Word,
|
|
FocasDataType.Int32 => Long,
|
|
FocasDataType.Float32 => Float,
|
|
FocasDataType.Float64 => Double,
|
|
_ => Byte,
|
|
};
|
|
}
|