FPGAArrayFXPReadProperty.cs 2.7 KB

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