AP_BoardConfig_CAN.cpp 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210
  1. /*
  2. This program is free software: you can redistribute it and/or modify
  3. it under the terms of the GNU General Public License as published by
  4. the Free Software Foundation, either version 3 of the License, or
  5. (at your option) any later version.
  6. This program is distributed in the hope that it will be useful,
  7. but WITHOUT ANY WARRANTY; without even the implied warranty of
  8. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  9. GNU General Public License for more details.
  10. You should have received a copy of the GNU General Public License
  11. along with this program. If not, see <http://www.gnu.org/licenses/>.
  12. */
  13. /*
  14. * AP_BoardConfig_CAN - board specific configuration for CAN interface
  15. */
  16. #include <AP_HAL/AP_HAL.h>
  17. #include <AP_Common/AP_Common.h>
  18. #include "AP_BoardConfig.h"
  19. #include "AP_BoardConfig_CAN.h"
  20. #if HAL_WITH_UAVCAN
  21. #if CONFIG_HAL_BOARD == HAL_BOARD_LINUX
  22. #include <AP_HAL_Linux/CAN.h>
  23. #elif CONFIG_HAL_BOARD == HAL_BOARD_CHIBIOS
  24. #include <AP_HAL_ChibiOS/CAN.h>
  25. #include <AP_HAL_ChibiOS/CANSerialRouter.h>
  26. #endif
  27. #include <AP_Vehicle/AP_Vehicle.h>
  28. #include <AP_UAVCAN/AP_UAVCAN_SLCAN.h>
  29. #include <AP_UAVCAN/AP_UAVCAN.h>
  30. #include <AP_KDECAN/AP_KDECAN.h>
  31. #include <AP_ToshibaCAN/AP_ToshibaCAN.h>
  32. #include <AP_SerialManager/AP_SerialManager.h>
  33. extern const AP_HAL::HAL& hal;
  34. // table of user settable parameters
  35. const AP_Param::GroupInfo AP_BoardConfig_CAN::var_info[] = {
  36. #if MAX_NUMBER_OF_CAN_INTERFACES > 0
  37. // @Group: P1_
  38. // @Path: ../AP_BoardConfig/canbus_interface.cpp
  39. AP_SUBGROUPINFO(_interfaces[0], "P1_", 1, AP_BoardConfig_CAN, AP_BoardConfig_CAN::Interface),
  40. #endif
  41. #if MAX_NUMBER_OF_CAN_INTERFACES > 1
  42. // @Group: P2_
  43. // @Path: ../AP_BoardConfig/canbus_interface.cpp
  44. AP_SUBGROUPINFO(_interfaces[1], "P2_", 2, AP_BoardConfig_CAN, AP_BoardConfig_CAN::Interface),
  45. #endif
  46. #if MAX_NUMBER_OF_CAN_INTERFACES > 2
  47. // @Group: P3_
  48. // @Path: ../AP_BoardConfig/canbus_interface.cpp
  49. AP_SUBGROUPINFO(_interfaces[2], "P3_", 3, AP_BoardConfig_CAN, AP_BoardConfig_CAN::Interface),
  50. #endif
  51. #if MAX_NUMBER_OF_CAN_DRIVERS > 0
  52. // @Group: D1_
  53. // @Path: ../AP_BoardConfig/canbus_driver.cpp
  54. AP_SUBGROUPINFO(_drivers[0], "D1_", 4, AP_BoardConfig_CAN, AP_BoardConfig_CAN::Driver),
  55. #endif
  56. #if MAX_NUMBER_OF_CAN_DRIVERS > 1
  57. // @Group: D2_
  58. // @Path: ../AP_BoardConfig/canbus_driver.cpp
  59. AP_SUBGROUPINFO(_drivers[1], "D2_", 5, AP_BoardConfig_CAN, AP_BoardConfig_CAN::Driver),
  60. #endif
  61. #if MAX_NUMBER_OF_CAN_DRIVERS > 2
  62. // @Group: D3_
  63. // @Path: ../AP_BoardConfig/canbus_driver.cpp
  64. AP_SUBGROUPINFO(_drivers[2], "D3_", 6, AP_BoardConfig_CAN, AP_BoardConfig_CAN::Driver),
  65. #endif
  66. #if AP_UAVCAN_SLCAN_ENABLED
  67. // @Group: SLCAN_
  68. // @Path: ../AP_BoardConfig/canbus_slcan.cpp
  69. AP_SUBGROUPINFO(_slcan, "SLCAN_", 7, AP_BoardConfig_CAN, AP_BoardConfig_CAN::SLCAN_Interface),
  70. #endif
  71. AP_GROUPEND
  72. };
  73. AP_BoardConfig_CAN *AP_BoardConfig_CAN::_singleton;
  74. AP_BoardConfig_CAN::AP_BoardConfig_CAN()
  75. {
  76. AP_Param::setup_object_defaults(this, var_info);
  77. #if CONFIG_HAL_BOARD == HAL_BOARD_SITL
  78. if (_singleton != nullptr) {
  79. AP_HAL::panic("AP_BoardConfig_CAN must be singleton");
  80. }
  81. #endif // CONFIG_HAL_BOARD == HAL_BOARD_SITL
  82. _singleton = this;
  83. }
  84. void AP_BoardConfig_CAN::init()
  85. {
  86. // Create all drivers that we need
  87. bool initret = true;
  88. #if AP_UAVCAN_SLCAN_ENABLED
  89. reset_slcan_serial();
  90. #endif
  91. for (uint8_t i = 0; i < MAX_NUMBER_OF_CAN_INTERFACES; i++) {
  92. // Check the driver number assigned to this physical interface
  93. uint8_t drv_num = _interfaces[i]._driver_number_cache = _interfaces[i]._driver_number;
  94. if (drv_num != 0 && drv_num <= MAX_NUMBER_OF_CAN_DRIVERS) {
  95. if (hal.can_mgr[drv_num - 1] == nullptr) {
  96. // CAN Manager is the driver
  97. // So if this driver was not created before for other physical interface - do it
  98. #if CONFIG_HAL_BOARD == HAL_BOARD_LINUX
  99. const_cast <AP_HAL::HAL&> (hal).can_mgr[drv_num - 1] = new Linux::CANManager;
  100. #elif CONFIG_HAL_BOARD == HAL_BOARD_CHIBIOS
  101. const_cast <AP_HAL::HAL&> (hal).can_mgr[drv_num - 1] = new ChibiOS::CANManager;
  102. #endif
  103. }
  104. // For this now existing driver (manager), start the physical interface
  105. if (hal.can_mgr[drv_num - 1] != nullptr) {
  106. initret = initret && hal.can_mgr[drv_num - 1]->begin(_interfaces[i]._bitrate, i);
  107. #if AP_UAVCAN_SLCAN_ENABLED
  108. if (_slcan._can_port == (i+1) && hal.can_mgr[drv_num - 1] != nullptr ) {
  109. ChibiOS_CAN::CanDriver* drv = (ChibiOS_CAN::CanDriver*)hal.can_mgr[drv_num - 1]->get_driver();
  110. ChibiOS_CAN::CanIface::slcan_router().init(drv->getIface(i), drv->getUpdateEvent());
  111. }
  112. #endif
  113. } else {
  114. printf("Failed to initialize can interface %d\n\r", i + 1);
  115. }
  116. }
  117. }
  118. if (initret) {
  119. for (uint8_t i = 0; i < MAX_NUMBER_OF_CAN_DRIVERS; i++) {
  120. Protocol_Type prot_type = _drivers[i]._protocol_type_cache = (Protocol_Type) _drivers[i]._protocol_type.get();
  121. if (hal.can_mgr[i] == nullptr) {
  122. continue;
  123. }
  124. _num_drivers = i + 1;
  125. hal.can_mgr[i]->initialized(true);
  126. printf("can_mgr %d initialized well\n\r", i + 1);
  127. if (prot_type == Protocol_Type_UAVCAN) {
  128. _drivers[i]._driver = _drivers[i]._uavcan = new AP_UAVCAN;
  129. if (_drivers[i]._driver == nullptr) {
  130. AP_HAL::panic("Failed to allocate uavcan %d\n\r", i + 1);
  131. continue;
  132. }
  133. AP_Param::load_object_from_eeprom(_drivers[i]._uavcan, AP_UAVCAN::var_info);
  134. } else if (prot_type == Protocol_Type_KDECAN) {
  135. // To be replaced with macro saying if KDECAN library is included
  136. #if APM_BUILD_TYPE(APM_BUILD_ArduCopter) || APM_BUILD_TYPE(APM_BUILD_ArduPlane) || APM_BUILD_TYPE(APM_BUILD_ArduSub)
  137. _drivers[i]._driver = _drivers[i]._kdecan = new AP_KDECAN;
  138. if (_drivers[i]._driver == nullptr) {
  139. AP_HAL::panic("Failed to allocate KDECAN %d\n\r", i + 1);
  140. continue;
  141. }
  142. AP_Param::load_object_from_eeprom(_drivers[i]._kdecan, AP_KDECAN::var_info);
  143. #endif
  144. } else if (prot_type == Protocol_Type_ToshibaCAN) {
  145. _drivers[i]._driver = _drivers[i]._tcan = new AP_ToshibaCAN;
  146. if (_drivers[i]._driver == nullptr) {
  147. AP_BoardConfig::sensor_config_error("ToshibaCAN init failed");
  148. continue;
  149. }
  150. } else {
  151. continue;
  152. }
  153. #if AP_UAVCAN_SLCAN_ENABLED
  154. if (_slcan._can_port == 0) {
  155. _drivers[i]._driver->init(i, true);
  156. } else {
  157. _drivers[i]._driver->init(i, false);
  158. }
  159. #endif
  160. }
  161. }
  162. }
  163. #if AP_UAVCAN_SLCAN_ENABLED
  164. AP_HAL::UARTDriver *AP_BoardConfig_CAN::get_slcan_serial()
  165. {
  166. if (_slcan._ser_port != -1) {
  167. return AP::serialmanager().get_serial_by_id(_slcan._ser_port);
  168. }
  169. AP_HAL::UARTDriver *ser_port = AP::serialmanager().find_serial(AP_SerialManager::SerialProtocol_SLCAN, 0);
  170. if (ser_port != nullptr) {
  171. if (ser_port->is_initialized()) {
  172. return ser_port;
  173. }
  174. }
  175. return nullptr;
  176. }
  177. #endif
  178. AP_BoardConfig_CAN& AP::can() {
  179. return *AP_BoardConfig_CAN::get_singleton();
  180. }
  181. #endif