mirror of
https://github.com/paparazzi/paparazzi.git
synced 2026-05-23 04:45:37 +08:00
[radio] rewrite the Spektrum driver to be generic (#2250)
This is based on #1799 and replace it. Now, the normal UART driver is used instead of the specific code. It makes it possible to use on only arch, including ChibiOS. Binding is also possible, but for boards using ChibiOS and SD logger, it is recommended to disable it for the binding process as the LSE clock required by the RTC is longer to start (bind pulses should be issued before 200ms after power up). The configuration is backward compatible and some defines in the boards' header could be even removed. Only Apogee, Chimera and Elle0 have been updated as it is the only board tested for now. There is no harm to keep the old defines.
This commit is contained in:
committed by
GitHub
parent
578ffe2b4d
commit
424cd788f5
@@ -18,7 +18,7 @@ UBX GPS / HMC58XX mag (drotek)
|
||||
<configure name="PERIODIC_FREQUENCY" value="100"/>
|
||||
</target>
|
||||
<target name="sim" board="pc">
|
||||
<module name="radio_control" type="ppm"/>
|
||||
<module name="radio_control" type="spektrum"/>
|
||||
</target>
|
||||
|
||||
<!-- Communication -->
|
||||
|
||||
@@ -8,50 +8,70 @@
|
||||
Define USE_DSMX on STM32 microcontrollers to bind in DSMX instead of DSM2
|
||||
</description>
|
||||
<configure name="RADIO_CONTROL_LED" value="none|num" description="LED number or 'none' to disable"/>
|
||||
<configure name="RADIO_CONTROL_SPEKTRUM_PRIMARY_PORT" value="num" description="UART number for primary spektrum receiver"/>
|
||||
<configure name="RADIO_CONTROL_SPEKTRUM_SECONDARY_PORT" value="num" description="UART number for optional secondary spektrum receiver"/>
|
||||
<configure name="RADIO_CONTROL_SPEKTRUM_PRIMARY_PORT" value="uartX" description="UART for primary spektrum receiver"/>
|
||||
<configure name="RADIO_CONTROL_SPEKTRUM_SECONDARY_PORT" value="uartX" description="UART for optional secondary spektrum receiver"/>
|
||||
<configure name="USE_SECONDARY_SPEKTRUM_RECEIVER" value="0|1" description="enable secondary receiver (default: disabled)"/>
|
||||
<define name="USE_DSMX" value="FALSE|TRUE" description="Set to true to use DSMX instead of DSM2"/>
|
||||
</doc>
|
||||
<header>
|
||||
<file name="spektrum.h" dir="subsystems/radio_control"/>
|
||||
</header>
|
||||
<makefile target="ap|fbw|sim|nps|hitl|test_radio_control">
|
||||
<makefile target="ap|fbw|sim|nps|test_radio_control">
|
||||
<configure name="RADIO_CONTROL_LED" default="none"/>
|
||||
<define name="RADIO_CONTROL_LED" value="$(RADIO_CONTROL_LED)" cond="ifneq ($(RADIO_CONTROL_LED),none)"/>
|
||||
<define name="RADIO_CONTROL_TYPE_H" value="subsystems/radio_control/spektrum.h" type="string"/>
|
||||
<raw>
|
||||
ifeq ($(ARCH), lpc21)
|
||||
ifndef RADIO_CONTROL_SPEKTRUM_MODEL
|
||||
RADIO_CONTROL_SPEKTRUM_MODEL=\"subsystems/radio_control/spektrum_dx7se.h\"
|
||||
endif
|
||||
RC_CFLAGS += -DRADIO_CONTROL_SPEKTRUM_MODEL_H=$(RADIO_CONTROL_SPEKTRUM_MODEL)
|
||||
endif
|
||||
</raw>
|
||||
</makefile>
|
||||
<makefile target="fbw|sim|nps|hitl|test_radio_control">
|
||||
<configure name="USE_SECONDARY_SPEKTRUM_RECEIVER" default="0"/>
|
||||
<makefile target="fbw|test_radio_control">
|
||||
<define name="RADIO_CONTROL"/>
|
||||
<define name="RADIO_CONTROL_BIND_IMPL_FUNC" value="radio_control_spektrum_try_bind"/>
|
||||
<define name="RADIO_CONTROL_SPEKTRUM_PRIMARY_PORT" value="SPEKTRUM_$(RADIO_CONTROL_SPEKTRUM_PRIMARY_PORT)"/>
|
||||
<define name="OVERRIDE_$(RADIO_CONTROL_SPEKTRUM_PRIMARY_PORT)_IRQ_HANDLER"/>
|
||||
<define name="RADIO_CONTROL_SPEKTRUM_SECONDARY_PORT" value="SPEKTRUM_$(RADIO_CONTROL_SPEKTRUM_SECONDARY_PORT)" cond="ifneq ($(USE_SECONDARY_SPEKTRUM_RECEIVER),0)"/>
|
||||
<define name="OVERRIDE_$(RADIO_CONTROL_SPEKTRUM_PRIMARY_PORT)_IRQ_HANDLER" cond="ifneq ($(USE_SECONDARY_SPEKTRUM_RECEIVER),0)"/>
|
||||
<define name="RADIO_CONTROL_TYPE_H" value="subsystems/radio_control/spektrum.h" type="string"/>
|
||||
<define name="RADIO_CONTROL_BIND_IMPL_FUNC" value="spektrum_try_bind"/>
|
||||
|
||||
<configure name="SPEKTRUM_PRIMARY_UART" value="$(RADIO_CONTROL_SPEKTRUM_PRIMARY_PORT)" case="upper|lower"/>
|
||||
<define name="USE_$(SPEKTRUM_PRIMARY_UART_UPPER)"/>
|
||||
<define name="SPEKTRUM_PRIMARY_UART" value="$(SPEKTRUM_PRIMARY_UART_LOWER)"/>
|
||||
<define name="SPEKTRUM_PRIMARY_UART_UPPER" value="$(SPEKTRUM_PRIMARY_UART_UPPER)_GPIO"/>
|
||||
<define name="$(SPEKTRUM_PRIMARY_UART_UPPER)_BAUD" value="B115200"/>
|
||||
<define name="USE_$(SPEKTRUM_PRIMARY_UART_UPPER)_TX" value="FALSE"/>
|
||||
|
||||
<configure name="SPEKTRUM_SECONDARY_UART" value="$(RADIO_CONTROL_SPEKTRUM_SECONDARY_PORT)" case="upper|lower"/>
|
||||
<configure name="USE_SECONDARY_SPEKTRUM_RECEIVER" default="0"/>
|
||||
<define name="USE_$(SPEKTRUM_SECONDARY_UART_UPPER)" cond="ifneq ($(USE_SECONDARY_SPEKTRUM_RECEIVER),0)"/>
|
||||
<define name="SPEKTRUM_SECONDARY_UART" value="$(SPEKTRUM_SECONDARY_UART_LOWER)" cond="ifneq ($(USE_SECONDARY_SPEKTRUM_RECEIVER),0)"/>
|
||||
<define name="SPEKTRUM_SECONDARY_UART_UPPER" value="$(SPEKTRUM_SECONDARY_UART_UPPER)_GPIO" cond="ifneq ($(USE_SECONDARY_SPEKTRUM_RECEIVER),0)"/>
|
||||
<define name="$(SPEKTRUM_SECONDARY_UART_UPPER)_BAUD" value="B115200" cond="ifneq ($(USE_SECONDARY_SPEKTRUM_RECEIVER),0)"/>
|
||||
<define name="USE_$(SPEKTRUM_SECONDARY_UART_UPPER)_TX" value="FALSE" cond="ifneq ($(USE_SECONDARY_SPEKTRUM_RECEIVER),0)"/>
|
||||
|
||||
<file name="radio_control.c" dir="subsystems"/>
|
||||
<file name="spektrum.c" dir="subsystems/radio_control"/>
|
||||
<file name="spektrum_arch.c" dir="$(SRC_ARCH)/subsystems/radio_control"/>
|
||||
</makefile>
|
||||
<makefile target="ap">
|
||||
<define name="RADIO_CONTROL_TYPE_H" value="subsystems/radio_control/spektrum.h" type="string"/>
|
||||
</makefile>
|
||||
<makefile target="ap" cond="ifeq (,$(findstring $(SEPARATE_FBW),1 TRUE))">
|
||||
<configure name="USE_SECONDARY_SPEKTRUM_RECEIVER" default="0"/>
|
||||
<define name="RADIO_CONTROL"/>
|
||||
<define name="RADIO_CONTROL_BIND_IMPL_FUNC" value="radio_control_spektrum_try_bind"/>
|
||||
<define name="RADIO_CONTROL_SPEKTRUM_PRIMARY_PORT" value="SPEKTRUM_$(RADIO_CONTROL_SPEKTRUM_PRIMARY_PORT)"/>
|
||||
<define name="OVERRIDE_$(RADIO_CONTROL_SPEKTRUM_PRIMARY_PORT)_IRQ_HANDLER"/>
|
||||
<define name="RADIO_CONTROL_SPEKTRUM_SECONDARY_PORT" value="SPEKTRUM_$(RADIO_CONTROL_SPEKTRUM_SECONDARY_PORT)" cond="ifneq ($(USE_SECONDARY_SPEKTRUM_RECEIVER),0)"/>
|
||||
<define name="OVERRIDE_$(RADIO_CONTROL_SPEKTRUM_PRIMARY_PORT)_IRQ_HANDLER" cond="ifneq ($(USE_SECONDARY_SPEKTRUM_RECEIVER),0)"/>
|
||||
<define name="RADIO_CONTROL_BIND_IMPL_FUNC" value="spektrum_try_bind"/>
|
||||
|
||||
<configure name="SPEKTRUM_PRIMARY_UART" value="$(RADIO_CONTROL_SPEKTRUM_PRIMARY_PORT)" case="upper|lower"/>
|
||||
<define name="USE_$(SPEKTRUM_PRIMARY_UART_UPPER)"/>
|
||||
<define name="SPEKTRUM_PRIMARY_UART" value="$(SPEKTRUM_PRIMARY_UART_LOWER)"/>
|
||||
<define name="SPEKTRUM_PRIMARY_UART_UPPER" value="$(SPEKTRUM_PRIMARY_UART_UPPER)_GPIO"/>
|
||||
<define name="$(SPEKTRUM_PRIMARY_UART_UPPER)_BAUD" value="B115200"/>
|
||||
<define name="USE_$(SPEKTRUM_PRIMARY_UART_UPPER)_TX" value="FALSE"/>
|
||||
|
||||
<configure name="SPEKTRUM_SECONDARY_UART" value="$(RADIO_CONTROL_SPEKTRUM_SECONDARY_PORT)" case="upper|lower"/>
|
||||
<configure name="USE_SECONDARY_SPEKTRUM_RECEIVER" default="0"/>
|
||||
<define name="USE_$(SPEKTRUM_SECONDARY_UART_UPPER)" cond="ifneq ($(USE_SECONDARY_SPEKTRUM_RECEIVER),0)"/>
|
||||
<define name="SPEKTRUM_SECONDARY_UART" value="$(SPEKTRUM_SECONDARY_UART_LOWER)" cond="ifneq ($(USE_SECONDARY_SPEKTRUM_RECEIVER),0)"/>
|
||||
<define name="SPEKTRUM_SECONDARY_UART_UPPER" value="$(SPEKTRUM_SECONDARY_UART_UPPER)_GPIO" cond="ifneq ($(USE_SECONDARY_SPEKTRUM_RECEIVER),0)"/>
|
||||
<define name="$(SPEKTRUM_SECONDARY_UART_UPPER)_BAUD" value="B115200" cond="ifneq ($(USE_SECONDARY_SPEKTRUM_RECEIVER),0)"/>
|
||||
<define name="USE_$(SPEKTRUM_SECONDARY_UART_UPPER)_TX" value="FALSE" cond="ifneq ($(USE_SECONDARY_SPEKTRUM_RECEIVER),0)"/>
|
||||
|
||||
<file name="radio_control.c" dir="subsystems"/>
|
||||
<file name="spektrum.c" dir="subsystems/radio_control"/>
|
||||
<file name="spektrum_arch.c" dir="$(SRC_ARCH)/subsystems/radio_control"/>
|
||||
</makefile>
|
||||
<makefile target="sim|nps|hitl">
|
||||
<define name="RADIO_CONTROL"/>
|
||||
<define name="RADIO_CONTROL_TYPE_H" value="subsystems/radio_control/spektrum_arch.h" type="string"/>
|
||||
<file name="radio_control.c" dir="subsystems"/>
|
||||
<file_arch name="spektrum_arch.c" dir="subsystems/radio_control"/>
|
||||
</makefile>
|
||||
</module>
|
||||
|
||||
|
||||
@@ -94,8 +94,15 @@ uint32_t get_sys_time_msec(void)
|
||||
*/
|
||||
void sys_time_usleep(uint32_t us)
|
||||
{
|
||||
uint64_t wait_st = ((uint64_t)us * CH_CFG_ST_FREQUENCY) / 1000000UL;
|
||||
chThdSleep((systime_t)wait_st);
|
||||
if (us < 1000) {
|
||||
// for small time, use the polled version instead of thread sleep
|
||||
chSysDisable();
|
||||
chSysPolledDelayX(US2RTC(STM32_HCLK, us));
|
||||
chSysEnable();
|
||||
} else {
|
||||
uint64_t wait_st = ((uint64_t)us * CH_CFG_ST_FREQUENCY) / 1000000UL;
|
||||
chThdSleep((systime_t)wait_st);
|
||||
}
|
||||
}
|
||||
|
||||
void sys_time_msleep(uint16_t ms)
|
||||
|
||||
@@ -1,34 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2008-2009 Antoine Drouin <poinix@gmail.com>
|
||||
*
|
||||
* This file is part of paparazzi.
|
||||
*
|
||||
* paparazzi is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* paparazzi is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with paparazzi; see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include "subsystems/radio_control.h"
|
||||
#include "subsystems/radio_control/spektrum_arch.h"
|
||||
|
||||
bool rc_spk_parser_status;
|
||||
uint8_t rc_spk_parser_idx;
|
||||
uint8_t rc_spk_parser_buf[RADIO_CONTROL_NB_CHANNEL * 2];
|
||||
const int16_t rc_spk_throw[RADIO_CONTROL_NB_CHANNEL] = RC_SPK_THROWS;
|
||||
|
||||
void radio_control_impl_init(void)
|
||||
{
|
||||
rc_spk_parser_status = RC_SPK_STA_UNINIT;
|
||||
rc_spk_parser_idx = 0;
|
||||
}
|
||||
@@ -1,100 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2009-2010 The Paparazzi Team
|
||||
*
|
||||
* This file is part of paparazzi.
|
||||
*
|
||||
* paparazzi is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* paparazzi is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with paparazzi; see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef RADIO_CONTROL_SPEKTRUM_ARCH_H
|
||||
#define RADIO_CONTROL_SPEKTRUM_ARCH_H
|
||||
|
||||
#include "std.h"
|
||||
#include "mcu_periph/uart.h"
|
||||
|
||||
#include RADIO_CONTROL_SPEKTRUM_MODEL_H
|
||||
|
||||
#define RC_SPK_SYNC_1 0x03
|
||||
|
||||
#define RC_SPK_STA_UNINIT 0
|
||||
#define RC_SPK_STA_GOT_SYNC_1 1
|
||||
#define RC_SPK_STA_GOT_SYNC_2 2
|
||||
|
||||
extern bool rc_spk_parser_status;
|
||||
extern uint8_t rc_spk_parser_idx;
|
||||
extern uint8_t rc_spk_parser_buf[RADIO_CONTROL_NB_CHANNEL * 2];
|
||||
|
||||
#define MAX_SPK 344
|
||||
|
||||
|
||||
extern const int16_t rc_spk_throw[RADIO_CONTROL_NB_CHANNEL];
|
||||
|
||||
#define __RcLink(dev, _x) dev##_x
|
||||
#define _RcLink(dev, _x) __RcLink(dev, _x)
|
||||
#define RcLink(_x) _RcLink(RADIO_CONTROL_SPEKTRUM_PRIMARY_PORT, _x)
|
||||
|
||||
#define RcLinkChAvailable() RcLink(ChAvailable())
|
||||
#define RcLinkGetCh() RcLink(Getch())
|
||||
|
||||
#define RadioControlEventImpl(_received_frame_handler) { \
|
||||
while (RcLinkChAvailable()) { \
|
||||
int8_t c = RcLinkGetCh(); \
|
||||
switch (rc_spk_parser_status) { \
|
||||
case RC_SPK_STA_UNINIT: \
|
||||
if (c==RC_SPK_SYNC_1) \
|
||||
rc_spk_parser_status = RC_SPK_STA_GOT_SYNC_1; \
|
||||
break; \
|
||||
case RC_SPK_STA_GOT_SYNC_1: \
|
||||
if (c==RC_SPK_SYNC_2) { \
|
||||
rc_spk_parser_status = RC_SPK_STA_GOT_SYNC_2; \
|
||||
rc_spk_parser_idx = 0; \
|
||||
} \
|
||||
else \
|
||||
rc_spk_parser_status = RC_SPK_STA_UNINIT; \
|
||||
break; \
|
||||
case RC_SPK_STA_GOT_SYNC_2: \
|
||||
rc_spk_parser_buf[rc_spk_parser_idx] = c; \
|
||||
rc_spk_parser_idx++; \
|
||||
if (rc_spk_parser_idx >= 2*RADIO_CONTROL_NB_CHANNEL) { \
|
||||
rc_spk_parser_status = RC_SPK_STA_UNINIT; \
|
||||
radio_control.frame_cpt++; \
|
||||
radio_control.time_since_last_frame = 0; \
|
||||
radio_control.status = RC_OK; \
|
||||
uint8_t i; \
|
||||
for (i=0;i<RADIO_CONTROL_NB_CHANNEL;i++) { \
|
||||
const int16_t tmp = (rc_spk_parser_buf[2*i]<<8) + \
|
||||
rc_spk_parser_buf[2*i+1]; \
|
||||
/*const int16_t chan = (tmp&0xFC00) >> 10;*/ \
|
||||
const int16_t val = (tmp&0x03FF) - 512; \
|
||||
radio_control.values[i] = val; \
|
||||
radio_control.values[i] *= rc_spk_throw[i]; \
|
||||
if (i==RADIO_CONTROL_THROTTLE) { \
|
||||
radio_control.values[i] += MAX_PPRZ; \
|
||||
radio_control.values[i] /= 2; \
|
||||
} \
|
||||
} \
|
||||
_received_frame_handler(); \
|
||||
} \
|
||||
break; \
|
||||
default: \
|
||||
rc_spk_parser_status = RC_SPK_STA_UNINIT; \
|
||||
} \
|
||||
} \
|
||||
}
|
||||
|
||||
|
||||
#endif /* RADIO_CONTROL_SPEKTRUM_ARCH_H */
|
||||
@@ -27,7 +27,7 @@
|
||||
*/
|
||||
|
||||
#include "subsystems/radio_control.h"
|
||||
#include "subsystems/radio_control/spektrum.h"
|
||||
#include "subsystems/radio_control/spektrum_arch.h"
|
||||
#include "std.h"
|
||||
#include <inttypes.h>
|
||||
|
||||
@@ -39,13 +39,11 @@
|
||||
|
||||
static bool spektrum_available;
|
||||
|
||||
void radio_control_spektrum_try_bind(void) {}
|
||||
|
||||
void radio_control_impl_init(void)
|
||||
{
|
||||
spektrum_available = false;
|
||||
}
|
||||
void RadioControlEventImp(void (*frame_handler)(void))
|
||||
void spektrum_event(void (*frame_handler)(void))
|
||||
{
|
||||
if (spektrum_available) {
|
||||
radio_control.frame_cpt++;
|
||||
@@ -56,6 +54,8 @@ void RadioControlEventImp(void (*frame_handler)(void))
|
||||
spektrum_available = false;
|
||||
}
|
||||
|
||||
void spektrum_try_bind(void) {}
|
||||
|
||||
#if USE_NPS
|
||||
#ifdef RADIO_CONTROL
|
||||
void radio_control_feed(void)
|
||||
|
||||
@@ -23,43 +23,11 @@
|
||||
#ifndef RADIO_CONTROL_SPEKTRUM_ARCH_H
|
||||
#define RADIO_CONTROL_SPEKTRUM_ARCH_H
|
||||
|
||||
#include "subsystems/radio_control/spektrum_radio.h"
|
||||
|
||||
/*
|
||||
* All Spektrum and JR 2.4 GHz transmitters
|
||||
* have the same channel assignments.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef RADIO_CONTROL_NB_CHANNEL
|
||||
#define RADIO_CONTROL_NB_CHANNEL 12
|
||||
#endif
|
||||
|
||||
#if RADIO_CONTROL_NB_CHANNEL > 12
|
||||
#error "RADIO_CONTROL_NB_CHANNEL mustn't be higher than 12."
|
||||
#endif
|
||||
|
||||
/* channel assignments */
|
||||
#define RADIO_THROTTLE 0
|
||||
#define RADIO_ROLL 1
|
||||
#define RADIO_PITCH 2
|
||||
#define RADIO_YAW 3
|
||||
#define RADIO_GEAR 4
|
||||
#define RADIO_FLAP 5
|
||||
#define RADIO_AUX1 5
|
||||
#define RADIO_AUX2 6
|
||||
#define RADIO_AUX3 7
|
||||
#define RADIO_AUX4 8
|
||||
#define RADIO_AUX5 9
|
||||
#define RADIO_AUX6 10
|
||||
#define RADIO_AUX7 11
|
||||
|
||||
/* really for a 9 channel transmitter
|
||||
we would swap the order of these */
|
||||
#ifndef RADIO_MODE
|
||||
#define RADIO_MODE RADIO_GEAR
|
||||
#endif
|
||||
|
||||
extern void RadioControlEventImp(void (*_received_frame_handler)(void));
|
||||
extern void spektrum_event(void (*_received_frame_handler)(void));
|
||||
#define RadioControlEventImp spektrum_event
|
||||
extern void spektrum_try_bind(void);
|
||||
|
||||
#if USE_NPS
|
||||
extern void radio_control_feed(void);
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -917,6 +917,28 @@
|
||||
#define PPM_CHANNEL ICU_CHANNEL_1
|
||||
#define PPM_TIMER ICUD1
|
||||
|
||||
/*
|
||||
* Spektrum
|
||||
*/
|
||||
|
||||
// shorter wait with chibios as the RTC oscillator takes longer to stabilize
|
||||
#define SPEKTRUM_BIND_WAIT 30000
|
||||
|
||||
/* The line that is pulled low at power up to initiate the bind process
|
||||
* PB15: AUX4
|
||||
*/
|
||||
#define SPEKTRUM_BIND_PIN GPIO15
|
||||
#define SPEKTRUM_BIND_PIN_PORT GPIOB
|
||||
|
||||
/* The line used to send the pulse train for the bind process
|
||||
* When using UART2 on Apogee, this as to be a different pin than the uart2 rx
|
||||
* Default pin for this is PA8: PPM_IN
|
||||
*/
|
||||
#ifndef SPEKTRUM_PRIMARY_BIND_CONF_PORT
|
||||
#define SPEKTRUM_PRIMARY_BIND_CONF_PORT GPIOA
|
||||
#define SPEKTRUM_PRIMARY_BIND_CONF_PIN GPIO8
|
||||
#endif
|
||||
|
||||
/*
|
||||
* PWM input
|
||||
*/
|
||||
|
||||
@@ -426,24 +426,6 @@
|
||||
#define SPEKTRUM_PRIMARY_BIND_CONF_PIN GPIO8
|
||||
#endif
|
||||
|
||||
/* Configuration of UART2 for Spektrum */
|
||||
#define SPEKTRUM_UART2_RCC RCC_USART2
|
||||
#define SPEKTRUM_UART2_BANK GPIOA
|
||||
#define SPEKTRUM_UART2_PIN GPIO3
|
||||
#define SPEKTRUM_UART2_AF GPIO_AF7
|
||||
#define SPEKTRUM_UART2_IRQ NVIC_USART2_IRQ
|
||||
#define SPEKTRUM_UART2_ISR usart2_isr
|
||||
#define SPEKTRUM_UART2_DEV USART2
|
||||
|
||||
/* Configuration of UART6 for Spektrum */
|
||||
#define SPEKTRUM_UART6_RCC RCC_USART6
|
||||
#define SPEKTRUM_UART6_BANK GPIOC
|
||||
#define SPEKTRUM_UART6_PIN GPIO7
|
||||
#define SPEKTRUM_UART6_AF GPIO_AF8
|
||||
#define SPEKTRUM_UART6_IRQ NVIC_USART6_IRQ
|
||||
#define SPEKTRUM_UART6_ISR usart6_isr
|
||||
#define SPEKTRUM_UART6_DEV USART6
|
||||
|
||||
/*
|
||||
* IRQ Priorities
|
||||
*/
|
||||
|
||||
@@ -384,14 +384,37 @@
|
||||
|
||||
/**
|
||||
* UART3 (XBee slot), UART8 (GPS) and UART1 (Companion)
|
||||
* are configured as UART from ChibiOS board file
|
||||
* are configured as UART from ChibiOS board file by default
|
||||
*/
|
||||
|
||||
#define UART1_GPIO_PORT_TX GPIOB
|
||||
#define UART1_GPIO_TX GPIO6
|
||||
#define UART1_GPIO_PORT_RX GPIOB
|
||||
#define UART1_GPIO_RX GPIO7
|
||||
#define UART1_GPIO_AF 7
|
||||
|
||||
#define UART3_GPIO_PORT_TX GPIOD
|
||||
#define UART3_GPIO_TX GPIO8
|
||||
#define UART3_GPIO_PORT_RX GPIOD
|
||||
#define UART3_GPIO_RX GPIO9
|
||||
#define UART3_GPIO_AF 7
|
||||
|
||||
#define UART8_GPIO_PORT_TX GPIOE
|
||||
#define UART8_GPIO_TX GPIO0
|
||||
#define UART8_GPIO_PORT_RX GPIOE
|
||||
#define UART8_GPIO_RX GPIO1
|
||||
#define UART8_GPIO_AF 8
|
||||
|
||||
/**
|
||||
* SBUS
|
||||
* SBUS / Spektrum port
|
||||
*
|
||||
* Recommended config:
|
||||
*
|
||||
* primary SBUS port is UART7, a.k.a. RC2 on Chimera board
|
||||
* secondary port (in dual driver) is UART4, a.k.a. RC1 on Chimera board
|
||||
*
|
||||
* primary Spektrum port is UART4, a.k.a. RC1 on Chimera board
|
||||
* secondary port is UART7, a.k.a. RC2 on Chimera board
|
||||
*/
|
||||
|
||||
// In case, do dynamic config of UARTs
|
||||
@@ -405,31 +428,18 @@
|
||||
|
||||
#define USE_UART4_RX TRUE
|
||||
#define USE_UART4_TX FALSE
|
||||
#define UART4_GPIO_PORT_RX GPIOE
|
||||
#define UART4_GPIO_RX GPIO7
|
||||
#define UART4_GPIO_PORT_RX GPIOA
|
||||
#define UART4_GPIO_RX GPIO1
|
||||
#define UART4_GPIO_AF 8
|
||||
|
||||
/*
|
||||
* Spektrum
|
||||
*
|
||||
* Not supported yet in chibios arch
|
||||
* Only here for future reference
|
||||
*
|
||||
* primary Spektrum port is UART4, a.k.a. RC1 on Chimera board
|
||||
* secondary port is UART7, a.k.a. RC2 on Chimera board
|
||||
/* The line that is pulled low at power up to initiate the bind process
|
||||
* PC7: AUX7
|
||||
*/
|
||||
/* The line that is pulled low at power up to initiate the bind process */
|
||||
/* These are not common between versions of lisa/mx and thus defined in the
|
||||
* version specific header files. */
|
||||
#define SPEKTRUM_UART4_BANK UART4_GPIO_PORT_RX
|
||||
#define SPEKTRUM_UART4_PIN UART4_GPIO_RX
|
||||
#define SPEKTRUM_UART4_AF UART4_GPIO_AF
|
||||
#define SPEKTRUM_UART4_DEV SD4
|
||||
#define SPEKTRUM_BIND_PIN GPIO7
|
||||
#define SPEKTRUM_BIND_PIN_PORT GPIOC
|
||||
|
||||
#define SPEKTRUM_UART7_BANK UART7_GPIO_PORT_RX
|
||||
#define SPEKTRUM_UART7_PIN UART7_GPIO_RX
|
||||
#define SPEKTRUM_UART7_AF UART7_GPIO_AF
|
||||
#define SPEKTRUM_UART7_DEV SD7
|
||||
// no wait with chibios as the RTC oscillator takes longer to stabilize
|
||||
#define SPEKTRUM_BIND_WAIT 30000
|
||||
|
||||
/**
|
||||
* PPM radio defines
|
||||
|
||||
@@ -43,7 +43,11 @@
|
||||
#define STM32_HSI_ENABLED TRUE
|
||||
#define STM32_LSI_ENABLED FALSE
|
||||
#define STM32_HSE_ENABLED TRUE
|
||||
#if HAL_USE_RTC // disable LSE init if not needed to start faster
|
||||
#define STM32_LSE_ENABLED TRUE
|
||||
#else
|
||||
#define STM32_LSE_ENABLED FALSE
|
||||
#endif
|
||||
#define STM32_CLOCK48_REQUIRED TRUE
|
||||
#define STM32_SW STM32_SW_PLL
|
||||
#define STM32_PLLSRC STM32_PLLSRC_HSE
|
||||
@@ -54,7 +58,11 @@
|
||||
#define STM32_HPRE STM32_HPRE_DIV1
|
||||
#define STM32_PPRE1 STM32_PPRE1_DIV4
|
||||
#define STM32_PPRE2 STM32_PPRE2_DIV2
|
||||
#if HAL_USE_RTC
|
||||
#define STM32_RTCSEL STM32_RTCSEL_LSE
|
||||
#else
|
||||
#define STM32_RTCSEL STM32_RTCSEL_NOCLOCK
|
||||
#endif
|
||||
#define STM32_RTCPRE_VALUE 25
|
||||
#define STM32_MCO1SEL STM32_MCO1SEL_HSE
|
||||
#define STM32_MCO1PRE STM32_MCO1PRE_DIV1
|
||||
|
||||
@@ -121,30 +121,6 @@
|
||||
#define SPEKTRUM_BIND_PIN GPIO0
|
||||
#define SPEKTRUM_BIND_PIN_PORT GPIOB
|
||||
|
||||
#define SPEKTRUM_UART1_RCC RCC_USART1
|
||||
#define SPEKTRUM_UART1_BANK GPIOA
|
||||
#define SPEKTRUM_UART1_PIN GPIO10
|
||||
#define SPEKTRUM_UART1_AF GPIO_AF7
|
||||
#define SPEKTRUM_UART1_IRQ NVIC_USART1_IRQ
|
||||
#define SPEKTRUM_UART1_ISR usart1_isr
|
||||
#define SPEKTRUM_UART1_DEV USART1
|
||||
|
||||
#define SPEKTRUM_UART2_RCC RCC_USART2
|
||||
#define SPEKTRUM_UART2_BANK GPIOA
|
||||
#define SPEKTRUM_UART2_PIN GPIO3
|
||||
#define SPEKTRUM_UART2_AF GPIO_AF7
|
||||
#define SPEKTRUM_UART2_IRQ NVIC_USART2_IRQ
|
||||
#define SPEKTRUM_UART2_ISR usart2_isr
|
||||
#define SPEKTRUM_UART2_DEV USART2
|
||||
|
||||
#define SPEKTRUM_UART5_RCC RCC_UART5
|
||||
#define SPEKTRUM_UART5_BANK GPIOD
|
||||
#define SPEKTRUM_UART5_PIN GPIO2
|
||||
#define SPEKTRUM_UART5_AF GPIO_AF8
|
||||
#define SPEKTRUM_UART5_IRQ NVIC_UART5_IRQ
|
||||
#define SPEKTRUM_UART5_ISR uart5_isr
|
||||
#define SPEKTRUM_UART5_DEV UART5
|
||||
|
||||
/* PPM
|
||||
*
|
||||
* Default is PPM config 2, input on GPIOA1 (Servo pin 6)
|
||||
|
||||
+2
-2
@@ -34,7 +34,7 @@
|
||||
#include "led.h"
|
||||
#endif
|
||||
#if defined RADIO_CONTROL
|
||||
#if defined RADIO_CONTROL_LINK || defined RADIO_CONTROL_SPEKTRUM_PRIMARY_PORT
|
||||
#if defined RADIO_CONTROL_BIND_IMPL_FUNC & defined SPEKTRUM_BIND_PIN_PORT
|
||||
#include "subsystems/radio_control.h"
|
||||
#endif
|
||||
#endif
|
||||
@@ -124,7 +124,7 @@ void mcu_init(void)
|
||||
PERIPHERAL3V3_ENABLE_ON(PERIPHERAL3V3_ENABLE_PORT, PERIPHERAL3V3_ENABLE_PIN);
|
||||
#endif
|
||||
/* for now this means using spektrum */
|
||||
#if defined RADIO_CONTROL & defined RADIO_CONTROL_SPEKTRUM_PRIMARY_PORT & defined RADIO_CONTROL_BIND_IMPL_FUNC & defined SPEKTRUM_BIND_PIN_PORT
|
||||
#if defined RADIO_CONTROL & defined RADIO_CONTROL_BIND_IMPL_FUNC & defined SPEKTRUM_BIND_PIN_PORT
|
||||
RADIO_CONTROL_BIND_IMPL_FUNC();
|
||||
#endif
|
||||
#if USE_UART0
|
||||
|
||||
@@ -1,49 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2008-2009 Antoine Drouin <poinix@gmail.com>
|
||||
*
|
||||
* This file is part of paparazzi.
|
||||
*
|
||||
* paparazzi is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* paparazzi is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with paparazzi; see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef RADIO_CONTROL_JOBY_9CH_H
|
||||
#define RADIO_CONTROL_JOBY_9CH_H
|
||||
|
||||
#define RADIO_CONTROL_NB_CHANNEL 9
|
||||
|
||||
#define RADIO_THROTTLE 0
|
||||
#define RADIO_YAW 1
|
||||
#define RADIO_PITCH 2
|
||||
#define RADIO_ROLL 3
|
||||
#define RADIO_GEAR 4
|
||||
#define RADIO_MODE 5
|
||||
#define RADIO_AUX2 6
|
||||
#define RADIO_AUX3 7
|
||||
#define RADIO_KILL 8
|
||||
|
||||
#define RC_JOBY_SYNC_2 0x12
|
||||
|
||||
#define RC_JOBY_SIGNS { 1, \
|
||||
1, \
|
||||
1, \
|
||||
1, \
|
||||
1, \
|
||||
1, \
|
||||
1, \
|
||||
1, \
|
||||
1 }
|
||||
|
||||
#endif /* RADIO_CONTROL_JOBY_9CH_H */
|
||||
@@ -1,5 +1,8 @@
|
||||
/*
|
||||
* Copyright (C) 2008-2009 Antoine Drouin <poinix@gmail.com>
|
||||
* 2010 Eric Parsonage <eric@eparsonage.com>
|
||||
* 2015 Freek van Tienen <freek.v.tienen@gmail.com>
|
||||
* 2018 Gautier Hattenberger <gautier.hattenberger@enac.fr>
|
||||
*
|
||||
* This file is part of paparazzi.
|
||||
*
|
||||
@@ -14,16 +17,363 @@
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with paparazzi; see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
* along with paparazzi; see the file COPYING. If not, see
|
||||
* <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "spektrum.h"
|
||||
#include "subsystems/radio_control/spektrum.h"
|
||||
|
||||
/* Currently the functionality has been pushed into the arch directories
|
||||
* both arch directories contain essentially the original parser.
|
||||
* The next step is to implement a new parser for lisa. Once this is complete
|
||||
* hardware dependent functions will be written for booz then the lisa parser
|
||||
* will end up in here
|
||||
/**
|
||||
* @file subsystems/radio_control/spektrum.c
|
||||
*
|
||||
* Spektrum sattelite receiver implementation. For the protocol specification see:
|
||||
* http://www.spektrumrc.com/ProdInfo/Files/Remote%20Receiver%20Interfacing%20Rev%20A.pdf
|
||||
*/
|
||||
|
||||
#include "std.h"
|
||||
#include "subsystems/radio_control.h"
|
||||
#include "mcu_periph/uart.h"
|
||||
#include "mcu_periph/gpio.h"
|
||||
#include "mcu_periph/sys_time.h"
|
||||
|
||||
/* Check if primary receiver is defined */
|
||||
#ifndef SPEKTRUM_PRIMARY_UART
|
||||
#error "You must at least define the primary Spektrum satellite receiver."
|
||||
#endif
|
||||
|
||||
/* Changed radio control order Notice */
|
||||
INFO("Radio-Control now follows PPRZ sign convention: this means you might need to reverese some channels in your transmitter: RollRight / PitchUp / YawRight / FullThrottle / Auto2 are positive deflections")
|
||||
|
||||
/* Number of low pulses sent during binding to the satellite receivers
|
||||
* As recommended, master and slave receivers are in DSMX 11ms mode,
|
||||
* other modes (DSM2, 22ms) will be automatically supported
|
||||
*/
|
||||
#define SPEKTRUM_MASTER_RECEIVER_PULSES 9 // only one receiver should be in master mode
|
||||
#define SPEKTRUM_SLAVE_RECEIVER_PULSES 10
|
||||
|
||||
/* Set polarity using RC_POLARITY_GPIO. */
|
||||
#ifndef RC_SET_POLARITY
|
||||
#define RC_SET_POLARITY gpio_clear
|
||||
#endif
|
||||
|
||||
/* Busy wait to let the receiver starts properly
|
||||
* This should be reduced when the MCU takes longer to start
|
||||
*/
|
||||
#ifndef SPEKTRUM_BIND_WAIT
|
||||
#define SPEKTRUM_BIND_WAIT 60000
|
||||
#endif
|
||||
|
||||
// in case the number of channel is less than maximum
|
||||
const int8_t spektrum_signs[] = RADIO_CONTROL_SPEKTRUM_SIGNS;
|
||||
|
||||
/* Default spektrum values */
|
||||
static struct spektrum_t spektrum = {
|
||||
.valid = false,
|
||||
.tx_type = 0, // unknown type
|
||||
};
|
||||
|
||||
/** Allowed system field valaues.
|
||||
* from datasheet, possible values for the frame format
|
||||
* encoded in the system field of the internal remote
|
||||
* frame (second byte).
|
||||
* Only the first one is encoding values on 10bits,
|
||||
* other ones on 11bits.
|
||||
*/
|
||||
#define SPEKTRUM_SYS_22_1024_2 0x01 // 22ms 1024 DSM2
|
||||
#define SPEKTRUM_SYS_11_2048_2 0x12 // 11ms 2048 DSM2
|
||||
#define SPEKTRUM_SYS_22_2048_X 0xa2 // 22ms 2048 DSMX
|
||||
#define SPEKTRUM_SYS_11_2048_X 0xb2 // 11ms 2048 DSMX
|
||||
|
||||
static void spektrum_bind(void);
|
||||
|
||||
/** Initialize a spektrum sattelite */
|
||||
static inline void spektrum_init_sat(struct spektrum_sat_t *sat)
|
||||
{
|
||||
sat->valid = false;
|
||||
sat->timer = get_sys_time_msec();
|
||||
sat->idx = 0;
|
||||
|
||||
// Initialize values
|
||||
for (uint8_t i = 0; i < SPEKTRUM_MAX_CHANNELS; i++) {
|
||||
sat->values[i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* spektrum_try_bind(void) must called on powerup as spektrum
|
||||
* satellites can only bind immediately after power up also it must be called
|
||||
* before the call to SpektrumUartInit as we leave them with their Rx pins set
|
||||
* as outputs.
|
||||
*
|
||||
*****************************************************************************/
|
||||
void spektrum_try_bind(void)
|
||||
{
|
||||
#ifdef SPEKTRUM_BIND_PIN_PORT
|
||||
#ifdef SPEKTRUM_BIND_PIN_HIGH
|
||||
/* Init GPIO for the bind pin, we enable the pulldown resistor.
|
||||
* (esden) As far as I can tell only navstick is using the PIN LOW version of
|
||||
* the bind pin, but I assume this should not harm anything. If I am mistaken
|
||||
* than I appologise for the inconvenience. :)
|
||||
*/
|
||||
gpio_setup_input_pulldown(SPEKTRUM_BIND_PIN_PORT, SPEKTRUM_BIND_PIN);
|
||||
|
||||
sys_time_usleep(10); // wait for electrical level to stabilize
|
||||
|
||||
/* Exit if the BIND_PIN is low, it needs to
|
||||
be pulled high at startup to initiate bind */
|
||||
if (gpio_get(SPEKTRUM_BIND_PIN_PORT, SPEKTRUM_BIND_PIN) != 0) {
|
||||
spektrum_bind();
|
||||
}
|
||||
#else
|
||||
/* Init GPIO for the bind pin, we enable the pullup resistor in case we have
|
||||
* a floating pin that does not have a hardware pullup resistor as it is the
|
||||
* case with Lisa/M and Lisa/MX prior to version 2.1.
|
||||
*/
|
||||
gpio_setup_input_pullup(SPEKTRUM_BIND_PIN_PORT, SPEKTRUM_BIND_PIN);
|
||||
|
||||
sys_time_usleep(10); // wait for electrical level to stabilize
|
||||
|
||||
/* Exit if the BIND_PIN is high, it needs to
|
||||
be pulled low at startup to initiate bind */
|
||||
if (gpio_get(SPEKTRUM_BIND_PIN_PORT, SPEKTRUM_BIND_PIN) == 0) {
|
||||
spektrum_bind();
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/** Main Radio initialization */
|
||||
void radio_control_impl_init(void)
|
||||
{
|
||||
|
||||
for (uint8_t i = 0; i < RADIO_CONTROL_NB_CHANNEL; i++) {
|
||||
spektrum.signs[i] = spektrum_signs[i];
|
||||
}
|
||||
|
||||
// Set polarity to normal on boards that can change this
|
||||
#ifdef RC_POLARITY_GPIO_PORT
|
||||
gpio_setup_output(RC_POLARITY_GPIO_PORT, RC_POLARITY_GPIO_PIN);
|
||||
RC_SET_POLARITY(RC_POLARITY_GPIO_PORT, RC_POLARITY_GPIO_PIN);
|
||||
#endif
|
||||
|
||||
// Initialize all the UART's in the satellites
|
||||
spektrum_init_sat(&spektrum.satellites[0]);
|
||||
#ifdef SPEKTRUM_SECONDARY_UART
|
||||
spektrum_init_sat(&spektrum.satellites[1]);
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Parse a sattelite channel */
|
||||
static inline void spektrum_parse_channel(struct spektrum_sat_t *sat, uint16_t chan)
|
||||
{
|
||||
// This channel is not used
|
||||
if (chan == 0xFFFF) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (spektrum.tx_type == SPEKTRUM_SYS_22_1024_2) {
|
||||
// We got a 10bit precision packet
|
||||
uint8_t chan_num = (chan & 0xFC00) >> 10;
|
||||
sat->values[chan_num] = chan & 0x03FF;
|
||||
if (chan_num == RADIO_THROTTLE) {
|
||||
// scale full range to pprz_t
|
||||
// but since 1024 correspond to 150%, scale with 1024/1.5 ~ 684
|
||||
// remove an offset of 2400 = 171 * MAX_PPRZ / 684
|
||||
sat->values[chan_num] = ((MAX_PPRZ * sat->values[chan_num]) / 684) - 2400;
|
||||
} else {
|
||||
sat->values[chan_num] -= (1 << 9); // substract 2^9 to get a value between [-512;512]
|
||||
// scale full range to pprz_t
|
||||
// but since 512 correspond to 150%, scale with 512/1.5 ~ 342
|
||||
sat->values[chan_num] = (MAX_PPRZ * sat->values[chan_num]) / 342;
|
||||
}
|
||||
}
|
||||
else {
|
||||
// We got a 11bit precision packet
|
||||
uint8_t chan_num = (chan & 0x7800) >> 11;
|
||||
sat->values[chan_num] = chan & 0x07FF;
|
||||
if (chan_num == RADIO_THROTTLE) {
|
||||
// scale full range to pprz_t
|
||||
// but since 2048 correspond to 150%, scale with 2048/1.5 ~ 1368
|
||||
// remove an offset of 2400 = 234 * MAX_PPRZ / 1368
|
||||
sat->values[chan_num] = ((MAX_PPRZ * sat->values[chan_num]) / 1368) - 2400;
|
||||
} else {
|
||||
sat->values[chan_num] -= (1 << 10); // substract 2^10 to get a value between [-1024;1024]
|
||||
// scale full range to pprz_t
|
||||
// but since 1024 correspond to 150%, scale with 1024/1.5 ~ 684
|
||||
sat->values[chan_num] = (MAX_PPRZ * sat->values[chan_num]) / 684;
|
||||
}
|
||||
}
|
||||
|
||||
// mark a valid frame
|
||||
sat->valid = true;
|
||||
spektrum.valid = true;
|
||||
}
|
||||
|
||||
/* Spektrum parser for a satellite */
|
||||
static inline void spektrum_parser(struct spektrum_sat_t *sat)
|
||||
{
|
||||
// Parse packet
|
||||
sat->lost_frame_cnt = sat->buf[0];
|
||||
// For now ignore the second byte (which could be the TX type)
|
||||
// if frame type is still unknown, try to find it in the 'system' byte
|
||||
// only the primary receiver should have a valid type
|
||||
if (spektrum.tx_type == 0) {
|
||||
uint8_t type = sat->buf[1];
|
||||
if (type == SPEKTRUM_SYS_22_1024_2 || type == SPEKTRUM_SYS_11_2048_2 ||
|
||||
type == SPEKTRUM_SYS_22_2048_X || type == SPEKTRUM_SYS_11_2048_X) {
|
||||
// we have a valid type, we assume it comes from primary receiver
|
||||
spektrum.tx_type = type;
|
||||
} else {
|
||||
// return and drop frame as we don't know what to do with it
|
||||
return;
|
||||
}
|
||||
}
|
||||
// parse servo channels
|
||||
for (uint8_t i = 2; i < 2*SPEKTRUM_CHANNELS_PER_FRAME+2; i = i+2) {
|
||||
uint16_t chan = (((uint16_t)sat->buf[i]) << 8) | ((uint16_t)sat->buf[i+1]);
|
||||
spektrum_parse_channel(sat, chan);
|
||||
}
|
||||
}
|
||||
|
||||
/** Check bytes on the UART */
|
||||
static void spektrum_uart_check(struct uart_periph *dev, struct spektrum_sat_t *sat)
|
||||
{
|
||||
// detect sync space based on frame spacing
|
||||
uint32_t t = get_sys_time_msec();
|
||||
if (t - sat->timer > SPEKTRUM_MIN_FRAME_SPACE) {
|
||||
sat->timer = t; // reset counter
|
||||
uint16_t bytes_cnt = uart_char_available(dev); // The amount of bytes in the buffer
|
||||
// sync space detected but buffer not empty, flush data
|
||||
if (bytes_cnt > 0) {
|
||||
for (uint8_t i = 0; i < bytes_cnt; i++) {
|
||||
uart_getch(dev);
|
||||
}
|
||||
}
|
||||
}
|
||||
// check and parse bytes in uart buffer
|
||||
while (uart_char_available(dev)) {
|
||||
sat->buf[sat->idx++] = uart_getch(dev);
|
||||
sat->timer = t; // reset counter
|
||||
if (sat->idx == SPEKTRUM_FRAME_LEN) {
|
||||
// buffer is full, parse frame
|
||||
spektrum_parser(sat);
|
||||
sat->idx = 0; // reset index
|
||||
break; // stop here to handle RC frame
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** Checks if there is one valid satellite and sets the radio_control structure */
|
||||
void spektrum_event(void (*frame_handler)(void))
|
||||
{
|
||||
spektrum_uart_check(&SPEKTRUM_PRIMARY_UART, &spektrum.satellites[0]);
|
||||
|
||||
#ifdef SPEKTRUM_SECONDARY_UART
|
||||
spektrum_uart_check(&SPEKTRUM_SECONDARY_UART, &spektrum.satellites[1]);
|
||||
#endif
|
||||
|
||||
// Whenever we received a valid RC packet
|
||||
if (spektrum.valid) {
|
||||
uint8_t sat_id = SPEKTRUM_SATELLITES_NB;
|
||||
spektrum.valid = false;
|
||||
|
||||
// Find the first satellite that has a valid packet
|
||||
for (uint8_t i = 0; i < SPEKTRUM_SATELLITES_NB; i++) {
|
||||
if (i < sat_id) {
|
||||
sat_id = i;
|
||||
}
|
||||
if (spektrum.satellites[i].valid) {
|
||||
spektrum.satellites[i].valid = false;
|
||||
}
|
||||
}
|
||||
|
||||
// Failsafe case if found satellite is out of bound (Should not happen)
|
||||
if (sat_id >= SPEKTRUM_SATELLITES_NB) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Set the radio control status
|
||||
radio_control.frame_cpt++;
|
||||
radio_control.time_since_last_frame = 0;
|
||||
radio_control.status = RC_OK;
|
||||
|
||||
// Copy the radio control channels
|
||||
for (uint8_t i = 0; i < RADIO_CONTROL_NB_CHANNEL; i++) {
|
||||
radio_control.values[i] = spektrum.satellites[sat_id].values[i] * spektrum.signs[i];
|
||||
Bound(radio_control.values[i], -MAX_PPRZ, MAX_PPRZ);
|
||||
}
|
||||
|
||||
// We got a valid frame so execute the frame handler
|
||||
(*frame_handler)();
|
||||
}
|
||||
}
|
||||
|
||||
/* Defines needed for easy access of port information */
|
||||
#define _UART_RX_PORT(i) i ## _PORT_RX
|
||||
#define UART_RX_PORT(i) _UART_RX_PORT(i)
|
||||
#define _UART_RX(i) i ## _RX
|
||||
#define UART_RX(i) _UART_RX(i)
|
||||
|
||||
/**
|
||||
* By default, the same pin is used for pulse train and uart rx, but
|
||||
* they can be different if needed
|
||||
*/
|
||||
#ifndef SPEKTRUM_PRIMARY_BIND_CONF_PORT
|
||||
#define SPEKTRUM_PRIMARY_BIND_CONF_PORT UART_RX_PORT(SPEKTRUM_PRIMARY_UART_UPPER)
|
||||
#endif
|
||||
#ifndef SPEKTRUM_PRIMARY_BIND_CONF_PIN
|
||||
#define SPEKTRUM_PRIMARY_BIND_CONF_PIN UART_RX(SPEKTRUM_PRIMARY_UART_UPPER)
|
||||
#endif
|
||||
#ifndef SPEKTRUM_SECONDARY_BIND_CONF_PORT
|
||||
#define SPEKTRUM_SECONDARY_BIND_CONF_PORT UART_RX_PORT(SPEKTRUM_SECONDARY_UART_UPPER)
|
||||
#endif
|
||||
#ifndef SPEKTRUM_SECONDARY_BIND_CONF_PIN
|
||||
#define SPEKTRUM_SECONDARY_BIND_CONF_PIN UART_RX(SPEKTRUM_SECONDARY_UART_UPPER)
|
||||
#endif
|
||||
|
||||
/** This function puts the satellite in binding mode.
|
||||
* The requirement of this are that this needs to be done while powering up.
|
||||
*/
|
||||
static void spektrum_bind(void)
|
||||
{
|
||||
|
||||
/* Master receiver Rx push-pull */
|
||||
gpio_setup_output(SPEKTRUM_PRIMARY_BIND_CONF_PORT, SPEKTRUM_PRIMARY_BIND_CONF_PIN);
|
||||
/* Master receiver RX line, drive high */
|
||||
gpio_set(SPEKTRUM_PRIMARY_BIND_CONF_PORT, SPEKTRUM_PRIMARY_BIND_CONF_PIN);
|
||||
|
||||
#ifdef SPEKTRUM_SECONDARY_UART
|
||||
/* Slave receiver Rx push-pull */
|
||||
gpio_setup_output(SPEKTRUM_SECONDARY_BIND_CONF_PORT, SPEKTRUM_SECONDARY_BIND_CONF_PIN);
|
||||
/* Slave receiver RX line, drive high */
|
||||
gpio_set(SPEKTRUM_SECONDARY_BIND_CONF_PORT, SPEKTRUM_SECONDARY_BIND_CONF_PIN);
|
||||
#endif
|
||||
|
||||
/* bind pulses should be issued within 200ms after power up
|
||||
* wait a bit to let the receiver start properly,
|
||||
* set to 0 to disable */
|
||||
#if SPEKTRUM_BIND_WAIT
|
||||
sys_time_usleep(SPEKTRUM_BIND_WAIT);
|
||||
#endif
|
||||
|
||||
/* Transmit the bind pulses */
|
||||
for (int i = 0; i < 2 * SPEKTRUM_MASTER_RECEIVER_PULSES ; i++) {
|
||||
gpio_toggle(SPEKTRUM_PRIMARY_BIND_CONF_PORT, SPEKTRUM_PRIMARY_BIND_CONF_PIN);
|
||||
sys_time_usleep(120);
|
||||
}
|
||||
#ifdef SPEKTRUM_SECONDARY_UART
|
||||
for (int i = 0; i < 2 * SPEKTRUM_SLAVE_RECEIVER_PULSES; i++) {
|
||||
gpio_toggle(SPEKTRUM_SECONDARY_BIND_CONF_PORT, SPEKTRUM_SECONDARY_BIND_CONF_PIN);
|
||||
sys_time_usleep(120);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Set conf pin as input in case it is different from RX pin */
|
||||
gpio_setup_input(SPEKTRUM_PRIMARY_BIND_CONF_PORT, SPEKTRUM_PRIMARY_BIND_CONF_PIN);
|
||||
#ifdef SPEKTRUM_SECONDARY_UART
|
||||
gpio_setup_input(SPEKTRUM_SECONDARY_BIND_CONF_PORT, SPEKTRUM_SECONDARY_BIND_CONF_PIN);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
/*
|
||||
* Copyright (C) 2009-2014 The Paparazzi Team
|
||||
* 2015 Freek van Tienen <freek.v.tienen@gmail.com>
|
||||
* 2018 Gautier Hattenberger <gautier.hattenberger@enac.fr>
|
||||
*
|
||||
* This file is part of paparazzi.
|
||||
*
|
||||
@@ -27,12 +29,44 @@
|
||||
#ifndef RADIO_CONTROL_SPEKTRUM_H
|
||||
#define RADIO_CONTROL_SPEKTRUM_H
|
||||
|
||||
/* implemented in arch/xxx/subsystems/radio_control/spektrum_arch.c */
|
||||
extern void radio_control_spektrum_try_bind(void);
|
||||
#include "std.h"
|
||||
|
||||
#include "subsystems/radio_control/spektrum_arch.h"
|
||||
/* implemented in arch/xxx/subsystems/radio_control/spektrum_arch.c */
|
||||
/* Include channels information */
|
||||
#include "spektrum_radio.h"
|
||||
|
||||
#define RadioControlEvent(_received_frame_handler) RadioControlEventImp(_received_frame_handler)
|
||||
/* For now only two satellites are supported */
|
||||
#define SPEKTRUM_SATELLITES_NB 2
|
||||
|
||||
/* Timings and maximums of Spektrum DSM protocol */
|
||||
#define SPEKTRUM_FRAME_LEN 16 ///< 16 bytes in a standard frame
|
||||
#define SPEKTRUM_CHANNELS_PER_FRAME 7 ///< Maximum amount of RC channels per frame
|
||||
#define SPEKTRUM_MAX_FRAMES 2 ///< Maximum amount of RC frames containing different channels
|
||||
#define SPEKTRUM_MAX_CHANNELS (SPEKTRUM_CHANNELS_PER_FRAME * SPEKTRUM_MAX_FRAMES)
|
||||
#define SPEKTRUM_MIN_FRAME_SPACE 7 ///< Minum amount of time between frames (7ms), in fact either 11 or 22 ms
|
||||
|
||||
/* Set the event function to the correct */
|
||||
#define RadioControlEvent(_received_frame_handler) spektrum_event(_received_frame_handler)
|
||||
|
||||
/* Per satellite we keep track of data */
|
||||
struct spektrum_sat_t {
|
||||
bool valid; ///< True when we received a packet else false
|
||||
uint32_t timer; ///< Timer to keep track of the UART synchronisation
|
||||
uint8_t lost_frame_cnt; ///< Amount of RC frames lost
|
||||
uint8_t buf[SPEKTRUM_FRAME_LEN]; ///< input buffer
|
||||
uint8_t idx; ///< input buffer index
|
||||
int16_t values[SPEKTRUM_MAX_CHANNELS]; ///< RC channel values
|
||||
};
|
||||
|
||||
/* Main spektrum structure */
|
||||
struct spektrum_t {
|
||||
bool valid; ///< True when we received a packet else false
|
||||
uint8_t tx_type; ///< Transmitter type encoded (see wiki)
|
||||
int8_t signs[RADIO_CONTROL_NB_CHANNEL]; ///< Signs for the RC channels
|
||||
struct spektrum_sat_t satellites[SPEKTRUM_SATELLITES_NB]; ///< All the satellites connected
|
||||
};
|
||||
|
||||
/* External functions */
|
||||
extern void spektrum_event(void (*_received_frame_handler)(void));
|
||||
extern void spektrum_try_bind(void);
|
||||
|
||||
#endif /* RADIO_CONTROL_SPEKTRUM_H */
|
||||
|
||||
@@ -1,53 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2008-2009 Antoine Drouin <poinix@gmail.com>
|
||||
*
|
||||
* This file is part of paparazzi.
|
||||
*
|
||||
* paparazzi is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* paparazzi is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with paparazzi; see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef RADIO_CONTROL_SPEKTRUM_DX7SE_H
|
||||
#define RADIO_CONTROL_SPEKTRUM_DX7SE_H
|
||||
|
||||
#define RADIO_CONTROL_NB_CHANNEL 7
|
||||
|
||||
#define RADIO_ROLL 0
|
||||
#define RADIO_THROTTLE 1
|
||||
#define RADIO_PITCH 2
|
||||
#define RADIO_YAW 3
|
||||
#define RADIO_AUX3 4
|
||||
#define RADIO_MODE 5
|
||||
#define RADIO_AUX4 6
|
||||
|
||||
#define RC_SPK_SYNC_2 0x12
|
||||
|
||||
#define RC_SPK_THROWS { MAX_PPRZ/MAX_SPK, \
|
||||
MAX_PPRZ/MAX_SPK, \
|
||||
-MAX_PPRZ/MAX_SPK, \
|
||||
MAX_PPRZ/MAX_SPK, \
|
||||
MAX_PPRZ/MAX_SPK, \
|
||||
-MAX_PPRZ/MAX_SPK, \
|
||||
MAX_PPRZ/MAX_SPK }
|
||||
|
||||
/*
|
||||
aileron 1
|
||||
elevator 2
|
||||
rudder 3
|
||||
gear 4
|
||||
throttle 5
|
||||
*/
|
||||
|
||||
#endif /* RADIO_CONTROL_SPEKTRUM_DX7SE_H */
|
||||
@@ -1,52 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2008-2009 Antoine Drouin <poinix@gmail.com>
|
||||
*
|
||||
* This file is part of paparazzi.
|
||||
*
|
||||
* paparazzi is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* paparazzi is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with paparazzi; see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef RADIO_CONTROL_SPEKTRUM_DX7SE_H
|
||||
#define RADIO_CONTROL_SPEKTRUM_DX7SE_H
|
||||
|
||||
#define RADIO_CONTROL_NB_CHANNEL 7
|
||||
|
||||
#define RADIO_ROLL 0
|
||||
#define RADIO_THROTTLE 5
|
||||
#define RADIO_PITCH 3
|
||||
#define RADIO_YAW 6
|
||||
#define RADIO_MODE 1
|
||||
#define RADIO_KILL_SWITCH 4
|
||||
|
||||
#define RC_SPK_SYNC_2 0x01
|
||||
|
||||
#define RC_SPK_THROWS { MAX_PPRZ/MAX_SPK, \
|
||||
MAX_PPRZ/MAX_SPK, \
|
||||
-MAX_PPRZ/MAX_SPK, \
|
||||
-MAX_PPRZ/MAX_SPK, \
|
||||
-MAX_PPRZ/MAX_SPK, \
|
||||
MAX_PPRZ/MAX_SPK, \
|
||||
MAX_PPRZ/MAX_SPK }
|
||||
|
||||
/*
|
||||
aileron 1
|
||||
elevator 2
|
||||
rudder 3
|
||||
gear 4
|
||||
throttle 5
|
||||
*/
|
||||
|
||||
#endif /* RADIO_CONTROL_SPEKTRUM_DX7SE_H */
|
||||
+28
-37
@@ -1,5 +1,6 @@
|
||||
/*
|
||||
* Copyright (C) 2010 Eric Parsonage <eric@eparsonage.com>
|
||||
* Copyright (C) 2009-2014 The Paparazzi Team
|
||||
* 2016 Freek van Tienen <freek.v.tienen@gmail.com>
|
||||
*
|
||||
* This file is part of paparazzi.
|
||||
*
|
||||
@@ -14,29 +15,26 @@
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with paparazzi; see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
* along with paparazzi; see the file COPYING. If not, see
|
||||
* <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file subsystems/radio_control/spektrum_radio.h
|
||||
*
|
||||
* Radio control channels defaults, because they are digital
|
||||
*/
|
||||
|
||||
#ifndef RADIO_CONTROL_SPEKTRUM_ARCH_H
|
||||
#define RADIO_CONTROL_SPEKTRUM_ARCH_H
|
||||
|
||||
|
||||
/*
|
||||
* All Spektrum and JR 2.4 GHz transmitters
|
||||
* have the same channel assignments.
|
||||
*/
|
||||
|
||||
#define SPEKTRUM_NB_CHANNEL 12
|
||||
#ifndef RADIO_CONTROL_SPEKTRUM_RADIO_H
|
||||
#define RADIO_CONTROL_SPEKTRUM_RADIO_H
|
||||
|
||||
/* Amount of spektrum channels */
|
||||
#ifndef RADIO_CONTROL_NB_CHANNEL
|
||||
#define RADIO_CONTROL_NB_CHANNEL 12
|
||||
#define RADIO_CONTROL_NB_CHANNEL 14
|
||||
#endif
|
||||
|
||||
#if RADIO_CONTROL_NB_CHANNEL > 12
|
||||
#error "RADIO_CONTROL_NB_CHANNEL mustn't be higher than 12."
|
||||
#if RADIO_CONTROL_NB_CHANNEL > 14
|
||||
#error "RADIO_CONTROL_NB_CHANNEL mustn't be higher than 14."
|
||||
#endif
|
||||
|
||||
/* default channel assignments */
|
||||
@@ -52,12 +50,8 @@
|
||||
#ifndef RADIO_YAW
|
||||
#define RADIO_YAW 3
|
||||
#endif
|
||||
#ifndef RADIO_GEAR
|
||||
#define RADIO_GEAR 4
|
||||
#endif
|
||||
#ifndef RADIO_FLAP
|
||||
#define RADIO_FLAP 5
|
||||
#endif
|
||||
#define RADIO_AUX1 5
|
||||
#define RADIO_AUX2 6
|
||||
#define RADIO_AUX3 7
|
||||
@@ -65,25 +59,22 @@
|
||||
#define RADIO_AUX5 9
|
||||
#define RADIO_AUX6 10
|
||||
#define RADIO_AUX7 11
|
||||
#define RADIO_AUX8 12
|
||||
#define RADIO_AUX9 13
|
||||
|
||||
/* reverse some channels to suit Paparazzi conventions */
|
||||
/* the maximum number of channels a Spektrum can transmit is 12 */
|
||||
#ifndef RADIO_CONTROL_SPEKTRUM_SIGNS
|
||||
#ifdef RADIO_CONTROL_SPEKTRUM_OLD_SIGNS
|
||||
#define RADIO_CONTROL_SPEKTRUM_SIGNS {1,-1,-1,-1,1,-1,1,1,1,1,1,1} // As most transmitters are sold
|
||||
#else
|
||||
#define RADIO_CONTROL_SPEKTRUM_SIGNS {1,1,1,1,1,1,1,1,1,1,1,1} // PPRZ sign convention
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* really for a 9 channel transmitter
|
||||
we would swap the order of these */
|
||||
/* Default Mode channel is GEAR (number 5) */
|
||||
#ifndef RADIO_MODE
|
||||
#define RADIO_MODE RADIO_GEAR
|
||||
#endif
|
||||
|
||||
extern void RadioControlEventImp(void (*_received_frame_handler)(void));
|
||||
/* initialise the uarts used by the parser */
|
||||
void SpektrumUartInit(void);
|
||||
/* Possibility to reverse channels */
|
||||
#ifndef RADIO_CONTROL_SPEKTRUM_SIGNS
|
||||
//
|
||||
#ifdef RADIO_CONTROL_SPEKTRUM_OLD_SIGNS
|
||||
#define RADIO_CONTROL_SPEKTRUM_SIGNS {1,-1,-1,-1,1,-1,1,1,1,1,1,1,1,1} // As most transmitters are sold
|
||||
#else
|
||||
#define RADIO_CONTROL_SPEKTRUM_SIGNS {1,1,1,1,1,1,1,1,1,1,1,1,1,1} // PPRZ sign convention
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#endif /* RADIO_CONTROL_SPEKTRUM_ARCH_H */
|
||||
#endif /* RADIO_CONTROL_SPEKTRUM_RADIO_H */
|
||||
Reference in New Issue
Block a user