FPGAArrayFXPWriteProperty.cs 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475
  1. using FxpConvert.Common;
  2. using System.Reflection;
  3. using System.Runtime.CompilerServices;
  4. namespace NIFPGA
  5. {
  6. public sealed class FPGAArrayFXPWriteProperty : FPGABaseProperty
  7. {
  8. Interop.NiFpgaDll_ReadArrayU8 Read;
  9. Interop.NiFpgaDll_WriteArrayU8 Write;
  10. private NiFpga_FxpTypeInfo _TypeInfo;
  11. private IFxpConvert _Convert;
  12. private ulong[] tempbuffer = new ulong[0];
  13. private double[] doubles = new double[0];
  14. private ulong[] tempvalue = new ulong[0];
  15. internal FPGAArrayFXPWriteProperty(FPGASession session, uint indicator, uint count,NiFpga_FxpTypeInfo typeInfo, IFxpConvert convert) : base(session, indicator,false)
  16. {
  17. _Convert = convert;
  18. Count = count;
  19. doubles = new double[count];
  20. tempvalue = new ulong[count];
  21. _TypeInfo = typeInfo;
  22. tempbuffer = new ulong[(int)Math.Ceiling(typeInfo.wordLength * count / (Unsafe.SizeOf<ulong>() * 8.0))];
  23. Read = _Session.GetDelegate<Interop.NiFpgaDll_ReadArrayU8>();
  24. Write = _Session.GetDelegate<Interop.NiFpgaDll_WriteArrayU8>();
  25. }
  26. private double[] GetData()
  27. {
  28. _Session.CheckResult(Read(_Session.Session, Indicator, ref Unsafe.As<ulong,byte>(ref tempbuffer[0]), (uint)tempbuffer.Length*8));
  29. int tempdatalen = Unsafe.SizeOf<ulong>() * 8;
  30. ulong mask = (1ul << _TypeInfo.wordLength) - 1;
  31. for (int i = 0; i < Count; i++)
  32. {
  33. int index = i * _TypeInfo.wordLength / tempdatalen;
  34. int bitindex = tempdatalen - (i * _TypeInfo.wordLength % tempdatalen);
  35. if (bitindex >= _TypeInfo.wordLength)
  36. {
  37. tempvalue[i] = (tempbuffer[index] >> (bitindex - _TypeInfo.wordLength)) & mask;
  38. }
  39. else
  40. {
  41. tempvalue[i] = (((tempbuffer[index] & ((1ul << bitindex) - 1)) << (_TypeInfo.wordLength - bitindex)) | (tempbuffer[index + 1] >> (tempdatalen - (_TypeInfo.wordLength - bitindex))));
  42. }
  43. }
  44. _Convert.FxpConvertToDouble(ref tempvalue[0], _TypeInfo, ref doubles[0], Count);
  45. return doubles;
  46. }
  47. private void SetData(double[] values)
  48. {
  49. if (values.Length != Count) return;
  50. _Convert.DoubleConvertToDxp(ref values[0], _TypeInfo, ref tempvalue[0], Count);
  51. int tempdatalen = Unsafe.SizeOf<ulong>() * 8;
  52. for (int i = 0; i < Count; i++)
  53. {
  54. int index = i * _TypeInfo.wordLength / tempdatalen;
  55. int bitindex = tempdatalen - (i * _TypeInfo.wordLength % tempdatalen);
  56. var b =(tempvalue[i] & ((1ul << _TypeInfo.wordLength) - 1));
  57. if (bitindex >= _TypeInfo.wordLength)
  58. {
  59. tempbuffer[index] |= (b << (bitindex - _TypeInfo.wordLength));
  60. }
  61. else
  62. {
  63. tempbuffer[index] |= (b >> (_TypeInfo.wordLength - bitindex));
  64. tempbuffer[index + 1] |= ((b & ((1ul << (_TypeInfo.wordLength - bitindex)) - 1)) << (tempdatalen - (_TypeInfo.wordLength - bitindex)));
  65. }
  66. }
  67. _Session.CheckResult(Write(_Session.Session,Indicator, ref Unsafe.As<ulong,byte>(ref tempbuffer[0]), (uint)tempbuffer.Length*8));
  68. }
  69. public uint Count { get; }
  70. public double[] Value { get => GetData(); set => SetData(value); }
  71. }
  72. }