AP_Radio.cpp 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305
  1. #include <AP_HAL/AP_HAL.h>
  2. #if HAL_RCINPUT_WITH_AP_RADIO
  3. #include "AP_Radio.h"
  4. #include "AP_Radio_backend.h"
  5. #include "AP_Radio_cypress.h"
  6. #include "AP_Radio_cc2500.h"
  7. #include "AP_Radio_bk2425.h"
  8. extern const AP_HAL::HAL& hal;
  9. // table of user settable parameters
  10. const AP_Param::GroupInfo AP_Radio::var_info[] = {
  11. // @Param: _TYPE
  12. // @DisplayName: Set type of direct attached radio
  13. // @Description: This enables support for direct attached radio receivers
  14. // @Values: 0:None,1:CYRF6936,2:CC2500,3:BK2425
  15. // @User: Advanced
  16. AP_GROUPINFO("_TYPE", 1, AP_Radio, radio_type, 0),
  17. // @Param: _PROT
  18. // @DisplayName: protocol
  19. // @Description: Select air protocol
  20. // @Values: 0:Auto,1:DSM2,2:DSMX
  21. // @User: Advanced
  22. AP_GROUPINFO("_PROT", 2, AP_Radio, protocol, PROTOCOL_AUTO),
  23. // @Param: _DEBUG
  24. // @DisplayName: debug level
  25. // @Description: radio debug level
  26. // @Range: 0 4
  27. // @User: Advanced
  28. AP_GROUPINFO("_DEBUG", 3, AP_Radio, debug_level, 0),
  29. // @Param: _DISCRC
  30. // @DisplayName: disable receive CRC
  31. // @Description: disable receive CRC (for debug)
  32. // @Values: 0:NotDisabled,1:Disabled
  33. // @User: Advanced
  34. AP_GROUPINFO("_DISCRC", 4, AP_Radio, disable_crc, 0),
  35. // @Param: _SIGCH
  36. // @DisplayName: RSSI signal strength
  37. // @Description: Channel to show receive RSSI signal strength, or zero for disabled
  38. // @Range: 0 16
  39. // @User: Advanced
  40. AP_GROUPINFO("_SIGCH", 5, AP_Radio, rssi_chan, 0),
  41. // @Param: _PPSCH
  42. // @DisplayName: Packet rate channel
  43. // @Description: Channel to show received packet-per-second rate, or zero for disabled
  44. // @Range: 0 16
  45. // @User: Advanced
  46. AP_GROUPINFO("_PPSCH", 6, AP_Radio, pps_chan, 0),
  47. // @Param: _TELEM
  48. // @DisplayName: Enable telemetry
  49. // @Description: If this is non-zero then telemetry packets will be sent over DSM
  50. // @Values: 0:Disabled,1:Enabled
  51. // @User: Advanced
  52. AP_GROUPINFO("_TELEM", 7, AP_Radio, telem_enable, 0),
  53. // @Param: _TXPOW
  54. // @DisplayName: Telemetry Transmit power
  55. // @Description: Set telemetry transmit power. This is the power level (from 1 to 8) for telemetry packets sent from the RX to the TX
  56. // @Range: 1 8
  57. // @User: Advanced
  58. AP_GROUPINFO("_TXPOW", 8, AP_Radio, transmit_power, 8),
  59. // @Param: _FCCTST
  60. // @DisplayName: Put radio into FCC test mode
  61. // @Description: If this is enabled then the radio will continuously transmit as required for FCC testing. The transmit channel is set by the value of the parameter. The radio will not work for RC input while this is enabled
  62. // @Values: 0:Disabled,1:MinChannel,2:MidChannel,3:MaxChannel,4:MinChannelCW,5:MidChannelCW,6:MaxChannelCW
  63. // @User: Advanced
  64. AP_GROUPINFO("_FCCTST", 9, AP_Radio, fcc_test, 0),
  65. // @Param: _STKMD
  66. // @DisplayName: Stick input mode
  67. // @Description: This selects between different stick input modes. The default is mode2, which has throttle on the left stick and pitch on the right stick. You can instead set mode1, which has throttle on the right stick and pitch on the left stick.
  68. // @Values: 1:Mode1,2:Mode2
  69. // @User: Advanced
  70. AP_GROUPINFO("_STKMD", 10, AP_Radio, stick_mode, 2),
  71. // @Param: _TESTCH
  72. // @DisplayName: Set radio to factory test channel
  73. // @Description: This sets the radio to a fixed test channel for factory testing. Using a fixed channel avoids the need for binding in factory testing.
  74. // @Values: 0:Disabled,1:TestChan1,2:TestChan2,3:TestChan3,4:TestChan4,5:TestChan5,6:TestChan6,7:TestChan7,8:TestChan8
  75. // @User: Advanced
  76. AP_GROUPINFO("_TESTCH", 11, AP_Radio, factory_test, 0),
  77. // @Param: _TSIGCH
  78. // @DisplayName: RSSI value channel for telemetry data on transmitter
  79. // @Description: Channel to show telemetry RSSI value as received by TX
  80. // @Range: 0 16
  81. // @User: Advanced
  82. AP_GROUPINFO("_TSIGCH", 12, AP_Radio, tx_rssi_chan, 0),
  83. // @Param: _TPPSCH
  84. // @DisplayName: Telemetry PPS channel
  85. // @Description: Channel to show telemetry packets-per-second value, as received at TX
  86. // @Range: 0 16
  87. // @User: Advanced
  88. AP_GROUPINFO("_TPPSCH", 13, AP_Radio, tx_pps_chan, 0),
  89. // @Param: _TXMAX
  90. // @DisplayName: Transmitter transmit power
  91. // @Description: Set transmitter maximum transmit power (from 1 to 8)
  92. // @Range: 1 8
  93. // @User: Advanced
  94. AP_GROUPINFO("_TXMAX", 14, AP_Radio, tx_max_power, 8),
  95. // @Param: _BZOFS
  96. // @DisplayName: Transmitter buzzer adjustment
  97. // @Description: Set transmitter buzzer note adjustment (adjust frequency up)
  98. // @Range: 0 40
  99. // @User: Advanced
  100. AP_GROUPINFO("_BZOFS", 15, AP_Radio, tx_buzzer_adjust, 25),
  101. // @Param: _ABTIME
  102. // @DisplayName: Auto-bind time
  103. // @Description: When non-zero this sets the time with no transmitter packets before we start looking for auto-bind packets.
  104. // @Range: 0 120
  105. // @User: Advanced
  106. AP_GROUPINFO("_ABTIME", 16, AP_Radio, auto_bind_time, 0),
  107. // @Param: _ABLVL
  108. // @DisplayName: Auto-bind level
  109. // @Description: This sets the minimum RSSI of an auto-bind packet for it to be accepted. This should be set so that auto-bind will only happen at short range to minimise the change of an auto-bind happening accidentially
  110. // @Range: 0 31
  111. // @User: Advanced
  112. AP_GROUPINFO("_ABLVL", 17, AP_Radio, auto_bind_rssi, 0),
  113. AP_GROUPEND
  114. };
  115. AP_Radio *AP_Radio::_singleton;
  116. // constructor
  117. AP_Radio::AP_Radio(void)
  118. {
  119. AP_Param::setup_object_defaults(this, var_info);
  120. if (_singleton != nullptr) {
  121. AP_HAL::panic("Multiple AP_Radio declarations");
  122. }
  123. _singleton = this;
  124. }
  125. bool AP_Radio::init(void)
  126. {
  127. switch (radio_type) {
  128. #if (not defined AP_RADIO_CYRF6936 || AP_RADIO_CYRF6936)
  129. case RADIO_TYPE_CYRF6936:
  130. driver = new AP_Radio_cypress(*this);
  131. break;
  132. #endif
  133. #if CONFIG_HAL_BOARD == HAL_BOARD_CHIBIOS
  134. #if (not defined AP_RADIO_CC2500 || AP_RADIO_CC2500)
  135. case RADIO_TYPE_CC2500:
  136. driver = new AP_Radio_cc2500(*this);
  137. break;
  138. #endif
  139. #endif
  140. #if CONFIG_HAL_BOARD_SUBTYPE == HAL_BOARD_SUBTYPE_CHIBIOS_SKYVIPER_F412
  141. #if (not defined AP_RADIO_BK2425 || AP_RADIO_BK2425)
  142. case RADIO_TYPE_BK2425:
  143. driver = new AP_Radio_beken(*this);
  144. break;
  145. #endif
  146. #endif
  147. #if CONFIG_HAL_BOARD_SUBTYPE == HAL_BOARD_SUBTYPE_CHIBIOS_SKYVIPER_F412
  148. case RADIO_TYPE_AUTO:
  149. // auto-detect between cc2500 and beken radios
  150. #if (not defined AP_RADIO_CC2500 || AP_RADIO_CC2500)
  151. if (AP_Radio_cc2500::probe()) {
  152. driver = new AP_Radio_cc2500(*this);
  153. }
  154. #endif
  155. #if (not defined AP_RADIO_BK2425 || AP_RADIO_BK2425)
  156. if (driver == nullptr) {
  157. driver = new AP_Radio_beken(*this);
  158. }
  159. #endif
  160. break;
  161. #endif
  162. default:
  163. break;
  164. }
  165. if (!driver) {
  166. return false;
  167. }
  168. return driver->init();
  169. }
  170. bool AP_Radio::reset(void)
  171. {
  172. if (!driver) {
  173. return false;
  174. }
  175. return driver->reset();
  176. }
  177. bool AP_Radio::send(const uint8_t *pkt, uint16_t len)
  178. {
  179. if (!driver) {
  180. return false;
  181. }
  182. return driver->send(pkt, len);
  183. }
  184. void AP_Radio::start_recv_bind(void)
  185. {
  186. if (!driver) {
  187. return;
  188. }
  189. return driver->start_recv_bind();
  190. }
  191. const AP_Radio::stats &AP_Radio::get_stats(void)
  192. {
  193. return driver->get_stats();
  194. }
  195. uint8_t AP_Radio::num_channels(void)
  196. {
  197. if (!driver) {
  198. return 0;
  199. }
  200. return driver->num_channels();
  201. }
  202. uint16_t AP_Radio::read(uint8_t chan)
  203. {
  204. if (!driver) {
  205. return 0;
  206. }
  207. return driver->read(chan);
  208. }
  209. uint32_t AP_Radio::last_recv_us(void)
  210. {
  211. if (!driver) {
  212. return 0;
  213. }
  214. return driver->last_recv_us();
  215. }
  216. // handle a data96 mavlink packet for fw upload
  217. void AP_Radio::handle_data_packet(mavlink_channel_t chan, const mavlink_data96_t &m)
  218. {
  219. if (driver) {
  220. driver->handle_data_packet(chan, m);
  221. }
  222. }
  223. // play a tune on the TX
  224. void AP_Radio::play_tune(const char *tune_str)
  225. {
  226. mavlink_data96_t pkt {};
  227. uint8_t len = MIN(strlen(tune_str), 92);
  228. pkt.len = len;
  229. pkt.type = 43;
  230. memcpy(&pkt.data[0], tune_str, len);
  231. handle_data_packet(MAVLINK_COMM_0, pkt);
  232. }
  233. // update status, should be called from main thread
  234. void AP_Radio::update(void)
  235. {
  236. if (driver) {
  237. driver->update();
  238. }
  239. }
  240. // get transmitter firmware version
  241. uint32_t AP_Radio::get_tx_version(void)
  242. {
  243. if (driver) {
  244. return driver->get_tx_version();
  245. }
  246. return 0;
  247. }
  248. // set the 2.4GHz wifi channel used by companion computer, so it can be avoided
  249. void AP_Radio::set_wifi_channel(uint8_t channel)
  250. {
  251. if (driver) {
  252. driver->set_wifi_channel(channel);
  253. }
  254. }
  255. // change TX mode, toggling between mode1 and mode2
  256. void AP_Radio::change_txmode(void)
  257. {
  258. if (stick_mode == 2) {
  259. stick_mode.set_and_save_ifchanged(1);
  260. } else {
  261. stick_mode.set_and_save_ifchanged(2);
  262. }
  263. }
  264. #endif // HAL_RCINPUT_WITH_AP_RADIO