RCInput_UART.cpp 2.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  1. #include "RCInput_UART.h"
  2. #include <errno.h>
  3. #include <fcntl.h>
  4. #include <inttypes.h>
  5. #include <stdio.h>
  6. #include <stdlib.h>
  7. #include <string.h>
  8. #include <termios.h>
  9. #include <unistd.h>
  10. #include <AP_HAL/AP_HAL.h>
  11. #define MAGIC 0x55AA
  12. using namespace Linux;
  13. RCInput_UART::RCInput_UART(const char *path)
  14. {
  15. _fd = open(path, O_RDONLY|O_NOCTTY|O_NONBLOCK|O_NDELAY|O_CLOEXEC);
  16. if (_fd < 0) {
  17. AP_HAL::panic("RCInput_UART: Error opening '%s': %s",
  18. path, strerror(errno));
  19. }
  20. }
  21. RCInput_UART::~RCInput_UART()
  22. {
  23. close(_fd);
  24. }
  25. void RCInput_UART::init()
  26. {
  27. struct termios options;
  28. tcgetattr(_fd, &options);
  29. cfsetispeed(&options, B115200);
  30. cfsetospeed(&options, B115200);
  31. options.c_cflag &= ~(PARENB|CSTOPB|CSIZE);
  32. options.c_cflag |= CS8;
  33. options.c_lflag &= ~(ICANON|ECHO|ECHOE|ISIG);
  34. options.c_iflag &= ~(IXON|IXOFF|IXANY);
  35. options.c_oflag &= ~OPOST;
  36. if (tcsetattr(_fd, TCSANOW, &options) != 0) {
  37. AP_HAL::panic("RCInput_UART: error configuring device: %s",
  38. strerror(errno));
  39. }
  40. tcflush(_fd, TCIOFLUSH);
  41. _pdata = (uint8_t *)&_data;
  42. _remain = sizeof(_data);
  43. }
  44. void RCInput_UART::_timer_tick()
  45. {
  46. ssize_t n;
  47. if ((n = ::read(_fd, _pdata, _remain)) <= 0)
  48. return;
  49. _remain -= n;
  50. _pdata += n;
  51. if (_remain != 0)
  52. return;
  53. if (_data.magic != MAGIC) {
  54. /* try to find the magic number and move
  55. * it to the beginning of our buffer */
  56. uint16_t magic = MAGIC;
  57. _pdata = (uint8_t *)memmem(&_data, sizeof(_data), &magic, sizeof(magic));
  58. if (!_pdata)
  59. _pdata = (uint8_t *)&_data + sizeof(_data) - 1;
  60. _remain = _pdata - (uint8_t *)&_data;
  61. n = sizeof(_data) - _remain;
  62. memmove(&_data, _pdata, n);
  63. _pdata = (uint8_t *)&_data + n;
  64. return;
  65. }
  66. _update_periods(_data.values, CHANNELS);
  67. _pdata = (uint8_t *)&_data;
  68. _remain = sizeof(_data);
  69. }