FPGAArrayFXPReadProperty.cs 2.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162
  1. using FxpConvert.Common;
  2. using System.Buffers.Binary;
  3. using System.Runtime.CompilerServices;
  4. namespace NIFPGA
  5. {
  6. public sealed class FPGAArrayFXPReadProperty : FPGABaseProperty
  7. {
  8. private object _Locker = new object();
  9. Interop.NiFpgaDll_ReadArrayU8 Read;
  10. private NiFpga_FxpTypeInfo _TypeInfo;
  11. private IFxpConvert _Convert;
  12. private uint bytescount = 0;
  13. private ulong[] tempbuffer = new ulong[0];
  14. private ulong[] tempvalue = new ulong[0];
  15. private double[] doubles = new double[0];
  16. internal FPGAArrayFXPReadProperty(FPGASession session, uint indicator, uint count, NiFpga_FxpTypeInfo typeInfo, IFxpConvert convert) : base(session, indicator, true)
  17. {
  18. _Convert = convert;
  19. Count = count;
  20. tempvalue = new ulong[count];
  21. doubles = new double[count];
  22. _TypeInfo = typeInfo;
  23. tempbuffer = new ulong[(int)Math.Ceiling(typeInfo.wordLength * count / (8 * 8.0))];
  24. bytescount = (uint)Math.Ceiling(typeInfo.wordLength * count / 8.0);
  25. Read = _Session.GetDelegate<Interop.NiFpgaDll_ReadArrayU8>();
  26. }
  27. private double[] GetData()
  28. {
  29. lock (_Locker)
  30. {
  31. _Session.CheckResult(Read(_Session.Session, Indicator, ref Unsafe.As<ulong, byte>(ref tempbuffer[0]), bytescount));
  32. for (int i = 0; i < tempbuffer.Length; i++)
  33. {
  34. tempbuffer[i] = BinaryPrimitives.ReverseEndianness(tempbuffer[i]);
  35. }
  36. int tempdatalen = Unsafe.SizeOf<ulong>() * 8;
  37. ulong mask = (1ul << _TypeInfo.wordLength) - 1;
  38. for (int i = 0; i < Count; i++)
  39. {
  40. int index = i * _TypeInfo.wordLength / tempdatalen;
  41. int bitindex = tempdatalen - (i * _TypeInfo.wordLength % tempdatalen);
  42. if (bitindex >= _TypeInfo.wordLength)
  43. {
  44. tempvalue[i] = (tempbuffer[index] >> (bitindex - _TypeInfo.wordLength)) & mask;
  45. }
  46. else
  47. {
  48. tempvalue[i] = (((tempbuffer[index] & ((1ul << bitindex) - 1)) << (_TypeInfo.wordLength - bitindex)) | (tempbuffer[index + 1] >> (tempdatalen - (_TypeInfo.wordLength - bitindex))));
  49. }
  50. }
  51. _Convert.FxpConvertToDouble(ref tempvalue[0], _TypeInfo, ref doubles[0], Count);
  52. return doubles;
  53. }
  54. }
  55. public uint Count { get; }
  56. public double[] Value { get => GetData(); }
  57. }
  58. }