|
@@ -1,5 +1,6 @@
|
|
|
using FxpConvert.Common;
|
|
|
using System.Reflection;
|
|
|
+using System.Runtime.CompilerServices;
|
|
|
|
|
|
namespace NIFPGA
|
|
|
{
|
|
@@ -9,34 +10,39 @@ namespace NIFPGA
|
|
|
Interop.NiFpgaDll_WriteArrayU8 Write;
|
|
|
private NiFpga_FxpTypeInfo _TypeInfo;
|
|
|
private IFxpConvert _Convert;
|
|
|
- private byte[] tempbuffer = new byte[0];
|
|
|
- private ulong[] tempvalue = new ulong[0];
|
|
|
+ private ulong[] tempbuffer = new ulong[0];
|
|
|
private double[] doubles = new double[0];
|
|
|
+ private ulong[] tempvalue = new ulong[0];
|
|
|
internal FPGAArrayFXPWriteProperty(FPGASession session, uint indicator, uint count,NiFpga_FxpTypeInfo typeInfo, IFxpConvert convert) : base(session, indicator,false)
|
|
|
{
|
|
|
_Convert = convert;
|
|
|
Count = count;
|
|
|
- tempvalue = new ulong[count];
|
|
|
doubles = new double[count];
|
|
|
+ tempvalue = new ulong[count];
|
|
|
_TypeInfo = typeInfo;
|
|
|
- tempbuffer = new byte[(int)Math.Ceiling(typeInfo.wordLength*count / 8.0)];
|
|
|
+ tempbuffer = new ulong[(int)Math.Ceiling(typeInfo.wordLength * count / (Unsafe.SizeOf<ulong>() * 8.0))];
|
|
|
Read = _Session.GetDelegate<Interop.NiFpgaDll_ReadArrayU8>();
|
|
|
Write = _Session.GetDelegate<Interop.NiFpgaDll_WriteArrayU8>();
|
|
|
}
|
|
|
private double[] GetData()
|
|
|
{
|
|
|
- lock (Read)
|
|
|
+ _Session.CheckResult(Read(_Session.Session, Indicator, ref Unsafe.As<ulong,byte>(ref tempbuffer[0]), (uint)tempbuffer.Length*8));
|
|
|
+
|
|
|
+ int tempdatalen = Unsafe.SizeOf<ulong>() * 8;
|
|
|
+ ulong mask = (1ul << _TypeInfo.wordLength) - 1;
|
|
|
+ for (int i = 0; i < Count; i++)
|
|
|
{
|
|
|
- _Session.CheckResult(Read(_Session.Session, Indicator, ref tempbuffer[0], (uint)tempbuffer.Length));
|
|
|
- string s = string.Empty;
|
|
|
- for (int i = 0; i < tempbuffer.Length; i++)
|
|
|
+ int index = i * _TypeInfo.wordLength / tempdatalen;
|
|
|
+ int bitindex = tempdatalen - (i * _TypeInfo.wordLength % tempdatalen);
|
|
|
+ if (bitindex >= _TypeInfo.wordLength)
|
|
|
{
|
|
|
- s += tempbuffer[i].ToString("b").PadLeft(8, '0');
|
|
|
+ tempvalue[i] = (tempbuffer[index] >> (bitindex - _TypeInfo.wordLength)) & mask;
|
|
|
}
|
|
|
- for (int i = 0; i < tempvalue.Length; i++)
|
|
|
+ else
|
|
|
{
|
|
|
- tempvalue[i] = System.Convert.ToUInt64(s.Substring(i * _TypeInfo.wordLength, _TypeInfo.wordLength), 2);
|
|
|
+ tempvalue[i] = (((tempbuffer[index] & ((1ul << bitindex) - 1)) << (_TypeInfo.wordLength - bitindex)) | (tempbuffer[index + 1] >> (tempdatalen - (_TypeInfo.wordLength - bitindex))));
|
|
|
}
|
|
|
+ }
|
|
|
|
|
|
_Convert.FxpConvertToDouble(ref tempvalue[0], _TypeInfo, ref doubles[0], Count);
|
|
|
return doubles;
|
|
@@ -44,21 +50,18 @@ namespace NIFPGA
|
|
|
}
|
|
|
private void SetData(double[] values)
|
|
|
{
|
|
|
- lock (Read)
|
|
|
+ if (values.Length != Count) return;
|
|
|
+ _Convert.DoubleConvertToDxp(ref values[0], _TypeInfo, ref tempvalue[0], Count);
|
|
|
+ string s = string.Empty;
|
|
|
+ for(int i=0;i<tempvalue.Length;i++)
|
|
|
{
|
|
|
- if (values.Length != Count) return;
|
|
|
- _Convert.DoubleConvertToDxp(ref values[0], _TypeInfo, ref tempvalue[0], Count);
|
|
|
- string s = string.Empty;
|
|
|
- for (int i = 0; i < tempvalue.Length; i++)
|
|
|
- {
|
|
|
- s += tempvalue[i].ToString("b").PadLeft(64, '0').Substring(64 - _TypeInfo.wordLength, _TypeInfo.wordLength);
|
|
|
- }
|
|
|
- for (int i = 0; i < tempbuffer.Length; i++)
|
|
|
- {
|
|
|
- tempbuffer[i] = System.Convert.ToByte(s.Substring(i * 8, Math.Min(8, s.Length - i * 8)), 2);
|
|
|
- }
|
|
|
- _Session.CheckResult(Write(_Session.Session, Indicator, ref tempbuffer[0], (uint)tempbuffer.Length));
|
|
|
+ s += tempvalue[i].ToString("b").PadLeft(64, '0').Substring(64 - _TypeInfo.wordLength, _TypeInfo.wordLength);
|
|
|
+ }
|
|
|
+ for(int i=0;i< tempbuffer.Length;i++)
|
|
|
+ {
|
|
|
+ tempbuffer[i] = System.Convert.ToByte(s.Substring(i * 8, Math.Min(8, s.Length - i * 8)),2);
|
|
|
}
|
|
|
+ _Session.CheckResult(Write(_Session.Session,Indicator, ref tempbuffer[0], (uint)tempbuffer.Length));
|
|
|
}
|
|
|
public uint Count { get; }
|
|
|
public double[] Value { get => GetData(); set => SetData(value); }
|