Credit: Chris Tacke
This code was written for reading and writing 1 or 2 bytes to and from CE ports for analog and digital I/O, so it will require some massaging for larger streams like COM port transfer. Still, it's a start.
using System;
using System.Runtime.InteropServices;
namespace ADSLibrary
{
public class CEPorts
{
public static bool PortIsValid(string PortName)
{
int hPort = CEAPI.INVALID_HANDLE_VALUE;
// open port
hPort = CEAPI.CreateFile(PortName, CEAPI.GENERIC_WRITE, 0, 0, CEAPI.OPEN_EXISTING, 0, 0);
// check for success
if(hPort == CEAPI.INVALID_HANDLE_VALUE)
{
if(CEAPI.GetLastError() == 55)
return false;
else
{
Exception e = new Exception("Failed to open port '" + PortName + "': " + Convert.ToString(CEAPI.GetLastError()));
throw e;
}
}
CEAPI.CloseHandle(hPort);
return true;
}
public static bool WritePort(string PortName, byte Value)
{
int hPort = CEAPI.INVALID_HANDLE_VALUE;
int dwSize = 1;
byte[] buffer = {Value};
// open port
hPort = CEAPI.CreateFile(PortName, CEAPI.GENERIC_WRITE, 0, 0, CEAPI.OPEN_EXISTING, 0, 0);
// check for success
if(hPort == CEAPI.INVALID_HANDLE_VALUE)
{
Exception e = new Exception("Failed to open port '" + PortName + "': " + Convert.ToString(CEAPI.GetLastError()));
throw e;
}
// write to port
if(!CEAPI.WriteFile(hPort, buffer, 1, ref dwSize, 0))
{
Exception e = new Exception("Unable to write to port '" + PortName + "': " + Convert.ToString(CEAPI.GetLastError()));
throw e;
}
// close port
if(!CEAPI.CloseHandle(hPort))
{
Exception e = new Exception("Unable to close port '" + PortName + "': " + Convert.ToString(CEAPI.GetLastError()));
throw e;
}
return true;
}
public static byte ReadPortByte(string PortName)
{
int hPort = CEAPI.INVALID_HANDLE_VALUE;
int read = 0;
byte[] buffer = new byte[1];
// open port
hPort = CEAPI.CreateFile(PortName, CEAPI.GENERIC_READ, 0, 0, CEAPI.OPEN_EXISTING, 0, 0);
// check for success
if(hPort == CEAPI.INVALID_HANDLE_VALUE)
{
Exception e = new Exception("Failed to open port '" + PortName + "': " + Convert.ToString(CEAPI.GetLastError()));
throw e;
}
// read port value
if(!CEAPI.ReadFile(hPort, buffer, 1, ref read, 0))
{
Exception e = new Exception("Failed to read port '" + PortName + "': " + Convert.ToString(CEAPI.GetLastError()));
throw e;
}
if(read != 1)
{
Exception e;
e = new Exception("BYTE block size specified but " + Convert.ToString(read) + " bytes returned");
throw e;
}
// close port
if(!CEAPI.CloseHandle(hPort))
{
Exception e = new Exception("Unable to close port '" + PortName + "': " + Convert.ToString(CEAPI.GetLastError()));
throw e;
}
return buffer[0];
}
public static ushort ReadPortWord(string PortName)
{
int hPort = CEAPI.INVALID_HANDLE_VALUE;
int read = 0;
byte[] buffer = new byte[2];
// open port
hPort = CEAPI.CreateFile(PortName, CEAPI.GENERIC_READ, 0, 0, CEAPI.OPEN_EXISTING, 0, 0);
// check for success
if(hPort == CEAPI.INVALID_HANDLE_VALUE)
{
Exception e = new Exception("Failed to open port '" + PortName + "': " + Convert.ToString(CEAPI.GetLastError()));
throw e;
}
// read port value
if(!CEAPI.ReadFile(hPort, buffer, 2, ref read, 0))
{
Exception e = new Exception("Failed to read port '" + PortName + "': " + Convert.ToString(CEAPI.GetLastError()));
throw e;
}
if(read != 2)
{
Exception e;
e = new Exception("WORD block size specified but " + Convert.ToString(read) + " bytes returned");
throw e;
}
// close port
if(!CEAPI.CloseHandle(hPort))
{
Exception e = new Exception("Unable to close port '" + PortName + "': " + Convert.ToString(CEAPI.GetLastError()));
throw e;
}
// convert the 2-byte array to a word
return (ushort)((buffer[1] << 8) + buffer[0]);
}
}
internal class CEAPI
{
public const uint GENERIC_READ = 0x80000000;
public const uint GENERIC_WRITE = 0x40000000;
public const int OPEN_EXISTING = 3;
public const int INVALID_HANDLE_VALUE = -1;
[DllImport("coredll.dll", EntryPoint="WriteFile")]
public static extern bool WriteFile(
int hFile,
Byte[] lpBuffer,
int nNumberOfBytesToWrite,
ref int lpNumberOfBytesWritten,
int lpOverlapped);
[DllImport("coredll.dll", EntryPoint="ReadFile")]
public static extern bool ReadFile(
int hFile,
byte[] lpBuffer,
int nNumberOfBytesToRead,
ref int lpNumberOfBytesRead,
int lpOverlapped);
[DllImport("coredll.dll", EntryPoint="CreateFile")]
public static extern int CreateFile(
string lpFileName,
uint dwDesiredAccess,
int dwShareMode,
int lpSecurityAttributes,
int dwCreationDisposition,
int dwFlagsAndAttributes,
int hTemplateFile);
[DllImport("coredll.dll", EntryPoint="CloseHandle")]
public static extern bool CloseHandle(int hObject);
[DllImport("coredll.dll", EntryPoint="GetLastError")]
public static extern int GetLastError();
}
}