Cheetah Software  1.0
rt_sbus.cpp
Go to the documentation of this file.
1 #include <errno.h>
2 #include <fcntl.h>
3 #include <pthread.h>
4 #include <stdint.h>
5 #include <stdio.h>
6 #include <stdlib.h>
7 #include <string.h>
8 #include <time.h>
9 #include <unistd.h>
10 
11 #define termios asmtermios
12 
13 #include <asm/termios.h>
14 
15 #undef termios
16 
17 #include <termios.h>
18 
19 #include <rt/rt_interface_lcm.h>
20 #include <rt/rt_sbus.h>
21 #include <rt/rt_serial.h>
22 
23 pthread_mutex_t sbus_data_m;
24 
25 uint16_t channels[18];
26 uint16_t channel_data[18];
27 
29 #define K_SBUS_PORT_SIM "/dev/ttyUSB0"
30 
31 #define K_SBUS_PORT_MC "/dev/ttyS4"
32 
33 void unpack_sbus_data(uint8_t sbus_data[], uint16_t *channels_) {
34  if ((sbus_data[0] == 0xF) && (sbus_data[24] == 0x0)) {
35  channels_[0] = ((sbus_data[1]) | ((sbus_data[2] & 0x7) << 8));
36  channels_[1] = (sbus_data[2] >> 3) | ((sbus_data[3] & 0x3F) << 5);
37  channels_[2] = ((sbus_data[3] & 0xC0) >> 6) | (sbus_data[4] << 2) |
38  ((sbus_data[5] & 0x1) << 10);
39  channels_[3] = ((sbus_data[5] & 0xFE) >> 1) | ((sbus_data[6] & 0xF) << 7);
40  channels_[4] = ((sbus_data[6] & 0xF0) >> 4) | ((sbus_data[7] & 0x7F) << 4);
41  channels_[5] = ((sbus_data[7] & 0x80) >> 7) | (sbus_data[8] << 1) |
42  ((sbus_data[9] & 0x3) << 9);
43  channels_[6] = ((sbus_data[9] & 0xFC) >> 2) | ((sbus_data[10] & 0x1F) << 6);
44  channels_[7] = ((sbus_data[10] & 0xE0) >> 5) | (sbus_data[11] << 3);
45 
46  channels_[8] = ((sbus_data[12]) | ((sbus_data[13] & 0x7) << 8));
47  channels_[9] = (sbus_data[13] >> 3) | ((sbus_data[14] & 0x3F) << 5);
48  channels_[10] = ((sbus_data[14] & 0xC0) >> 6) | (sbus_data[15] << 2) |
49  ((sbus_data[16] & 0x1) << 10);
50  channels_[11] =
51  ((sbus_data[16] & 0xFE) >> 1) | ((sbus_data[17] & 0xF) << 7);
52  channels_[12] =
53  ((sbus_data[17] & 0xF0) >> 4) | ((sbus_data[18] & 0x7F) << 4);
54  channels_[13] = ((sbus_data[18] & 0x80) >> 7) | (sbus_data[19] << 1) |
55  ((sbus_data[20] & 0x3) << 9);
56  channels_[14] =
57  ((sbus_data[20] & 0xFC) >> 2) | ((sbus_data[21] & 0x1F) << 6);
58  channels_[15] = ((sbus_data[21] & 0xE0) >> 5) | (sbus_data[22] << 3);
59 
60  channels_[16] = (sbus_data[23] & 0x80) >> 7;
61  channels_[17] = (sbus_data[23] & 0x40) >> 6;
62 
63  pthread_mutex_lock(&sbus_data_m);
64  for (int i = 0; i < 18; i++) {
65  // printf("%d ", channels_[i]);
66  channel_data[i] = channels_[i];
67  }
68  // printf("\n\n");
69  pthread_mutex_unlock(&sbus_data_m);
70 
71  } else {
72  printf("Bad Packet\n");
73  }
74 }
75 
76 int read_sbus_data(int port, uint8_t *sbus_data) {
77  uint8_t packet_full = 0;
78  uint8_t read_byte[1] = {0};
79  int timeout_counter = 0;
80  // int n = read(fd1, read_buff, sizeof(read_buff));
81  while ((!packet_full) && (timeout_counter < 50)) {
82  timeout_counter++;
83  // Read a byte //
84  int n = read(port, read_byte, sizeof(read_byte));
85  (void)n;
86  // Shift the buffer //
87  for (int i = 0; i < 24; i++) {
88  sbus_data[i] = sbus_data[i + 1];
89  }
90  sbus_data[24] = read_byte[0];
91 
92  // Check for the correct start and stop bytes ///
93  if ((sbus_data[0] == 15) && (sbus_data[24] == 0)) {
94  // unpack_sbus_data(sbus_data_buff, channels);
95  packet_full = 1;
96  }
97  }
98  return packet_full;
99 }
100 
101 int read_sbus_channel(int channel) {
102  pthread_mutex_lock(&sbus_data_m);
103  int value = channel_data[channel];
104  pthread_mutex_unlock(&sbus_data_m);
105  return value;
106 }
107 
108 int receive_sbus(int port) {
109  uint16_t read_buff[25] = {0};
110  int x = read_sbus_data(port, (uint8_t *)read_buff);
111  if (x) {
112  unpack_sbus_data((uint8_t *)read_buff, channels);
113  } else {
114  printf("SBUS tried read 50 bytes without seeing a packet\n");
115  }
116  return x;
117 }
118 
119 int init_sbus(int is_simulator) {
120  // char *port1;
121  std::string port1;
122  if (is_simulator) {
123  port1 = K_SBUS_PORT_SIM;
124  } else {
125  port1 = K_SBUS_PORT_MC;
126  }
127 
128  if (pthread_mutex_init(&sbus_data_m, NULL) != 0) {
129  printf("Failed to initialize sbus data mutex.\n");
130  }
131 
132  int fd1 = open(port1.c_str(), O_RDWR | O_NOCTTY | O_SYNC);
133  if (fd1 < 0) {
134  printf("Error opening %s: %s\n", port1.c_str(), strerror(errno));
135  } else {
136  set_interface_attribs_custom_baud(fd1, 100000, 0, 0);
137  }
138  return fd1;
139 }
void unpack_sbus_data(uint8_t sbus_data[], uint16_t *channels_)
Definition: rt_sbus.cpp:33
int init_sbus(int is_simulator)
Definition: rt_sbus.cpp:119
#define K_SBUS_PORT_SIM
Name of SBUS serial port in simulator.
Definition: rt_sbus.cpp:29
int set_interface_attribs_custom_baud(int fd, int speed, int parity, int port)
Configure serial port.
Definition: rt_serial.cpp:40
int receive_sbus(int port)
Definition: rt_sbus.cpp:108
int read_sbus_data(int port, uint8_t *sbus_data)
Definition: rt_sbus.cpp:76
pthread_mutex_t sbus_data_m
Definition: rt_sbus.cpp:23
#define K_SBUS_PORT_MC
Name of SBUS serial port on the mini cheetah.
Definition: rt_sbus.cpp:31
uint16_t channel_data[18]
Definition: rt_sbus.cpp:26
int read_sbus_channel(int channel)
Definition: rt_sbus.cpp:101
uint16_t channels[18]
Definition: rt_sbus.cpp:25