Paparazzi UAS  v6.3_unstable
Paparazzi is a free software Unmanned Aircraft System.
actuators_dshot_arch.c
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2018 Gautier Hattenberger <gautier.hattenberger@enac.fr>
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, see
18  * <http://www.gnu.org/licenses/>.
19  */
20 
30 #include "modules/core/abi.h"
31 #include "mcu_periph/ram_arch.h"
32 #include "mcu_periph/gpio.h"
33 #include BOARD_CONFIG
34 
35 #if PERIODIC_TELEMETRY
38 #endif
39 
40 struct dshot_private {
43 };
44 
47 
48 #if DSHOT_CONF_TIM1
49 static DSHOTDriver DSHOTD1;
50 static IN_DMA_SECTION_NOINIT(DshotDmaBuffer dshot1DmaBuffer);
51 static DSHOTConfig dshotcfg1 = DSHOT_CONF1_DEF;
52 #endif
53 #if DSHOT_CONF_TIM2
54 static DSHOTDriver DSHOTD2;
55 static IN_DMA_SECTION_NOINIT(DshotDmaBuffer dshot2DmaBuffer);
56 static DSHOTConfig dshotcfg2 = DSHOT_CONF2_DEF;
57 #endif
58 #if DSHOT_CONF_TIM3
59 static DSHOTDriver DSHOTD3;
60 static IN_DMA_SECTION_NOINIT(DshotDmaBuffer dshot3DmaBuffer);
61 static DSHOTConfig dshotcfg3 = DSHOT_CONF3_DEF;
62 #endif
63 #if DSHOT_CONF_TIM4
64 static DSHOTDriver DSHOTD4;
65 static IN_DMA_SECTION_NOINIT(DshotDmaBuffer dshot4DmaBuffer);
66 static DSHOTConfig dshotcfg4 = DSHOT_CONF4_DEF;
67 #endif
68 #if DSHOT_CONF_TIM5
69 static DSHOTDriver DSHOTD5;
70 static IN_DMA_SECTION_NOINIT(DshotDmaBuffer dshot5DmaBuffer);
71 static DSHOTConfig dshotcfg5 = DSHOT_CONF5_DEF;
72 #endif
73 #if DSHOT_CONF_TIM8
74 static DSHOTDriver DSHOTD8;
75 static IN_DMA_SECTION_NOINIT(DshotDmaBuffer dshot8DmaBuffer);
76 static DSHOTConfig dshotcfg8 = DSHOT_CONF8_DEF;
77 #endif
78 #if DSHOT_CONF_TIM9
79 static DSHOTDriver DSHOTD9;
80 static IN_DMA_SECTION_NOINIT(DshotDmaBuffer dshot9DmaBuffer);
81 static DSHOTConfig dshotcfg9 = DSHOT_CONF9_DEF;
82 #endif
83 
84 #if PERIODIC_TELEMETRY
85 static void esc_msg_send(struct transport_tx *trans, struct link_device *dev) {
86  for (uint8_t i = 0; i < ACTUATORS_DSHOT_NB; i++) {
87  if (actuators_dshot_values[i].activated) {
89 
90  actuators_dshot_values[i].current = (float)dtelem->current * 0.01f;
91  actuators_dshot_values[i].voltage = (float)dtelem->voltage * 0.01f;
92  actuators_dshot_values[i].rpm = (float)dtelem->rpm;
93  float bat_voltage = electrical.vsupply;
94  float power = actuators_dshot_values[i].current * bat_voltage;
95  float energy = (float)dtelem->consumption;
96  float temp = dtelem->temp;
97  float temp_dev = 0;
98  pprz_msg_send_ESC(trans, dev, AC_ID,
99  &actuators_dshot_values[i].current,
100  &bat_voltage,
101  &power,
103  &actuators_dshot_values[i].voltage,
104  &energy,
105  &temp,
106  &temp_dev,
107  &i,
108  &i);
109  }
110  }
111 }
112 #endif
113 
114 static void dshot_init_struct(struct dshot * ds)
115 {
116  ds->cmd = 0;
117  ds->rpm = 0;
118  ds->current = 0;
119  ds->voltage = 0;
120  ds->activated = false;
121 }
122 
123 static void dshot_set_struct(struct dshot * ds, struct dshot_private * dsp, DSHOTDriver * driver, uint32_t channel)
124 {
125  ds->activated = true;
126  dsp->driver = driver;
127  dsp->channel = channel;
128 }
129 
130 #define _CONCAT_GPIO(num, name) UART ## num ## _GPIO_ ## name
131 #define CONCAT_GPIO(num, name) _CONCAT_GPIO(num, name)
132 
134 {
135  // init dshot structure to zero
136  for (int i = 0; i < ACTUATORS_DSHOT_NB; i++) {
138  }
139 
140  // configure telemetry pin if needed
141  // the serial device interface might have to be activated
142  // by hand (ChibiOS HAL), but PPRZ one disabled
143 #ifdef DSHOT_TIM1_TELEMETRY_NUM
145  CONCAT_GPIO(DSHOT_TIM1_TELEMETRY_NUM, PORT_RX),
146  CONCAT_GPIO(DSHOT_TIM1_TELEMETRY_NUM, RX),
147  CONCAT_GPIO(DSHOT_TIM1_TELEMETRY_NUM, AF), FALSE);
148 #endif
149 #ifdef DSHOT_TIM2_TELEMETRY_NUM
151  CONCAT_GPIO(DSHOT_TIM2_TELEMETRY_NUM, PORT_RX),
152  CONCAT_GPIO(DSHOT_TIM2_TELEMETRY_NUM, RX),
153  CONCAT_GPIO(DSHOT_TIM2_TELEMETRY_NUM, AF), FALSE);
154 #endif
155 #ifdef DSHOT_TIM3_TELEMETRY_NUM
157  CONCAT_GPIO(DSHOT_TIM3_TELEMETRY_NUM, PORT_RX),
158  CONCAT_GPIO(DSHOT_TIM3_TELEMETRY_NUM, RX),
159  CONCAT_GPIO(DSHOT_TIM3_TELEMETRY_NUM, AF), FALSE);
160 #endif
161 #ifdef DSHOT_TIM4_TELEMETRY_NUM
163  CONCAT_GPIO(DSHOT_TIM4_TELEMETRY_NUM, PORT_RX),
164  CONCAT_GPIO(DSHOT_TIM4_TELEMETRY_NUM, RX),
165  CONCAT_GPIO(DSHOT_TIM4_TELEMETRY_NUM, AF), FALSE);
166 #endif
167 #ifdef DSHOT_TIM5_TELEMETRY_NUM
169  CONCAT_GPIO(DSHOT_TIM5_TELEMETRY_NUM, PORT_RX),
170  CONCAT_GPIO(DSHOT_TIM5_TELEMETRY_NUM, RX),
171  CONCAT_GPIO(DSHOT_TIM5_TELEMETRY_NUM, AF), FALSE);
172 #endif
173 #ifdef DSHOT_TIM8_TELEMETRY_NUM
175  CONCAT_GPIO(DSHOT_TIM8_TELEMETRY_NUM, PORT_RX),
176  CONCAT_GPIO(DSHOT_TIM8_TELEMETRY_NUM, RX),
177  CONCAT_GPIO(DSHOT_TIM8_TELEMETRY_NUM, AF), FALSE);
178 #endif
179 #ifdef DSHOT_TIM9_TELEMETRY_NUM
181  CONCAT_GPIO(DSHOT_TIM9_TELEMETRY_NUM, PORT_RX),
182  CONCAT_GPIO(DSHOT_TIM9_TELEMETRY_NUM, RX),
183  CONCAT_GPIO(DSHOT_TIM9_TELEMETRY_NUM, AF), FALSE);
184 #endif
185 
186  /*----------------
187  * Configure GPIO
188  *----------------*/
189 #ifdef DSHOT_SERVO_0
192 #endif
193 #ifdef DSHOT_SERVO_1
196 #endif
197 #ifdef DSHOT_SERVO_2
200 #endif
201 #ifdef DSHOT_SERVO_3
204 #endif
205 #ifdef DSHOT_SERVO_4
208 #endif
209 #ifdef DSHOT_SERVO_5
212 #endif
213 #ifdef DSHOT_SERVO_6
214  gpio_setup_pin_af(DSHOT_SERVO_6_GPIO, DSHOT_SERVO_6_PIN, DSHOT_SERVO_6_AF, true);
215  dshot_set_struct(&actuators_dshot_values[DSHOT_SERVO_6], &actuators_dshot_private[DSHOT_SERVO_6], &DSHOT_SERVO_6_DRIVER, DSHOT_SERVO_6_CHANNEL);
216 #endif
217 #ifdef DSHOT_SERVO_7
220 #endif
221 #ifdef DSHOT_SERVO_8
224 #endif
225 #ifdef DSHOT_SERVO_9
228 #endif
229 #ifdef DSHOT_SERVO_10
232 #endif
233 #ifdef DSHOT_SERVO_11
234  gpio_setup_pin_af(DSHOT_SERVO_11_GPIO, DSHOT_SERVO_11_PIN, DSHOT_SERVO_11_AF, true);
235  dshot_set_struct(&actuators_dshot_values[DSHOT_SERVO_11], &actuators_dshot_private[DSHOT_SERVO_11], &DSHOT_SERVO_11_DRIVER, DSHOT_SERVO_11_CHANNEL);
236 #endif
237 
238  /*---------------
239  * Configure DSHOT
240  *---------------*/
241 #if DSHOT_CONF_TIM1
242  dshotStart(&DSHOTD1, &dshotcfg1);
243 #endif
244 #if DSHOT_CONF_TIM2
245  dshotStart(&DSHOTD2, &dshotcfg2);
246 #endif
247 #if DSHOT_CONF_TIM3
248  dshotStart(&DSHOTD3, &dshotcfg3);
249 #endif
250 #if DSHOT_CONF_TIM4
251  dshotStart(&DSHOTD4, &dshotcfg4);
252 #endif
253 #if DSHOT_CONF_TIM5
254  dshotStart(&DSHOTD5, &dshotcfg5);
255 #endif
256 #if DSHOT_CONF_TIM8
257  dshotStart(&DSHOTD8, &dshotcfg8);
258 #endif
259 #if DSHOT_CONF_TIM9
260  dshotStart(&DSHOTD9, &dshotcfg9);
261 #endif
262 
263 #if PERIODIC_TELEMETRY
265 #endif
266 }
267 
268 
270 {
271 #ifdef DSHOT_SERVO_0
273 #endif
274 #ifdef DSHOT_SERVO_1
276 #endif
277 #ifdef DSHOT_SERVO_2
279 #endif
280 #ifdef DSHOT_SERVO_3
282 #endif
283 #ifdef DSHOT_SERVO_4
285 #endif
286 #ifdef DSHOT_SERVO_5
288 #endif
289 #ifdef DSHOT_SERVO_6
290  dshotSetThrottle(&DSHOT_SERVO_6_DRIVER, DSHOT_SERVO_6_CHANNEL, actuators_dshot_values[DSHOT_SERVO_6].cmd);
291 #endif
292 #ifdef DSHOT_SERVO_7
294 #endif
295 #ifdef DSHOT_SERVO_8
297 #endif
298 #ifdef DSHOT_SERVO_9
300 #endif
301 #ifdef DSHOT_SERVO_10
303 #endif
304 #ifdef DSHOT_SERVO_11
305  dshotSetThrottle(&DSHOT_SERVO_11_DRIVER, DSHOT_SERVO_11_CHANNEL, actuators_dshot_values[DSHOT_SERVO_11].cmd);
306 #endif
307 
308 #if DSHOT_CONF_TIM1
309  dshotSendFrame(&DSHOTD1);
310 #endif
311 #if DSHOT_CONF_TIM2
312  dshotSendFrame(&DSHOTD2);
313 #endif
314 #if DSHOT_CONF_TIM3
315  dshotSendFrame(&DSHOTD3);
316 #endif
317 #if DSHOT_CONF_TIM4
318  dshotSendFrame(&DSHOTD4);
319 #endif
320 #if DSHOT_CONF_TIM5
321  dshotSendFrame(&DSHOTD5);
322 #endif
323 #if DSHOT_CONF_TIM8
324  dshotSendFrame(&DSHOTD8);
325 #endif
326 #if DSHOT_CONF_TIM9
327  dshotSendFrame(&DSHOTD9);
328 #endif
329 
330 
331  struct rpm_act_t rpm_list[ACTUATORS_DSHOT_NB] = { 0 };
332  for (uint8_t i = 0; i < ACTUATORS_DSHOT_NB; i++) {
333  rpm_list[i].actuator_idx = ACTUATORS_DSHOT_OFFSET + i;
334  rpm_list[i].rpm = 0;
335  if (actuators_dshot_values[i].activated) {
337  rpm_list[i].rpm = dtelem->rpm;
338  }
339  }
340  AbiSendMsgRPM(RPM_DSHOT_ID, rpm_list, ACTUATORS_DSHOT_NB);
341 }
Main include for ABI (AirBorneInterface).
#define RPM_DSHOT_ID
bool activated
current dshot channel is activated
float cmd
command
float current
current
float voltage
motor current
#define ACTUATORS_DSHOT_NB
Maxnum number of DSHOT commands This should be large enough for max applications: 8 motors +1 in case...
float rpm
rpm
#define ACTUATORS_DSHOT_OFFSET
In normal DSHOT, first 48 values are special commands this offset allow to use 0 as the no-throttle c...
#define DSHOT_SERVO_2_GPIO
Definition: board.h:341
#define DSHOT_SERVO_4_DRIVER
Definition: board.h:316
#define DSHOT_SERVO_2_CHANNEL
Definition: board.h:345
#define DSHOT_SERVO_2_AF
Definition: board.h:343
#define DSHOT_SERVO_5_DRIVER
Definition: board.h:322
#define DSHOT_SERVO_0_AF
Definition: board.h:337
#define DSHOT_SERVO_3_GPIO
Definition: board.h:347
#define DSHOT_CONF2_DEF
Definition: board.h:325
#define DSHOT_SERVO_2
Definition: board.h:340
#define DSHOT_SERVO_5_GPIO
Definition: board.h:319
#define DSHOT_SERVO_5
Definition: board.h:318
#define DSHOT_SERVO_1_DRIVER
Definition: board.h:310
#define DSHOT_SERVO_0_PIN
Definition: board.h:336
#define DSHOT_SERVO_1_PIN
Definition: board.h:308
#define DSHOT_SERVO_0_DRIVER
Definition: board.h:338
#define DSHOT_SERVO_3_PIN
Definition: board.h:348
#define DSHOT_SERVO_1_AF
Definition: board.h:309
#define DSHOT_SERVO_5_CHANNEL
Definition: board.h:323
#define DSHOT_CONF3_DEF
Definition: board.h:362
#define DSHOT_SERVO_0_CHANNEL
Definition: board.h:339
#define DSHOT_SERVO_1
Definition: board.h:306
#define DSHOT_SERVO_1_GPIO
Definition: board.h:307
#define DSHOT_SERVO_3_CHANNEL
Definition: board.h:351
#define DSHOT_SERVO_4_PIN
Definition: board.h:314
#define DSHOT_SERVO_3
Definition: board.h:346
#define DSHOT_SERVO_2_PIN
Definition: board.h:342
#define DSHOT_SERVO_1_CHANNEL
Definition: board.h:311
#define DSHOT_SERVO_3_AF
Definition: board.h:349
#define DSHOT_SERVO_5_PIN
Definition: board.h:320
#define DSHOT_SERVO_4
Definition: board.h:312
#define DSHOT_SERVO_0_GPIO
Definition: board.h:335
#define DSHOT_SERVO_5_AF
Definition: board.h:321
#define DSHOT_SERVO_3_DRIVER
Definition: board.h:350
#define DSHOT_SERVO_4_CHANNEL
Definition: board.h:317
#define DSHOT_SERVO_2_DRIVER
Definition: board.h:344
#define DSHOT_SERVO_4_AF
Definition: board.h:315
#define DSHOT_SERVO_4_GPIO
Definition: board.h:313
#define DSHOT_SERVO_0
Definition: board.h:334
void gpio_setup_pin_af(ioportid_t port, uint16_t pin, uint8_t af, bool is_output)
Setup a gpio for input or output with alternate function.
Definition: gpio_arch.c:61
void actuators_dshot_arch_init(void)
Arch dependent init.
struct dshot_private actuators_dshot_private[ACTUATORS_DSHOT_NB]
#define CONCAT_GPIO(num, name)
static void dshot_set_struct(struct dshot *ds, struct dshot_private *dsp, DSHOTDriver *driver, uint32_t channel)
struct dshot actuators_dshot_values[ACTUATORS_DSHOT_NB]
static void dshot_init_struct(struct dshot *ds)
static void esc_msg_send(struct transport_tx *trans, struct link_device *dev)
void actuators_dshot_arch_commit(void)
DSHOTDriver * driver
struct Electrical electrical
Definition: electrical.c:66
Interface for electrical status: supply voltage, current, battery status, etc.
float vsupply
supply voltage in V
Definition: electrical.h:45
void dshotStart(DSHOTDriver *driver, const DSHOTConfig *config)
Configures and activates the DSHOT peripheral.
Definition: esc_dshot.c:122
void dshotSetThrottle(DSHOTDriver *driver, const uint8_t index, const uint16_t throttle)
prepare throttle order for specified ESC
Definition: esc_dshot.c:210
void dshotSendFrame(DSHOTDriver *driver)
send throttle order
Definition: esc_dshot.c:302
const DshotTelemetry * dshotGetTelemetry(const DSHOTDriver *driver, const uint32_t index)
return last received telemetry data
Definition: esc_dshot.c:342
DSHOT driver based on ChibiOS.
DSHOT Driver configuration structure.
Definition: esc_dshot.h:155
telemetry packed as sent by some KISS ESC
Definition: esc_dshot.h:125
Some architecture independent helper functions for GPIOs.
#define DSHOT_SERVO_10_AF
#define DSHOT_SERVO_9_PIN
#define DSHOT_SERVO_9_DRIVER
#define DSHOT_SERVO_8
#define DSHOT_SERVO_7_GPIO
#define DSHOT_SERVO_8_CHANNEL
#define DSHOT_SERVO_8_AF
#define DSHOT_SERVO_8_PIN
#define DSHOT_SERVO_7_AF
#define DSHOT_SERVO_9_AF
#define DSHOT_SERVO_7_PIN
#define DSHOT_SERVO_10_PIN
#define DSHOT_SERVO_7_CHANNEL
#define DSHOT_SERVO_10_GPIO
#define DSHOT_SERVO_9_CHANNEL
#define DSHOT_CONF4_DEF
#define DSHOT_SERVO_9_GPIO
#define DSHOT_SERVO_10
#define DSHOT_SERVO_10_CHANNEL
#define DSHOT_SERVO_8_DRIVER
#define DSHOT_SERVO_8_GPIO
#define DSHOT_SERVO_9
#define DSHOT_SERVO_7_DRIVER
#define DSHOT_SERVO_10_DRIVER
#define DSHOT_SERVO_7
int32_t rpm
Definition: actuators.h:46
uint8_t actuator_idx
Definition: actuators.h:45
Specific RAM section for DMA usage on F7.
#define IN_DMA_SECTION_NOINIT(var)
Definition: ram_arch.h:83
uint16_t rpm
Definition: rpm_sensor.c:33
#define FALSE
Definition: std.h:5
static const struct usb_device_descriptor dev
Definition: usb_ser_hw.c:74
DSHOT driver structure.
Definition: esc_dshot.h:228
int8_t register_periodic_telemetry(struct periodic_telemetry *_pt, uint8_t _id, telemetry_cb _cb)
Register a telemetry callback function.
Definition: telemetry.c:51
Periodic telemetry system header (includes downlink utility and generated code).
#define DefaultPeriodic
Set default periodic telemetry.
Definition: telemetry.h:66
unsigned int uint32_t
Typedef defining 32 bit unsigned int type.
Definition: vl53l1_types.h:78
unsigned char uint8_t
Typedef defining 8 bit unsigned char type.
Definition: vl53l1_types.h:98