Paparazzi UAS  v5.12_stable-4-g9b43e9b
Paparazzi is a free software Unmanned Aircraft System.
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
nps_radio_control_spektrum.c
Go to the documentation of this file.
1 #include "nps_radio_control.h"
2 
3 #include <glib.h>
4 #include <stdio.h>
5 #include <termios.h>
6 #include <sys/types.h>
7 #include <sys/stat.h>
8 #include <fcntl.h>
9 #include <string.h>
10 #include <errno.h>
11 #include <inttypes.h>
12 
13 // IUCLC flag translates upper case to lower case (actually needed here?)
14 // but is not in POSIX and OSX
15 #ifndef IUCLC
16 #define IUCLC 0
17 #endif
18 
19 #define CHANNEL_OF_FRAME(i) ((((frame_buf[2*i]<<8) + frame_buf[2*i+1])&0x03FF)-512)
20 
21 static int sp_fd;
22 
23 static gboolean on_serial_data_received(GIOChannel *source,
24  GIOCondition condition,
25  gpointer data);
26 static void parse_data(char *buf, int len);
27 static void handle_frame(void);
28 
29 
30 int nps_radio_control_spektrum_init(const char *device)
31 {
32 
33  if ((sp_fd = open(device, O_RDWR | O_NONBLOCK)) < 0) {
34  printf("opening %s (%s)\n", device, strerror(errno));
35  return -1;
36  }
37  struct termios termios;
38  termios.c_iflag = 0; // properly initialize variable
39  /* input modes */
40  termios.c_iflag &= ~(IGNBRK | BRKINT | PARMRK | INPCK | ISTRIP | INLCR | IGNCR
41  | ICRNL | IUCLC | IXON | IXANY | IXOFF | IMAXBEL);
42  termios.c_iflag |= IGNPAR;
43 
44  termios.c_cflag = 0; // properly initialize variable
45  /* control modes*/
46  termios.c_cflag &= ~(CSIZE | PARENB | CRTSCTS | PARODD | HUPCL);
47  termios.c_cflag |= CREAD | CS8 | CSTOPB | CLOCAL;
48 
49  termios.c_lflag = 0; // properly initialize variable
50  /* local modes */
51  termios.c_lflag &= ~(ISIG | ICANON | IEXTEN | ECHO | FLUSHO | PENDIN);
52  termios.c_lflag |= NOFLSH;
53  /* speed */
54  speed_t speed = B115200;
55 
56  if (cfsetispeed(&termios, speed)) {
57  printf("setting term speed (%s)\n", strerror(errno));
58  return -1;
59  }
60  if (tcsetattr(sp_fd, TCSADRAIN, &termios)) {
61  printf("setting term attributes (%s)\n", strerror(errno));
62  return -1;
63  }
64  GIOChannel *channel = g_io_channel_unix_new(sp_fd);
65  g_io_channel_set_encoding(channel, NULL, NULL);
66  g_io_add_watch(channel, G_IO_IN , on_serial_data_received, NULL);
67  return 0;
68 }
69 
70 
71 
72 
73 static gboolean on_serial_data_received(GIOChannel *source,
74  GIOCondition condition __attribute__((unused)),
75  gpointer data __attribute__((unused)))
76 {
77  char buf[255];
78  gsize bytes_read;
79  GError *_err = NULL;
80  GIOStatus st = g_io_channel_read_chars(source, buf, 255, &bytes_read, &_err);
81  if (!_err) {
82  if (st == G_IO_STATUS_NORMAL) {
83  parse_data(buf, bytes_read);
84  }
85  } else {
86  printf("error reading serial: %s\n", _err->message);
87  g_error_free(_err);
88  }
89  return TRUE;
90 }
91 
92 
93 #define SYNC_1 0x03
94 #define SYNC_2 0x12
95 
96 #define STA_UNINIT 0
97 #define STA_GOT_SYNC_1 1
98 #define STA_GOT_SYNC_2 2
99 
101 
102 #define FRAME_LEN 14
104 static uint32_t idx = 0;
105 
106 static void parse_data(char *buf, int len)
107 {
108  int i;
109  for (i = 0; i < len; i++) {
110  int8_t c = buf[i ];
111  switch (status) {
112  case STA_UNINIT:
113  if (c == SYNC_1) {
114  status = STA_GOT_SYNC_1;
115  }
116  break;
117  case STA_GOT_SYNC_1:
118  if (c == SYNC_2) {
119  status = STA_GOT_SYNC_2;
120  idx = 0;
121  } else {
122  status = STA_UNINIT;
123  }
124  break;
125  case STA_GOT_SYNC_2:
126  frame_buf[idx] = c;
127  idx++;
128  if (idx == FRAME_LEN) {
129  status = STA_UNINIT;
130  handle_frame();
131  }
132  break;
133  }
134  }
135 }
136 
137 static void handle_frame(void)
138 {
139  nps_radio_control.roll = (float)CHANNEL_OF_FRAME(0) / -340.;
140  nps_radio_control.throttle = (float)(CHANNEL_OF_FRAME(1) + 340) / 680.;
141  nps_radio_control.pitch = (float)CHANNEL_OF_FRAME(2) / -340.;
142  nps_radio_control.yaw = (float)CHANNEL_OF_FRAME(3) / -340.;
143  nps_radio_control.mode = (float)CHANNEL_OF_FRAME(5) / 340.;
144  // printf("%f %f %f %f %f \n", nps_radio_control.roll, nps_radio_control.throttle, nps_radio_control.pitch, nps_radio_control.yaw, nps_radio_control.mode);
145 }
#define STA_GOT_SYNC_1
status
Definition: anemotaxis.c:10
static uint32_t idx
static gboolean on_serial_data_received(GIOChannel *source, GIOCondition condition, gpointer data)
#define CHANNEL_OF_FRAME(i)
#define B115200
Definition: uart_arch.h:48
#define STA_UNINIT
static int sp_fd
int nps_radio_control_spektrum_init(const char *device)
#define FRAME_LEN
#define STA_GOT_SYNC_2
struct NpsRadioControl nps_radio_control
static void handle_frame(void)
#define TRUE
Definition: std.h:4
static uint8_t frame_buf[FRAME_LEN]
unsigned long uint32_t
Definition: types.h:18
#define SYNC_2
unsigned char uint8_t
Definition: types.h:14
#define IUCLC
signed char int8_t
Definition: types.h:15
static void parse_data(char *buf, int len)
static uint8_t channel
Definition: ADS8344.c:80
#define SYNC_1