readout software for 2 channels [0 and 1] of the tdc-gpx2 board with raspberry pi 3B SPI readout. This code is a fork of the original design by marvin.peter@physik.uni-giessen.de https://github.com/marvin5300/tdc-gpx2_software
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

119 lines
4.8 KiB

1 year ago
  1. #ifndef GPX2_H
  2. #define GPX2_H
  3. #include "config.h"
  4. #include "../spidevice.h"
  5. #include <stdint.h>
  6. #include <limits>
  7. #include <string>
  8. #include <vector>
  9. #include <queue>
  10. #include <chrono>
  11. #include <cmath>
  12. namespace SPI {
  13. namespace GPX2_TDC {
  14. static constexpr std::uint8_t spiopc_power = 0x30; // Power on reset and stop measurement
  15. static constexpr std::uint8_t spiopc_init = 0x18; // Initializes Chip and starts measurement
  16. static constexpr std::uint8_t spiopc_write_config = 0x80; // Write to configuration register X=0..17
  17. static constexpr std::uint8_t spiopc_read_results = 0x60; // Read opcode for result and status register X=8..31
  18. static constexpr std::uint8_t spiopc_read_config = 0x40; // Readout of configuration register X=0..17
  19. enum class StopChannel{
  20. channel_0,
  21. channel_1,
  22. channel_2,
  23. channel_3
  24. };
  25. struct Meas{
  26. enum Status{
  27. Invalid,
  28. Valid
  29. }status{Invalid};
  30. StopChannel stop_channel{};
  31. uint32_t ref_index{};
  32. uint32_t stop_result{};
  33. double lsb_ps{1.};
  34. double refclk_freq{std::numeric_limits<double>::quiet_NaN()};
  35. std::chrono::time_point<std::chrono::system_clock> ts{};
  36. operator bool();
  37. auto operator < (const Meas& other) const -> bool;
  38. auto operator > (const Meas& other) const -> bool;
  39. auto operator == (const Meas& other) const -> bool;
  40. auto operator != (const Meas& other) const -> bool;
  41. auto operator <= (const Meas& other) const -> bool;
  42. auto operator >= (const Meas& other) const -> bool;
  43. };
  44. constexpr double pico_second { 1e-12 }; // value for one pico second in seconds
  45. constexpr double max_plausible_interval { };
  46. inline static auto diff(const SPI::GPX2_TDC::Meas& first, const SPI::GPX2_TDC::Meas& second) -> double{
  47. if (first.status == SPI::GPX2_TDC::Meas::Invalid || second.status == SPI::GPX2_TDC::Meas::Invalid || first.refclk_freq != second.refclk_freq || first.refclk_freq == 0.) {
  48. return std::nan("invalid");// std::cout << "measurement not valid" << std::endl;
  49. }
  50. // int32_t is possible since maximum number of bits in register is 24
  51. int32_t ref0{ static_cast<int32_t>(first.ref_index) };
  52. int32_t ref1{ static_cast<int32_t>(second.ref_index) };
  53. double refclk_period = 1 / first.refclk_freq;
  54. double stop_first = first.lsb_ps * static_cast<double>(first.stop_result);
  55. double stop_second = second.lsb_ps * static_cast<double>(second.stop_result);
  56. double result{};
  57. result = refclk_period * static_cast<double>(ref1 - ref0);
  58. result += (stop_second - stop_first) * pico_second;
  59. return result;
  60. }
  61. inline static auto inPicoseconds(const SPI::GPX2_TDC::Meas& first) -> double{
  62. if (first.status == SPI::GPX2_TDC::Meas::Invalid || first.refclk_freq == 0.){
  63. return std::nan("invalid");// std::cout << "measurement not valid" << std::endl;
  64. }
  65. // int32_t is possible since maximum number of bits in register is 24
  66. // int32_t ref0{ static_cast<int32_t>(first.ref_index) };
  67. // double refclk_period = 1 / first.refclk_freq;
  68. double stop_first = first.lsb_ps * static_cast<double>(first.stop_result);
  69. double result{};
  70. // result = refclk_period * static_cast<double>(ref0);
  71. result = (stop_first) * pico_second;
  72. return result;
  73. }
  74. /*inline double operator-(const Meas& first, const Meas& second){
  75. if (!first || !second || first.refclk_freq != second.refclk_freq || first.refclk_freq==0.){
  76. std::cout << "measurement not valid" << std::endl;
  77. }
  78. double refclk_period = 1/first.refclk_freq;
  79. double stop_first = first.lsb_ps*first.stop_result;
  80. double stop_second = second.lsb_ps*second.stop_result;
  81. double result{};
  82. result = refclk_period*static_cast<double>(second.ref_index - first.ref_index);
  83. result += (stop_second - stop_first)*pico_second;
  84. return result;
  85. }*/
  86. class GPX2 : public spiDevice {
  87. public:
  88. using spiDevice::spiDevice;
  89. void init(std::string busAddress = "/dev/spidev0.0", std::uint32_t speed = 61035, Mode mode = SPI::Mode::spi_mode_1, std::uint8_t bits = 8);
  90. void power_on_reset();
  91. void init_reset();
  92. [[nodiscard]] auto write_config()->bool;
  93. [[nodiscard]] auto write_config(const Config& data)->bool;
  94. [[nodiscard]] auto read_config()->std::string;
  95. [[nodiscard]] auto get_filtered_intervals(double max_interval)->std::vector<double>;
  96. [[nodiscard]] auto read_results()->std::vector<Meas>;
  97. private:
  98. [[nodiscard]] auto write_config(const std::string& data)->bool;
  99. [[nodiscard]] auto write_config(const std::uint8_t reg_addr, const std::uint8_t data)->bool;
  100. [[nodiscard]] auto read_config(const std::uint8_t reg_addr)->std::uint8_t;
  101. std::queue<Meas> readout_buffer;
  102. Config config;
  103. };
  104. }
  105. }
  106. #endif // !GPX2_H