hawkeye camera support(not tested)
This commit is contained in:
159
framework/Inspectron.HawkEye/Camera/I2CLinux.cs
Normal file
159
framework/Inspectron.HawkEye/Camera/I2CLinux.cs
Normal file
@@ -0,0 +1,159 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using Mono.Unix.Native;
|
||||
|
||||
namespace Inspectron.Devices.Raspberry
|
||||
{
|
||||
public unsafe class I2CLinux
|
||||
{
|
||||
string device;
|
||||
int fd = -1;
|
||||
|
||||
public I2CLinux(int index)
|
||||
{
|
||||
device = "/dev/i2c-" + index;
|
||||
Open();
|
||||
//Close();
|
||||
}
|
||||
|
||||
public void Open()
|
||||
{
|
||||
fd = Syscall.open(device, OpenFlags.O_RDWR);
|
||||
if (fd < 0)
|
||||
throw new IOException(device);
|
||||
}
|
||||
|
||||
void IoCtl(byte devAddr)
|
||||
{
|
||||
int ret = LunixNatives.ioctl(fd, LunixNatives.I2C_SLAVE, devAddr);
|
||||
if (ret < 0)
|
||||
throw new IOException(device + ": ioctl");
|
||||
}
|
||||
|
||||
public byte readBytes(byte devAddr, byte regAddr, byte length, byte[] data, int offset, ushort timeout = 0)
|
||||
{
|
||||
if (length > 127)
|
||||
throw new IOException(device + ": length > 127");
|
||||
|
||||
//Open();
|
||||
|
||||
IoCtl(devAddr);
|
||||
|
||||
//fixed(byte* p = ®Addr)
|
||||
{
|
||||
int ret = (int)Syscall.write(fd, ®Addr, 1);
|
||||
if (ret != 1)
|
||||
throw new IOException(device + ": write");
|
||||
}
|
||||
|
||||
int count;
|
||||
fixed (byte* p = &data[offset])
|
||||
{
|
||||
count = (int)Syscall.read(fd, p, (ulong)length);
|
||||
if (count < 0)
|
||||
throw new IOException(device + ": read");
|
||||
else if (count != length)
|
||||
throw new IOException(device + ": read short: length = " + length + " > " + count);
|
||||
}
|
||||
|
||||
//Close();
|
||||
|
||||
return (byte)count;
|
||||
}
|
||||
|
||||
public byte readBytes(byte devAddr, byte regAddr, byte length, byte[] data, ushort timeout = 0)
|
||||
{
|
||||
return readBytes(devAddr, regAddr, length, data, 0, timeout);
|
||||
}
|
||||
|
||||
/** Write multiple bytes to an 8-bit device register.
|
||||
* @param devAddr I2C slave device address
|
||||
* @param regAddr First register address to write to
|
||||
* @param length Number of bytes to write
|
||||
* @param data Buffer to copy new data from
|
||||
* @return Status of operation (true = success)
|
||||
*/
|
||||
public void writeBytes(byte devAddr, byte regAddr, byte length, byte[] data)
|
||||
{
|
||||
if (length > 127)
|
||||
throw new IOException(device + ": length > 127");
|
||||
|
||||
//Open();
|
||||
IoCtl(devAddr);
|
||||
|
||||
byte[] buffer = new byte[128];
|
||||
buffer[0] = regAddr;
|
||||
Array.Copy(data, 0, buffer, 1, length);
|
||||
|
||||
int count;
|
||||
fixed (byte* p = buffer)
|
||||
{
|
||||
count = (int)Syscall.write(fd, p, (ulong)(length + 1));
|
||||
}
|
||||
|
||||
if (count < 0)
|
||||
{
|
||||
throw new IOException(device + ": write = " + count);
|
||||
}
|
||||
else if (count != length + 1)
|
||||
{
|
||||
throw new IOException(device + ": write short = " + count);
|
||||
}
|
||||
|
||||
//Close();
|
||||
}
|
||||
|
||||
|
||||
/** Write multiple words to a 16-bit device register.
|
||||
* @param devAddr I2C slave device address
|
||||
* @param regAddr First register address to write to
|
||||
* @param length Number of words to write
|
||||
* @param data Buffer to copy new data from
|
||||
* @return Status of operation (true = success)
|
||||
*/
|
||||
public void writeWords(byte devAddr, byte regAddr, byte length, ushort[] data)
|
||||
{
|
||||
int count = 0;
|
||||
byte[] buf = new byte[128];
|
||||
int i;
|
||||
|
||||
// Should do potential byteswap and call writeBytes() really, but that
|
||||
// messes with the callers buffer
|
||||
|
||||
if (length > 63)
|
||||
{
|
||||
throw new IOException(device + ": length > 63");
|
||||
}
|
||||
|
||||
//Open();
|
||||
IoCtl(devAddr);
|
||||
|
||||
buf[0] = regAddr;
|
||||
for (i = 0; i < (int)length; i++)
|
||||
{
|
||||
buf[i * 2 + 1] = (byte)(data[i] >> 8);
|
||||
buf[i * 2 + 2] = (byte)data[i];
|
||||
}
|
||||
fixed (byte* p = buf)
|
||||
{
|
||||
count = (int)Syscall.write(fd, p, (ulong)(length * 2 + 1));
|
||||
}
|
||||
if (count < 0)
|
||||
{
|
||||
throw new IOException(device + ": write");
|
||||
}
|
||||
else if (count != length * 2 + 1)
|
||||
{
|
||||
throw new IOException(device + ": write short");
|
||||
}
|
||||
//Close();
|
||||
}
|
||||
|
||||
public void Close()
|
||||
{
|
||||
int ret = Syscall.close(fd);
|
||||
if (ret != 0)
|
||||
throw new IOException(device);
|
||||
}
|
||||
}
|
||||
}
|
||||
112
framework/Inspectron.HawkEye/Camera/InspectronCamera.cs
Normal file
112
framework/Inspectron.HawkEye/Camera/InspectronCamera.cs
Normal file
@@ -0,0 +1,112 @@
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Threading;
|
||||
using Inspectron.Devices.Raspberry;
|
||||
using Inspectron.HawkEye.Protocol;
|
||||
using Inspectron.HawkEye.Protocol.Interfaces;
|
||||
|
||||
namespace Inspectron.HawkEye.Camera
|
||||
{
|
||||
public class InspectronCamera:ICameraControl,IImageSource,ILightControl
|
||||
{
|
||||
|
||||
[DllImport("libVCLibProxy.so", CallingConvention = CallingConvention.Cdecl)]
|
||||
static extern IntPtr init(Int32 captBuf);
|
||||
[DllImport("libVCLibProxy.so", CallingConvention = CallingConvention.Cdecl)]
|
||||
static extern int trigger(IntPtr cpt, byte[] addr, int lines, int captBuf,ref int cancelFlag);
|
||||
[DllImport("libVCLibProxy.so", CallingConvention = CallingConvention.Cdecl)]
|
||||
static extern void set_parameters(IntPtr cpt, ref ImageSettings imageSettings);
|
||||
|
||||
[DllImport("libVCLibProxy.so", CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern int test();
|
||||
byte[] _buffer = new byte[2048 * 250 * 4];
|
||||
|
||||
public InspectronCamera()
|
||||
{
|
||||
|
||||
_i2c = new I2CLinux(0);
|
||||
_i2c.Open();
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
private bool _isRunningContiniuos = false;
|
||||
private IntPtr _cp= IntPtr.Zero;
|
||||
private ImageSettings _imageSettings=new ImageSettings()
|
||||
{
|
||||
CaptureBuffer = 25,
|
||||
Gain = 200,
|
||||
Lines = 1000,
|
||||
Shutter = 200,
|
||||
SensorWidth = 1440
|
||||
};
|
||||
|
||||
private I2CLinux _i2c;
|
||||
|
||||
private int _lastBuffer = -1;
|
||||
public void SetParameters(CameraSettings cameraSettings)
|
||||
|
||||
{
|
||||
_cameraSettings = cameraSettings;
|
||||
ImageSettings imageSettings = cameraSettings.ImageSettings;
|
||||
if (_lastBuffer ==-1)
|
||||
{
|
||||
_lastBuffer = imageSettings.CaptureBuffer;
|
||||
_cp = init(_lastBuffer);
|
||||
}
|
||||
|
||||
|
||||
_imageSettings = imageSettings;
|
||||
_buffer=new byte[imageSettings.SensorWidth*(imageSettings.Lines)];
|
||||
var cpImageSettings = imageSettings;
|
||||
cpImageSettings.UseExternalTrigger =imageSettings.UseExternalTrigger;
|
||||
|
||||
if(_lastBuffer==imageSettings.CaptureBuffer)
|
||||
set_parameters(_cp, ref cpImageSettings);
|
||||
else
|
||||
Console.WriteLine("Warning! Buffer size changed. Needs restart");
|
||||
_i2c.writeBytes(4, 2, 4, BitConverter.GetBytes(imageSettings.Divider));
|
||||
Thread.Sleep(100);
|
||||
_i2c.writeBytes(4,3,1, new byte[] { (byte)imageSettings.UseExternalTrigger });
|
||||
Thread.Sleep(100);
|
||||
}
|
||||
|
||||
|
||||
private int _cancelFlag = 0;
|
||||
private CameraSettings _cameraSettings;
|
||||
|
||||
public byte[] GetImage()
|
||||
{
|
||||
_cancelFlag = 0;
|
||||
var sw = Stopwatch.StartNew();
|
||||
|
||||
_i2c.writeBytes(4, 4, 1,new byte[]{ (byte)(_cameraSettings.LaserTrigger?1:0)} );
|
||||
//Thread.Sleep(20);
|
||||
_i2c.writeBytes(4, 5, 4, BitConverter.GetBytes(_cameraSettings.LaserTriggerDelay));
|
||||
//Thread.Sleep(20);
|
||||
|
||||
trigger(_cp, _buffer, _imageSettings.Lines, _imageSettings.CaptureBuffer,ref _cancelFlag);
|
||||
sw.Stop();
|
||||
Console.WriteLine("Trigger time: "+sw.ElapsedMilliseconds);
|
||||
if(_cancelFlag==1)return new byte[0];
|
||||
return _buffer;
|
||||
}
|
||||
|
||||
public void CancelTrigger()
|
||||
{
|
||||
_cancelFlag = 1;
|
||||
}
|
||||
|
||||
public void SetLight(int pwm1, int pwm2)
|
||||
{
|
||||
Console.WriteLine($"setting lights to {pwm1}/{pwm2}");
|
||||
pwm1 = (int)(pwm1 / 100.0 * 255);
|
||||
pwm2 = (int)(pwm2 / 100.0 * 255);
|
||||
_i2c.writeBytes(4, 1, 2, new byte[] { (byte)pwm1,(byte)pwm2 });
|
||||
|
||||
Thread.Sleep(10);
|
||||
}
|
||||
}
|
||||
}
|
||||
21
framework/Inspectron.HawkEye/Camera/LunixNatives.cs
Normal file
21
framework/Inspectron.HawkEye/Camera/LunixNatives.cs
Normal file
@@ -0,0 +1,21 @@
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace Inspectron.Devices.Raspberry
|
||||
{
|
||||
public static class LunixNatives
|
||||
{
|
||||
public const int O_RDWR = 2;
|
||||
|
||||
[DllImport("libc.so.6")]
|
||||
extern public static int open(string file, int mode);
|
||||
|
||||
[DllImport("libc.so.6")]
|
||||
extern public static int close(int fd);
|
||||
|
||||
[DllImport("libc.so.6")]
|
||||
extern public static int ioctl(int fd, int request, byte x);
|
||||
|
||||
public const int I2C_SLAVE = 0x0703;
|
||||
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user