AP_Baro_UAVCAN.cpp 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168
  1. #include <AP_HAL/AP_HAL.h>
  2. #if HAL_WITH_UAVCAN
  3. #include "AP_Baro_UAVCAN.h"
  4. #include <AP_BoardConfig/AP_BoardConfig_CAN.h>
  5. #include <AP_UAVCAN/AP_UAVCAN.h>
  6. #include <uavcan/equipment/air_data/StaticPressure.hpp>
  7. #include <uavcan/equipment/air_data/StaticTemperature.hpp>
  8. extern const AP_HAL::HAL& hal;
  9. #define debug_baro_uavcan(level_debug, can_driver, fmt, args...) do { if ((level_debug) <= AP::can().get_debug_level_driver(can_driver)) { printf(fmt, ##args); }} while (0)
  10. //UAVCAN Frontend Registry Binder
  11. UC_REGISTRY_BINDER(PressureCb, uavcan::equipment::air_data::StaticPressure);
  12. UC_REGISTRY_BINDER(TemperatureCb, uavcan::equipment::air_data::StaticTemperature);
  13. AP_Baro_UAVCAN::DetectedModules AP_Baro_UAVCAN::_detected_modules[] = {0};
  14. HAL_Semaphore AP_Baro_UAVCAN::_sem_registry;
  15. /*
  16. constructor - registers instance at top Baro driver
  17. */
  18. AP_Baro_UAVCAN::AP_Baro_UAVCAN(AP_Baro &baro) :
  19. AP_Baro_Backend(baro)
  20. {}
  21. void AP_Baro_UAVCAN::subscribe_msgs(AP_UAVCAN* ap_uavcan)
  22. {
  23. if (ap_uavcan == nullptr) {
  24. return;
  25. }
  26. auto* node = ap_uavcan->get_node();
  27. uavcan::Subscriber<uavcan::equipment::air_data::StaticPressure, PressureCb> *pressure_listener;
  28. pressure_listener = new uavcan::Subscriber<uavcan::equipment::air_data::StaticPressure, PressureCb>(*node);
  29. // Msg Handler
  30. const int pressure_listener_res = pressure_listener->start(PressureCb(ap_uavcan, &handle_pressure));
  31. if (pressure_listener_res < 0) {
  32. AP_HAL::panic("UAVCAN Baro subscriber start problem\n\r");
  33. return;
  34. }
  35. uavcan::Subscriber<uavcan::equipment::air_data::StaticTemperature, TemperatureCb> *temperature_listener;
  36. temperature_listener = new uavcan::Subscriber<uavcan::equipment::air_data::StaticTemperature, TemperatureCb>(*node);
  37. // Msg Handler
  38. const int temperature_listener_res = temperature_listener->start(TemperatureCb(ap_uavcan, &handle_temperature));
  39. if (temperature_listener_res < 0) {
  40. AP_HAL::panic("UAVCAN Baro subscriber start problem\n\r");
  41. return;
  42. }
  43. }
  44. AP_Baro_Backend* AP_Baro_UAVCAN::probe(AP_Baro &baro)
  45. {
  46. WITH_SEMAPHORE(_sem_registry);
  47. AP_Baro_UAVCAN* backend = nullptr;
  48. for (uint8_t i = 0; i < BARO_MAX_DRIVERS; i++) {
  49. if (_detected_modules[i].driver == nullptr && _detected_modules[i].ap_uavcan != nullptr) {
  50. backend = new AP_Baro_UAVCAN(baro);
  51. if (backend == nullptr) {
  52. debug_baro_uavcan(2,
  53. _detected_modules[i].ap_uavcan->get_driver_index(),
  54. "Failed register UAVCAN Baro Node %d on Bus %d\n",
  55. _detected_modules[i].node_id,
  56. _detected_modules[i].ap_uavcan->get_driver_index());
  57. } else {
  58. _detected_modules[i].driver = backend;
  59. backend->_ap_uavcan = _detected_modules[i].ap_uavcan;
  60. backend->_node_id = _detected_modules[i].node_id;
  61. backend->register_sensor();
  62. debug_baro_uavcan(2,
  63. _detected_modules[i].ap_uavcan->get_driver_index(),
  64. "Registered UAVCAN Baro Node %d on Bus %d\n",
  65. _detected_modules[i].node_id,
  66. _detected_modules[i].ap_uavcan->get_driver_index());
  67. }
  68. break;
  69. }
  70. }
  71. return backend;
  72. }
  73. AP_Baro_UAVCAN* AP_Baro_UAVCAN::get_uavcan_backend(AP_UAVCAN* ap_uavcan, uint8_t node_id, bool create_new)
  74. {
  75. if (ap_uavcan == nullptr) {
  76. return nullptr;
  77. }
  78. for (uint8_t i = 0; i < BARO_MAX_DRIVERS; i++) {
  79. if (_detected_modules[i].driver != nullptr &&
  80. _detected_modules[i].ap_uavcan == ap_uavcan &&
  81. _detected_modules[i].node_id == node_id) {
  82. return _detected_modules[i].driver;
  83. }
  84. }
  85. if (create_new) {
  86. bool already_detected = false;
  87. //Check if there's an empty spot for possible registeration
  88. for (uint8_t i = 0; i < BARO_MAX_DRIVERS; i++) {
  89. if (_detected_modules[i].ap_uavcan == ap_uavcan && _detected_modules[i].node_id == node_id) {
  90. //Already Detected
  91. already_detected = true;
  92. break;
  93. }
  94. }
  95. if (!already_detected) {
  96. for (uint8_t i = 0; i < BARO_MAX_DRIVERS; i++) {
  97. if (_detected_modules[i].ap_uavcan == nullptr) {
  98. _detected_modules[i].ap_uavcan = ap_uavcan;
  99. _detected_modules[i].node_id = node_id;
  100. break;
  101. }
  102. }
  103. }
  104. }
  105. return nullptr;
  106. }
  107. void AP_Baro_UAVCAN::handle_pressure(AP_UAVCAN* ap_uavcan, uint8_t node_id, const PressureCb &cb)
  108. {
  109. WITH_SEMAPHORE(_sem_registry);
  110. AP_Baro_UAVCAN* driver = get_uavcan_backend(ap_uavcan, node_id, true);
  111. if (driver == nullptr) {
  112. return;
  113. }
  114. {
  115. WITH_SEMAPHORE(driver->_sem_baro);
  116. driver->_pressure = cb.msg->static_pressure;
  117. driver->new_pressure = true;
  118. }
  119. }
  120. void AP_Baro_UAVCAN::handle_temperature(AP_UAVCAN* ap_uavcan, uint8_t node_id, const TemperatureCb &cb)
  121. {
  122. WITH_SEMAPHORE(_sem_registry);
  123. AP_Baro_UAVCAN* driver = get_uavcan_backend(ap_uavcan, node_id, false);
  124. if (driver == nullptr) {
  125. return;
  126. }
  127. {
  128. WITH_SEMAPHORE(driver->_sem_baro);
  129. driver->_temperature = cb.msg->static_temperature - C_TO_KELVIN;
  130. }
  131. }
  132. // Read the sensor
  133. void AP_Baro_UAVCAN::update(void)
  134. {
  135. WITH_SEMAPHORE(_sem_baro);
  136. if (new_pressure) {
  137. _copy_to_frontend(_instance, _pressure, _temperature);
  138. _frontend.set_external_temperature(_temperature);
  139. new_pressure = false;
  140. }
  141. }
  142. #endif // HAL_WITH_UAVCAN