Paparazzi UAS v7.0_unstable
Paparazzi is a free software Unmanned Aircraft System.
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
actuators_sbus.c
Go to the documentation of this file.
1/*
2 * Copyright (C) 2015 Freek van Tienen <freek.v.tienen@gmail.com>
3 *
4 * This file is part of paparazzi.
5 *
6 * paparazzi is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2, or (at your option)
9 * any later version.
10 *
11 * paparazzi is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with paparazzi; see the file COPYING. If not, write to
18 * the Free Software Foundation, 59 Temple Place - Suite 330,
19 * Boston, MA 02111-1307, USA.
20 */
21
29#include "generated/airframe.h"
30#include "mcu_periph/uart.h"
31
32/* Currently we only support 7 channels */
33#if SERVOS_SBUS_NB > ACTUATORS_SBUS_MAX_NB
34#error SBUS actuators only support less then 7 servos
35#endif
36
37/* Calculate the frequency divider to aim at 7 ms */
38#if PERIODIC_FREQUENCY < 150
39#error Sbus actuators need at leest a frequency of 150 Hz
40#else
41static uint8_t freq_trig = PERIODIC_FREQUENCY / 142.0 + 0.5; // Round it to nearest value
42#endif
43
44/* Main actuator structure */
46static inline void actuators_sbus_send(struct link_device *dev);
47
48/*
49 * Initialize the sbus devices (UART output devices)
50 */
60
61/*
62 * Transmit the sbus output at 1 / 7ms
63 */
65{
66 static uint8_t cnt = 0;
67
68 // Only send every 7 ms
69 cnt++;
70 if (cnt == freq_trig) {
72 cnt = 0;
73 }
74}
75
76/*
77 * Actually transmit the sbus output on a link device
78 *
79 * The protocol is 25 Byte long and is send every 14ms (analog mode) or 7ms (highspeed mode).
80 * One Byte = 1 startbit + 8 databit + 1 paritybit + 2 stopbit (8E2), baudrate = 100'000 bit/s
81 * The highest bit is send first. The logic is inverted (Level High = 1)
82 *
83 * [startbyte] [data1] [data2] .... [data22] [flags][endbyte]
84 *
85 * SBUS protocol
86 */
87
88#define SBUS_START_BYTE 0x0f
89#define SBUS_END_BYTE 0x00
90
91#define SBUS_BIT_PER_CHANNEL 11
92
93static inline void actuators_sbus_send(struct link_device *dev)
94{
95 uint8_t frame[25] = {0};
96
98 frame[1] = (actuators_sbus.cmds[0] & 0x07FF);
99 frame[2] = (actuators_sbus.cmds[0] & 0x07FF) >> 8 | (actuators_sbus.cmds[1] & 0x07FF) << 3;
100 frame[3] = (actuators_sbus.cmds[1] & 0x07FF) >> 5 | (actuators_sbus.cmds[2] & 0x07FF) << 6;
101 frame[4] = (actuators_sbus.cmds[2] & 0x07FF) >> 2;
102 frame[5] = (actuators_sbus.cmds[2] & 0x07FF) >> 10 | (actuators_sbus.cmds[3] & 0x07FF) << 1;
103 frame[6] = (actuators_sbus.cmds[3] & 0x07FF) >> 7 | (actuators_sbus.cmds[4] & 0x07FF) << 4;
104 frame[7] = (actuators_sbus.cmds[4] & 0x07FF) >> 4 | (actuators_sbus.cmds[5] & 0x07FF) << 7;
105 frame[8] = (actuators_sbus.cmds[5] & 0x07FF) >> 1;
106 frame[9] = (actuators_sbus.cmds[5] & 0x07FF) >> 9 | (actuators_sbus.cmds[6] & 0x07FF) << 2;
107 frame[10] = (actuators_sbus.cmds[6] & 0x07FF) >> 6 | (actuators_sbus.cmds[7] & 0x07FF) << 5;
108 frame[11] = (actuators_sbus.cmds[7] & 0x07FF) >> 3;
109 frame[12] = (actuators_sbus.cmds[8] & 0x07FF);
110 frame[13] = (actuators_sbus.cmds[8] & 0x07FF) >> 8 | (actuators_sbus.cmds[9] & 0x07FF) << 3;
111 frame[14] = (actuators_sbus.cmds[9] & 0x07FF) >> 5 | (actuators_sbus.cmds[10] & 0x07FF) << 6;
112 frame[15] = (actuators_sbus.cmds[10] & 0x07FF) >> 2;
113 frame[16] = (actuators_sbus.cmds[10] & 0x07FF) >> 10 | (actuators_sbus.cmds[11] & 0x07FF) << 1;
114 frame[17] = (actuators_sbus.cmds[11] & 0x07FF) >> 7 | (actuators_sbus.cmds[12] & 0x07FF) << 4;
115 frame[18] = (actuators_sbus.cmds[12] & 0x07FF) >> 4 | (actuators_sbus.cmds[13] & 0x07FF) << 7;
116 frame[19] = (actuators_sbus.cmds[13] & 0x07FF) >> 1;
117 frame[20] = (actuators_sbus.cmds[13] & 0x07FF) >> 9 | (actuators_sbus.cmds[14] & 0x07FF) << 2;
118 frame[21] = (actuators_sbus.cmds[14] & 0x07FF) >> 6 | (actuators_sbus.cmds[15] & 0x07FF) << 5;
119 frame[22] = (actuators_sbus.cmds[15] & 0x07FF) >> 3;
120 frame[23] = 0x00; // No frame lost, switches off, no failsafe
121 frame[24] = SBUS_END_BYTE; // stop byte
122
123 dev->put_buffer(dev->periph, 0, frame, 25);
124
125}
#define SBUS_START_BYTE
void actuators_sbus_set(void)
#define SBUS_END_BYTE
static void actuators_sbus_send(struct link_device *dev)
struct ActuatorsSbus actuators_sbus
void actuators_sbus_init(void)
Sbus actuator driver, which can output as 7 sbus channels at ~11ms.
int32_t cmds[ACTUATORS_SBUS_MAX_NB]
struct link_device * device
static uint8_t frame[20]
#define B100000
Definition uart_arch.h:47
void uart_periph_set_bits_stop_parity(struct uart_periph *periph, uint8_t bits, uint8_t stop, uint8_t parity)
Definition uart_arch.c:296
void uart_periph_set_baudrate(struct uart_periph *periph, uint32_t baud)
Definition uart_arch.c:280
uint16_t foo
Definition main_demo5.c:58
Hardware independent API for actuators (servos, motor controllers).
#define UBITS_8
Definition serial_port.c:50
#define USTOP_2
Definition serial_port.c:53
#define UPARITY_EVEN
Definition serial_port.c:57
static const struct usb_device_descriptor dev
Definition usb_ser_hw.c:74
void WEAK uart_periph_invert_data_logic(struct uart_periph *p, bool invert_rx, bool invert_tx)
Definition uart.c:194
arch independent UART (Universal Asynchronous Receiver/Transmitter) API
unsigned char uint8_t
Typedef defining 8 bit unsigned char type.