RCInput.cpp 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559
  1. #include <errno.h>
  2. #include <fcntl.h>
  3. #include <poll.h>
  4. #include <stdint.h>
  5. #include <stdio.h>
  6. #include <stdlib.h>
  7. #include <string.h>
  8. #include <sys/mman.h>
  9. #include <sys/stat.h>
  10. #include <sys/time.h>
  11. #include <unistd.h>
  12. #include <AP_HAL/AP_HAL.h>
  13. #include <AP_HAL/utility/dsm.h>
  14. #include <AP_HAL/utility/sumd.h>
  15. #include <AP_HAL/utility/st24.h>
  16. #include <AP_HAL/utility/srxl.h>
  17. #include "RCInput.h"
  18. #include "sbus.h"
  19. #define MIN_NUM_CHANNELS 5
  20. extern const AP_HAL::HAL& hal;
  21. using namespace Linux;
  22. RCInput::RCInput()
  23. {
  24. ppm_state._channel_counter = -1;
  25. }
  26. void RCInput::init()
  27. {
  28. }
  29. bool RCInput::new_input()
  30. {
  31. bool ret = rc_input_count != last_rc_input_count;
  32. if (ret) {
  33. last_rc_input_count.store(rc_input_count);
  34. }
  35. return ret;
  36. }
  37. uint8_t RCInput::num_channels()
  38. {
  39. return _num_channels;
  40. }
  41. void RCInput::set_num_channels(uint8_t num)
  42. {
  43. _num_channels = num;
  44. }
  45. uint16_t RCInput::read(uint8_t ch)
  46. {
  47. if (ch >= _num_channels) {
  48. return 0;
  49. }
  50. return _pwm_values[ch];
  51. }
  52. uint8_t RCInput::read(uint16_t* periods, uint8_t len)
  53. {
  54. uint8_t i;
  55. for (i=0; i<len; i++) {
  56. periods[i] = read(i);
  57. }
  58. return len;
  59. }
  60. /*
  61. process a PPM-sum pulse of the given width
  62. */
  63. void RCInput::_process_ppmsum_pulse(uint16_t width_usec)
  64. {
  65. if (width_usec >= 2700) {
  66. // a long pulse indicates the end of a frame. Reset the
  67. // channel counter so next pulse is channel 0
  68. if (ppm_state._channel_counter >= MIN_NUM_CHANNELS) {
  69. for (uint8_t i=0; i<ppm_state._channel_counter; i++) {
  70. _pwm_values[i] = ppm_state._pulse_capt[i];
  71. }
  72. _num_channels = ppm_state._channel_counter;
  73. rc_input_count++;
  74. }
  75. ppm_state._channel_counter = 0;
  76. return;
  77. }
  78. if (ppm_state._channel_counter == -1) {
  79. // we are not synchronised
  80. return;
  81. }
  82. /*
  83. we limit inputs to between 700usec and 2300usec. This allows us
  84. to decode SBUS on the same pin, as SBUS will have a maximum
  85. pulse width of 100usec
  86. */
  87. if (width_usec > 700 && width_usec < 2300) {
  88. // take a reading for the current channel
  89. // buffer these
  90. ppm_state._pulse_capt[ppm_state._channel_counter] = width_usec;
  91. // move to next channel
  92. ppm_state._channel_counter++;
  93. }
  94. // if we have reached the maximum supported channels then
  95. // mark as unsynchronised, so we wait for a wide pulse
  96. if (ppm_state._channel_counter >= LINUX_RC_INPUT_NUM_CHANNELS) {
  97. for (uint8_t i=0; i<ppm_state._channel_counter; i++) {
  98. _pwm_values[i] = ppm_state._pulse_capt[i];
  99. }
  100. _num_channels = ppm_state._channel_counter;
  101. rc_input_count++;
  102. ppm_state._channel_counter = -1;
  103. }
  104. }
  105. /*
  106. process a SBUS input pulse of the given width
  107. */
  108. void RCInput::_process_sbus_pulse(uint16_t width_s0, uint16_t width_s1)
  109. {
  110. // convert to bit widths, allowing for up to 1usec error, assuming 100000 bps
  111. uint16_t bits_s0 = (width_s0+1) / 10;
  112. uint16_t bits_s1 = (width_s1+1) / 10;
  113. uint16_t nlow;
  114. uint8_t byte_ofs = sbus_state.bit_ofs/12;
  115. uint8_t bit_ofs = sbus_state.bit_ofs%12;
  116. if (bits_s0 == 0 || bits_s1 == 0) {
  117. // invalid data
  118. goto reset;
  119. }
  120. if (bits_s0+bit_ofs > 10) {
  121. // invalid data as last two bits must be stop bits
  122. goto reset;
  123. }
  124. // pull in the high bits
  125. sbus_state.bytes[byte_ofs] |= ((1U<<bits_s0)-1) << bit_ofs;
  126. sbus_state.bit_ofs += bits_s0;
  127. bit_ofs += bits_s0;
  128. // pull in the low bits
  129. nlow = bits_s1;
  130. if (nlow + bit_ofs > 12) {
  131. nlow = 12 - bit_ofs;
  132. }
  133. bits_s1 -= nlow;
  134. sbus_state.bit_ofs += nlow;
  135. if (sbus_state.bit_ofs == 25*12 && bits_s1 > 12) {
  136. // we have a full frame
  137. uint8_t bytes[25];
  138. uint8_t i;
  139. for (i=0; i<25; i++) {
  140. // get inverted data
  141. uint16_t v = ~sbus_state.bytes[i];
  142. // check start bit
  143. if ((v & 1) != 0) {
  144. goto reset;
  145. }
  146. // check stop bits
  147. if ((v & 0xC00) != 0xC00) {
  148. goto reset;
  149. }
  150. // check parity
  151. uint8_t parity = 0, j;
  152. for (j=1; j<=8; j++) {
  153. parity ^= (v & (1U<<j))?1:0;
  154. }
  155. if (parity != (v&0x200)>>9) {
  156. goto reset;
  157. }
  158. bytes[i] = ((v>>1) & 0xFF);
  159. }
  160. uint16_t values[LINUX_RC_INPUT_NUM_CHANNELS];
  161. uint16_t num_values=0;
  162. bool sbus_failsafe=false, sbus_frame_drop=false;
  163. if (sbus_decode(bytes, values, &num_values,
  164. &sbus_failsafe, &sbus_frame_drop,
  165. LINUX_RC_INPUT_NUM_CHANNELS) &&
  166. num_values >= MIN_NUM_CHANNELS) {
  167. for (i=0; i<num_values; i++) {
  168. _pwm_values[i] = values[i];
  169. }
  170. _num_channels = num_values;
  171. if (!sbus_failsafe) {
  172. rc_input_count++;
  173. }
  174. }
  175. goto reset;
  176. } else if (bits_s1 > 12) {
  177. // break
  178. goto reset;
  179. }
  180. return;
  181. reset:
  182. memset(&sbus_state, 0, sizeof(sbus_state));
  183. }
  184. void RCInput::_process_dsm_pulse(uint16_t width_s0, uint16_t width_s1)
  185. {
  186. // convert to bit widths, allowing for up to 1usec error, assuming 115200 bps
  187. uint16_t bits_s0 = ((width_s0+4)*(uint32_t)115200) / 1000000;
  188. uint16_t bits_s1 = ((width_s1+4)*(uint32_t)115200) / 1000000;
  189. uint8_t bit_ofs, byte_ofs;
  190. uint16_t nbits;
  191. if (bits_s0 == 0 || bits_s1 == 0) {
  192. // invalid data
  193. goto reset;
  194. }
  195. byte_ofs = dsm_state.bit_ofs/10;
  196. bit_ofs = dsm_state.bit_ofs%10;
  197. if(byte_ofs > 15) {
  198. // invalid data
  199. goto reset;
  200. }
  201. // pull in the high bits
  202. nbits = bits_s0;
  203. if (nbits+bit_ofs > 10) {
  204. nbits = 10 - bit_ofs;
  205. }
  206. dsm_state.bytes[byte_ofs] |= ((1U<<nbits)-1) << bit_ofs;
  207. dsm_state.bit_ofs += nbits;
  208. bit_ofs += nbits;
  209. if (bits_s0 - nbits > 10) {
  210. if (dsm_state.bit_ofs == 16*10) {
  211. // we have a full frame
  212. uint8_t bytes[16];
  213. uint8_t i;
  214. for (i=0; i<16; i++) {
  215. // get raw data
  216. uint16_t v = dsm_state.bytes[i];
  217. // check start bit
  218. if ((v & 1) != 0) {
  219. goto reset;
  220. }
  221. // check stop bits
  222. if ((v & 0x200) != 0x200) {
  223. goto reset;
  224. }
  225. bytes[i] = ((v>>1) & 0xFF);
  226. }
  227. uint16_t values[8];
  228. uint16_t num_values=0;
  229. if (dsm_decode(AP_HAL::micros64(), bytes, values, &num_values, 8) &&
  230. num_values >= MIN_NUM_CHANNELS) {
  231. for (i=0; i<num_values; i++) {
  232. _pwm_values[i] = values[i];
  233. }
  234. _num_channels = num_values;
  235. rc_input_count++;
  236. }
  237. }
  238. memset(&dsm_state, 0, sizeof(dsm_state));
  239. }
  240. byte_ofs = dsm_state.bit_ofs/10;
  241. bit_ofs = dsm_state.bit_ofs%10;
  242. if (bits_s1+bit_ofs > 10) {
  243. // invalid data
  244. goto reset;
  245. }
  246. // pull in the low bits
  247. dsm_state.bit_ofs += bits_s1;
  248. return;
  249. reset:
  250. memset(&dsm_state, 0, sizeof(dsm_state));
  251. }
  252. void RCInput::_process_pwm_pulse(uint16_t channel, uint16_t width_s0, uint16_t width_s1)
  253. {
  254. if (channel < _num_channels) {
  255. _pwm_values[channel] = width_s1; // range: 700usec ~ 2300usec
  256. rc_input_count++;
  257. }
  258. }
  259. /*
  260. process a RC input pulse of the given width
  261. */
  262. void RCInput::_process_rc_pulse(uint16_t width_s0, uint16_t width_s1)
  263. {
  264. #if 0
  265. // useful for debugging
  266. static FILE *rclog;
  267. if (rclog == nullptr) {
  268. rclog = fopen("/tmp/rcin.log", "w");
  269. }
  270. if (rclog) {
  271. fprintf(rclog, "%u %u\n", (unsigned)width_s0, (unsigned)width_s1);
  272. }
  273. #endif
  274. // treat as PPM-sum
  275. _process_ppmsum_pulse(width_s0 + width_s1);
  276. // treat as SBUS
  277. _process_sbus_pulse(width_s0, width_s1);
  278. // treat as DSM
  279. _process_dsm_pulse(width_s0, width_s1);
  280. }
  281. /*
  282. * Update channel values directly
  283. */
  284. void RCInput::_update_periods(uint16_t *periods, uint8_t len)
  285. {
  286. if (len > LINUX_RC_INPUT_NUM_CHANNELS) {
  287. len = LINUX_RC_INPUT_NUM_CHANNELS;
  288. }
  289. for (unsigned int i=0; i < len; i++) {
  290. _pwm_values[i] = periods[i];
  291. }
  292. _num_channels = len;
  293. rc_input_count++;
  294. }
  295. /*
  296. add some bytes of input in DSM serial stream format, coping with partial packets
  297. */
  298. bool RCInput::add_dsm_input(const uint8_t *bytes, size_t nbytes)
  299. {
  300. if (nbytes == 0) {
  301. return false;
  302. }
  303. const uint8_t dsm_frame_size = sizeof(dsm.frame);
  304. bool ret = false;
  305. uint32_t now = AP_HAL::millis();
  306. if (now - dsm.last_input_ms > 5) {
  307. // resync based on time
  308. dsm.partial_frame_count = 0;
  309. }
  310. dsm.last_input_ms = now;
  311. while (nbytes > 0) {
  312. size_t n = nbytes;
  313. if (dsm.partial_frame_count + n > dsm_frame_size) {
  314. n = dsm_frame_size - dsm.partial_frame_count;
  315. }
  316. if (n > 0) {
  317. memcpy(&dsm.frame[dsm.partial_frame_count], bytes, n);
  318. dsm.partial_frame_count += n;
  319. nbytes -= n;
  320. bytes += n;
  321. }
  322. if (dsm.partial_frame_count == dsm_frame_size) {
  323. dsm.partial_frame_count = 0;
  324. uint16_t values[16] {};
  325. uint16_t num_values=0;
  326. /*
  327. we only accept input when nbytes==0 as dsm is highly
  328. sensitive to framing, and extra bytes may be an
  329. indication this is really SRXL
  330. */
  331. if (dsm_decode(AP_HAL::micros64(), dsm.frame, values, &num_values, 16) &&
  332. num_values >= MIN_NUM_CHANNELS &&
  333. nbytes == 0) {
  334. for (uint8_t i=0; i<num_values; i++) {
  335. if (values[i] != 0) {
  336. _pwm_values[i] = values[i];
  337. }
  338. }
  339. /*
  340. the apparent number of channels can change on DSM,
  341. as they are spread across multiple frames. We just
  342. use the max num_values we get
  343. */
  344. if (num_values > _num_channels) {
  345. _num_channels = num_values;
  346. }
  347. rc_input_count++;
  348. #if 0
  349. printf("Decoded DSM %u channels %u %u %u %u %u %u %u %u\n",
  350. (unsigned)num_values,
  351. values[0], values[1], values[2], values[3], values[4], values[5], values[6], values[7]);
  352. #endif
  353. ret = true;
  354. }
  355. }
  356. }
  357. return ret;
  358. }
  359. /*
  360. add some bytes of input in SUMD serial stream format, coping with partial packets
  361. */
  362. bool RCInput::add_sumd_input(const uint8_t *bytes, size_t nbytes)
  363. {
  364. uint16_t values[LINUX_RC_INPUT_NUM_CHANNELS];
  365. uint8_t rssi;
  366. uint8_t rx_count;
  367. uint16_t channel_count;
  368. bool ret = false;
  369. while (nbytes > 0) {
  370. if (sumd_decode(*bytes++, &rssi, &rx_count, &channel_count, values, LINUX_RC_INPUT_NUM_CHANNELS) == 0) {
  371. if (channel_count > LINUX_RC_INPUT_NUM_CHANNELS) {
  372. continue;
  373. }
  374. for (uint8_t i=0; i<channel_count; i++) {
  375. if (values[i] != 0) {
  376. _pwm_values[i] = values[i];
  377. }
  378. }
  379. _num_channels = channel_count;
  380. rc_input_count++;
  381. ret = true;
  382. _rssi = rssi;
  383. }
  384. nbytes--;
  385. }
  386. return ret;
  387. }
  388. /*
  389. add some bytes of input in ST24 serial stream format, coping with partial packets
  390. */
  391. bool RCInput::add_st24_input(const uint8_t *bytes, size_t nbytes)
  392. {
  393. uint16_t values[LINUX_RC_INPUT_NUM_CHANNELS];
  394. uint8_t rssi;
  395. uint8_t rx_count;
  396. uint16_t channel_count;
  397. bool ret = false;
  398. while (nbytes > 0) {
  399. if (st24_decode(*bytes++, &rssi, &rx_count, &channel_count, values, LINUX_RC_INPUT_NUM_CHANNELS) == 0) {
  400. if (channel_count > LINUX_RC_INPUT_NUM_CHANNELS) {
  401. continue;
  402. }
  403. for (uint8_t i=0; i<channel_count; i++) {
  404. if (values[i] != 0) {
  405. _pwm_values[i] = values[i];
  406. }
  407. }
  408. _num_channels = channel_count;
  409. rc_input_count++;
  410. ret = true;
  411. _rssi = rssi;
  412. }
  413. nbytes--;
  414. }
  415. return ret;
  416. }
  417. /*
  418. add some bytes of input in SRXL serial stream format, coping with partial packets
  419. */
  420. bool RCInput::add_srxl_input(const uint8_t *bytes, size_t nbytes)
  421. {
  422. uint16_t values[LINUX_RC_INPUT_NUM_CHANNELS];
  423. uint8_t channel_count;
  424. uint64_t now = AP_HAL::micros64();
  425. bool ret = false;
  426. bool failsafe_state;
  427. while (nbytes > 0) {
  428. if (srxl_decode(now, *bytes++, &channel_count, values, LINUX_RC_INPUT_NUM_CHANNELS, &failsafe_state) == 0) {
  429. if (channel_count > LINUX_RC_INPUT_NUM_CHANNELS) {
  430. continue;
  431. }
  432. for (uint8_t i=0; i<channel_count; i++) {
  433. _pwm_values[i] = values[i];
  434. }
  435. _num_channels = channel_count;
  436. if (failsafe_state == false) {
  437. rc_input_count++;
  438. }
  439. ret = true;
  440. }
  441. nbytes--;
  442. }
  443. return ret;
  444. }
  445. /*
  446. add some bytes of input in SBUS serial stream format, coping with partial packets
  447. */
  448. void RCInput::add_sbus_input(const uint8_t *bytes, size_t nbytes)
  449. {
  450. if (nbytes == 0) {
  451. return;
  452. }
  453. const uint8_t sbus_frame_size = sizeof(sbus.frame);
  454. uint32_t now = AP_HAL::millis();
  455. if (now - sbus.last_input_ms > 5) {
  456. // resync based on time
  457. sbus.partial_frame_count = 0;
  458. }
  459. sbus.last_input_ms = now;
  460. while (nbytes > 0) {
  461. size_t n = nbytes;
  462. if (sbus.partial_frame_count + n > sbus_frame_size) {
  463. n = sbus_frame_size - sbus.partial_frame_count;
  464. }
  465. if (n > 0) {
  466. memcpy(&sbus.frame[sbus.partial_frame_count], bytes, n);
  467. sbus.partial_frame_count += n;
  468. nbytes -= n;
  469. bytes += n;
  470. }
  471. if (sbus.partial_frame_count == sbus_frame_size) {
  472. sbus.partial_frame_count = 0;
  473. uint16_t values[16] {};
  474. uint16_t num_values=0;
  475. bool sbus_failsafe;
  476. bool sbus_frame_drop;
  477. if (sbus_decode(sbus.frame, values, &num_values, &sbus_failsafe, &sbus_frame_drop, 16) &&
  478. num_values >= MIN_NUM_CHANNELS) {
  479. for (uint8_t i=0; i<num_values; i++) {
  480. if (values[i] != 0) {
  481. _pwm_values[i] = values[i];
  482. }
  483. }
  484. /*
  485. the apparent number of channels can change on SBUS,
  486. as they are spread across multiple frames. We just
  487. use the max num_values we get
  488. */
  489. if (num_values > _num_channels) {
  490. _num_channels = num_values;
  491. }
  492. if (!sbus_failsafe) {
  493. rc_input_count++;
  494. }
  495. #if 0
  496. printf("Decoded SBUS %u channels %u %u %u %u %u %u %u %u %s\n",
  497. (unsigned)num_values,
  498. values[0], values[1], values[2], values[3], values[4], values[5], values[6], values[7],
  499. sbus_failsafe?"FAIL":"OK");
  500. #endif
  501. }
  502. }
  503. }
  504. }