Mac OS X gamepad emulator for serial RC transmitters
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

protocol.c 4.1KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  1. /*
  2. * ----------------------------------------------------------------------------
  3. * "THE BEER-WARE LICENSE" (Revision 42):
  4. * <xythobuz@xythobuz.de> wrote this file. As long as you retain this notice
  5. * you can do whatever you want with this stuff. If we meet some day, and you
  6. * think this stuff is worth it, you can buy me a beer in return. Thomas Buck
  7. * ----------------------------------------------------------------------------
  8. */
  9. #include <stdint.h>
  10. #include <stdio.h>
  11. #include <signal.h>
  12. #include <unistd.h>
  13. #include "serial.h"
  14. #define BAUDRATE 115200
  15. #define PACKETSIZE 18
  16. #define HEADERBYTES 2
  17. #define HEADERBYTE_A 85
  18. #define HEADERBYTE_B 252
  19. #define CHECKSUMBYTES 2
  20. #define PAYLOADBYTES (PACKETSIZE - HEADERBYTES - CHECKSUMBYTES)
  21. #define CHANNELS 6
  22. #define TESTCHANNEL 2
  23. static int running = 1;
  24. static void signalHandler(int signo) {
  25. running = 0;
  26. }
  27. int main(int argc, char* argv[]) {
  28. if (argc != 2) {
  29. printf("Usage:\n\t%s /dev/serial_port\n", argv[0]);
  30. return 1;
  31. }
  32. printf("Opening serial port...\n");
  33. int fd = serialOpen(argv[1], BAUDRATE);
  34. if (fd == -1) {
  35. return 1;
  36. }
  37. if (signal(SIGINT, signalHandler) == SIG_ERR) {
  38. perror("Couldn't register signal handler");
  39. return 1;
  40. }
  41. while (running != 0) {
  42. if (serialHasChar(fd)) {
  43. unsigned char c1;
  44. serialReadChar(fd, (char*)&c1);
  45. if (c1 == HEADERBYTE_A) {
  46. // Found first byte of protocol start
  47. while (!serialHasChar(fd)) {
  48. if (running == 0) {
  49. serialClose(fd);
  50. return 0;
  51. }
  52. }
  53. unsigned char c2;
  54. serialReadChar(fd, (char*)&c2);
  55. if (c2 == HEADERBYTE_B) {
  56. // Protocol start has been found, read payload
  57. unsigned char data[PAYLOADBYTES];
  58. int read = 0;
  59. while ((read < PAYLOADBYTES) && (running != 0)) {
  60. read += serialReadRaw(fd, (char*)data + read, PAYLOADBYTES - read);
  61. }
  62. // Read 16bit checksum
  63. unsigned char checksumData[CHECKSUMBYTES];
  64. read = 0;
  65. while ((read < CHECKSUMBYTES) && (running != 0)) {
  66. read += serialReadRaw(fd, (char*)checksumData + read,
  67. CHECKSUMBYTES - read);
  68. }
  69. // Check if checksum matches
  70. uint16_t checksum = 0;
  71. for (int i = 0; i < PAYLOADBYTES; i++) {
  72. checksum += data[i];
  73. }
  74. if (checksum != ((checksumData[0] << 8) | checksumData[1])) {
  75. printf("Wrong checksum: %d != %d\n",
  76. checksum, ((checksumData[0] << 8) | checksumData[1]));
  77. } else {
  78. // Decode channel values
  79. uint16_t buff[CHANNELS + 1];
  80. for (int i = 0; i < (CHANNELS + 1); i++) {
  81. buff[i] = data[2 * i] << 8;
  82. buff[i] |= data[(2 * i) + 1];
  83. if (i < CHANNELS) {
  84. buff[i] -= 1000;
  85. }
  86. }
  87. // Check Test Channel Value
  88. if (buff[CHANNELS] != buff[TESTCHANNEL]) {
  89. printf("Wrong test channel value: %d != %d\n",
  90. buff[CHANNELS], buff[TESTCHANNEL]);
  91. }
  92. for (int i = 0; i < CHANNELS; i++) {
  93. printf("CH%d: %d\n", i + 1, buff[i]);
  94. }
  95. for (int i = 0; i < CHANNELS; i++) {
  96. printf("\r\033[1A");
  97. }
  98. }
  99. }
  100. }
  101. }
  102. usleep(1000);
  103. }
  104. printf("Closing serial port... \n");
  105. serialClose(fd);
  106. return 0;
  107. }