123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101 |
- using FxpConvert.Common;
- using log4net.Appender;
- using MessagePack.Formatters;
- using System.Buffers.Binary;
- using System.Reflection;
- using System.Runtime.CompilerServices;
- namespace NIFPGA
- {
- public sealed class FPGAArrayFXPWriteProperty : FPGABaseProperty
- {
- Interop.NiFpgaDll_ReadArrayU8 Read;
- Interop.NiFpgaDll_WriteArrayU8 Write;
- private object _Locker = new object();
- private NiFpga_FxpTypeInfo _TypeInfo;
- private IFxpConvert _Convert;
- private uint bytescount = 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;
- doubles = new double[count];
- tempvalue = new ulong[count];
- _TypeInfo = typeInfo;
- tempbuffer = new ulong[(int)Math.Ceiling(typeInfo.wordLength * count / 64.0)];
- bytescount = (uint)Math.Ceiling(typeInfo.wordLength * count / 8.0);
- Read = _Session.GetDelegate<Interop.NiFpgaDll_ReadArrayU8>();
- Write = _Session.GetDelegate<Interop.NiFpgaDll_WriteArrayU8>();
- }
- private double[] GetData()
- {
- lock (_Locker)
- {
- _Session.CheckResult(Read(_Session.Session, Indicator, ref Unsafe.As <ulong,byte>(ref tempbuffer[0]), bytescount));
- for(int i = 0; i < tempbuffer.Length;i++)
- {
- tempbuffer[i] = BinaryPrimitives.ReverseEndianness(tempbuffer[i]);
- }
- int tempdatalen = Unsafe.SizeOf<ulong>() * 8;
- ulong mask = (1ul << _TypeInfo.wordLength) - 1;
- for (int i = 0; i < Count; i++)
- {
- int index = i * _TypeInfo.wordLength / tempdatalen;
- int bitindex =tempdatalen - (i * _TypeInfo.wordLength % tempdatalen);
- if (bitindex >= _TypeInfo.wordLength)
- {
- tempvalue[i] = (tempbuffer[index] >> (bitindex-_TypeInfo.wordLength)) & mask;
- }
- else
- {
- 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;
- }
- }
- private void SetData(double[] values)
- {
- lock (_Locker)
- {
- if (values.Length != Count || Count == 0) return;
- _Convert.DoubleConvertToDxp(ref values[0], _TypeInfo, ref tempvalue[0], Count);
- int tempdatalen = Unsafe.SizeOf<ulong>() * 8;
- tempbuffer = new ulong[tempbuffer.Length];
- for (int i = 0; i < Count; i++)
- {
- int index = i * _TypeInfo.wordLength / tempdatalen;
- int bitindex = tempdatalen - (i * _TypeInfo.wordLength % tempdatalen);
- var b = (tempvalue[i] & ((1ul << _TypeInfo.wordLength) - 1));
- if (bitindex >= _TypeInfo.wordLength)
- {
- tempbuffer[index] |= (b << (bitindex - _TypeInfo.wordLength));
- }
- else
- {
- tempbuffer[index] |= (b >> (_TypeInfo.wordLength - bitindex));
- tempbuffer[index + 1] |= ((b & ((1ul << (_TypeInfo.wordLength - bitindex)) - 1)) << (tempdatalen - (_TypeInfo.wordLength - bitindex)));
- }
- }
- ulong[] oldvalues = new ulong[tempbuffer.Length];
- _Session.CheckResult(Read(_Session.Session, Indicator, ref Unsafe.As<ulong, byte>(ref oldvalues[0]), bytescount));
- for (int i = 0; i < tempbuffer.Length; i++)
- {
- tempbuffer[i] = BinaryPrimitives.ReverseEndianness(tempbuffer[i]);
- }
- bool changed = Enumerable.Range(0, oldvalues.Length).Any(x => oldvalues[x] != tempbuffer[x]);
- if (!changed) return;
- _Session.CheckResult(Write(_Session.Session, Indicator, ref Unsafe.As<ulong, byte>(ref tempbuffer[0]), bytescount));
- }
- }
- public uint Count { get; }
- public double[] Value { get => GetData(); set => SetData(value); }
- }
- }
|