mirror of
https://bitbucket.org/librepilot/librepilot.git
synced 2024-11-29 07:24:13 +01:00
rcvr: convert PWM, PPM, SBUS and Spektrum to use PIOS_RCVR
All receivers now fall under the same driver API provided by pios_rcvr.c. This is part of a larger sequence of commits that will switch the receiver selection over to boot time dynamic configuration via UAVObjects.
This commit is contained in:
parent
e77795dc28
commit
740b5f1584
@ -211,6 +211,7 @@ SRC += $(PIOSCOMMON)/pios_com.c
|
|||||||
SRC += $(PIOSCOMMON)/pios_i2c_esc.c
|
SRC += $(PIOSCOMMON)/pios_i2c_esc.c
|
||||||
SRC += $(PIOSCOMMON)/pios_iap.c
|
SRC += $(PIOSCOMMON)/pios_iap.c
|
||||||
SRC += $(PIOSCOMMON)/pios_bl_helper.c
|
SRC += $(PIOSCOMMON)/pios_bl_helper.c
|
||||||
|
SRC += $(PIOSCOMMON)/pios_rcvr.c
|
||||||
SRC += $(PIOSCOMMON)/printf-stdarg.c
|
SRC += $(PIOSCOMMON)/printf-stdarg.c
|
||||||
## Libraries for flight calculations
|
## Libraries for flight calculations
|
||||||
SRC += $(FLIGHTLIB)/fifo_buffer.c
|
SRC += $(FLIGHTLIB)/fifo_buffer.c
|
||||||
|
@ -1,116 +1,118 @@
|
|||||||
/**
|
/**
|
||||||
******************************************************************************
|
******************************************************************************
|
||||||
* @addtogroup OpenPilotSystem OpenPilot System
|
* @addtogroup OpenPilotSystem OpenPilot System
|
||||||
* @{
|
* @{
|
||||||
* @addtogroup OpenPilotCore OpenPilot Core
|
* @addtogroup OpenPilotCore OpenPilot Core
|
||||||
* @{
|
* @{
|
||||||
*
|
*
|
||||||
* @file pios_config.h
|
* @file pios_config.h
|
||||||
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
|
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
|
||||||
* @brief PiOS configuration header.
|
* @brief PiOS configuration header.
|
||||||
* Central compile time config for the project.
|
* Central compile time config for the project.
|
||||||
* In particular, pios_config.h is where you define which PiOS libraries
|
* In particular, pios_config.h is where you define which PiOS libraries
|
||||||
* and features are included in the firmware.
|
* and features are included in the firmware.
|
||||||
* @see The GNU Public License (GPL) Version 3
|
* @see The GNU Public License (GPL) Version 3
|
||||||
*
|
*
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
/*
|
/*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
* the Free Software Foundation; either version 3 of the License, or
|
* the Free Software Foundation; either version 3 of the License, or
|
||||||
* (at your option) any later version.
|
* (at your option) any later version.
|
||||||
*
|
*
|
||||||
* This program is distributed in the hope that it will be useful, but
|
* This program is distributed in the hope that it will be useful, but
|
||||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
* for more details.
|
* for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License along
|
* You should have received a copy of the GNU General Public License along
|
||||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef PIOS_CONFIG_H
|
#ifndef PIOS_CONFIG_H
|
||||||
#define PIOS_CONFIG_H
|
#define PIOS_CONFIG_H
|
||||||
|
|
||||||
/* Enable/Disable PiOS Modules */
|
/* Enable/Disable PiOS Modules */
|
||||||
#define PIOS_INCLUDE_ADC
|
#define PIOS_INCLUDE_ADC
|
||||||
#define PIOS_INCLUDE_DELAY
|
#define PIOS_INCLUDE_DELAY
|
||||||
#if defined(USE_I2C)
|
#if defined(USE_I2C)
|
||||||
#define PIOS_INCLUDE_I2C
|
#define PIOS_INCLUDE_I2C
|
||||||
#define PIOS_INCLUDE_I2C_ESC
|
#define PIOS_INCLUDE_I2C_ESC
|
||||||
#endif
|
#endif
|
||||||
#define PIOS_INCLUDE_IRQ
|
#define PIOS_INCLUDE_IRQ
|
||||||
#define PIOS_INCLUDE_LED
|
#define PIOS_INCLUDE_LED
|
||||||
|
|
||||||
/* Receiver interfaces - only one allowed */
|
#define PIOS_INCLUDE_RCVR
|
||||||
#if !defined(USE_SPEKTRUM) && !defined(USE_SBUS)
|
|
||||||
//#define PIOS_INCLUDE_PPM
|
/* Receiver interfaces - only one allowed */
|
||||||
#define PIOS_INCLUDE_PWM
|
#if !defined(USE_SPEKTRUM) && !defined(USE_SBUS)
|
||||||
#endif
|
//#define PIOS_INCLUDE_PPM
|
||||||
|
#define PIOS_INCLUDE_PWM
|
||||||
/* USART-based PIOS modules */
|
#endif
|
||||||
#if defined(USE_TELEMETRY)
|
|
||||||
#define PIOS_INCLUDE_TELEMETRY_RF
|
/* USART-based PIOS modules */
|
||||||
#endif
|
#if defined(USE_TELEMETRY)
|
||||||
#if defined(USE_GPS)
|
#define PIOS_INCLUDE_TELEMETRY_RF
|
||||||
#define PIOS_INCLUDE_GPS
|
#endif
|
||||||
#endif
|
#if defined(USE_GPS)
|
||||||
#if defined(USE_SPEKTRUM)
|
#define PIOS_INCLUDE_GPS
|
||||||
#define PIOS_INCLUDE_SPEKTRUM
|
#endif
|
||||||
#endif
|
#if defined(USE_SPEKTRUM)
|
||||||
#if defined(USE_SBUS)
|
#define PIOS_INCLUDE_SPEKTRUM
|
||||||
#define PIOS_INCLUDE_SBUS
|
#endif
|
||||||
#endif
|
#if defined(USE_SBUS)
|
||||||
|
#define PIOS_INCLUDE_SBUS
|
||||||
#define PIOS_INCLUDE_SERVO
|
#endif
|
||||||
#define PIOS_INCLUDE_SPI
|
|
||||||
#define PIOS_INCLUDE_SYS
|
#define PIOS_INCLUDE_SERVO
|
||||||
#define PIOS_INCLUDE_USART
|
#define PIOS_INCLUDE_SPI
|
||||||
#define PIOS_INCLUDE_USB_HID
|
#define PIOS_INCLUDE_SYS
|
||||||
#define PIOS_INCLUDE_COM
|
#define PIOS_INCLUDE_USART
|
||||||
#define PIOS_INCLUDE_SETTINGS
|
#define PIOS_INCLUDE_USB_HID
|
||||||
#define PIOS_INCLUDE_FREERTOS
|
#define PIOS_INCLUDE_COM
|
||||||
#define PIOS_INCLUDE_GPIO
|
#define PIOS_INCLUDE_SETTINGS
|
||||||
#define PIOS_INCLUDE_EXTI
|
#define PIOS_INCLUDE_FREERTOS
|
||||||
#define PIOS_INCLUDE_RTC
|
#define PIOS_INCLUDE_GPIO
|
||||||
#define PIOS_INCLUDE_WDG
|
#define PIOS_INCLUDE_EXTI
|
||||||
#define PIOS_INCLUDE_BL_HELPER
|
#define PIOS_INCLUDE_RTC
|
||||||
|
#define PIOS_INCLUDE_WDG
|
||||||
#define PIOS_INCLUDE_ADXL345
|
#define PIOS_INCLUDE_BL_HELPER
|
||||||
#define PIOS_INCLUDE_FLASH
|
|
||||||
|
#define PIOS_INCLUDE_ADXL345
|
||||||
/* A really shitty setting saving implementation */
|
#define PIOS_INCLUDE_FLASH
|
||||||
#define PIOS_INCLUDE_FLASH_SECTOR_SETTINGS
|
|
||||||
|
/* A really shitty setting saving implementation */
|
||||||
/* Defaults for Logging */
|
#define PIOS_INCLUDE_FLASH_SECTOR_SETTINGS
|
||||||
#define LOG_FILENAME "PIOS.LOG"
|
|
||||||
#define STARTUP_LOG_ENABLED 1
|
/* Defaults for Logging */
|
||||||
|
#define LOG_FILENAME "PIOS.LOG"
|
||||||
/* COM Module */
|
#define STARTUP_LOG_ENABLED 1
|
||||||
#define GPS_BAUDRATE 19200
|
|
||||||
#define TELEM_BAUDRATE 19200
|
/* COM Module */
|
||||||
#define AUXUART_ENABLED 0
|
#define GPS_BAUDRATE 19200
|
||||||
#define AUXUART_BAUDRATE 19200
|
#define TELEM_BAUDRATE 19200
|
||||||
|
#define AUXUART_ENABLED 0
|
||||||
/* Alarm Thresholds */
|
#define AUXUART_BAUDRATE 19200
|
||||||
#define HEAP_LIMIT_WARNING 220
|
|
||||||
#define HEAP_LIMIT_CRITICAL 150
|
/* Alarm Thresholds */
|
||||||
#define CPULOAD_LIMIT_WARNING 80
|
#define HEAP_LIMIT_WARNING 220
|
||||||
#define CPULOAD_LIMIT_CRITICAL 95
|
#define HEAP_LIMIT_CRITICAL 150
|
||||||
|
#define CPULOAD_LIMIT_WARNING 80
|
||||||
/* Task stack sizes */
|
#define CPULOAD_LIMIT_CRITICAL 95
|
||||||
#define PIOS_ACTUATOR_STACK_SIZE 1020
|
|
||||||
#define PIOS_MANUAL_STACK_SIZE 724
|
/* Task stack sizes */
|
||||||
#define PIOS_SYSTEM_STACK_SIZE 560
|
#define PIOS_ACTUATOR_STACK_SIZE 1020
|
||||||
#define PIOS_STABILIZATION_STACK_SIZE 524
|
#define PIOS_MANUAL_STACK_SIZE 724
|
||||||
#define PIOS_TELEM_STACK_SIZE 500
|
#define PIOS_SYSTEM_STACK_SIZE 560
|
||||||
|
#define PIOS_STABILIZATION_STACK_SIZE 524
|
||||||
#define IDLE_COUNTS_PER_SEC_AT_NO_LOAD 1995998
|
#define PIOS_TELEM_STACK_SIZE 500
|
||||||
//#define PIOS_QUATERNION_STABILIZATION
|
|
||||||
|
#define IDLE_COUNTS_PER_SEC_AT_NO_LOAD 1995998
|
||||||
#endif /* PIOS_CONFIG_H */
|
//#define PIOS_QUATERNION_STABILIZATION
|
||||||
/**
|
|
||||||
* @}
|
#endif /* PIOS_CONFIG_H */
|
||||||
* @}
|
/**
|
||||||
*/
|
* @}
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
@ -469,13 +469,13 @@ const struct pios_usart_cfg pios_usart_spektrum_cfg = {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#include <pios_spektrum_priv.h>
|
||||||
static uint32_t pios_usart_spektrum_id;
|
static uint32_t pios_usart_spektrum_id;
|
||||||
void PIOS_USART_spektrum_irq_handler(void)
|
void PIOS_USART_spektrum_irq_handler(void)
|
||||||
{
|
{
|
||||||
SPEKTRUM_IRQHandler(pios_usart_spektrum_id);
|
PIOS_SPEKTRUM_irq_handler(pios_usart_spektrum_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
#include <pios_spektrum_priv.h>
|
|
||||||
void RTC_IRQHandler();
|
void RTC_IRQHandler();
|
||||||
void RTC_IRQHandler() __attribute__ ((alias ("PIOS_SUPV_irq_handler")));
|
void RTC_IRQHandler() __attribute__ ((alias ("PIOS_SUPV_irq_handler")));
|
||||||
const struct pios_spektrum_cfg pios_spektrum_cfg = {
|
const struct pios_spektrum_cfg pios_spektrum_cfg = {
|
||||||
@ -501,7 +501,7 @@ void PIOS_SUPV_irq_handler() {
|
|||||||
if (RTC_GetITStatus(RTC_IT_SEC))
|
if (RTC_GetITStatus(RTC_IT_SEC))
|
||||||
{
|
{
|
||||||
/* Call the right handler */
|
/* Call the right handler */
|
||||||
PIOS_SPEKTRUM_irq_handler(pios_usart_spektrum_id);
|
PIOS_SPEKTRUMSV_irq_handler(pios_usart_spektrum_id);
|
||||||
|
|
||||||
/* Wait until last write operation on RTC registers has finished */
|
/* Wait until last write operation on RTC registers has finished */
|
||||||
RTC_WaitForLastTask();
|
RTC_WaitForLastTask();
|
||||||
@ -561,7 +561,7 @@ const struct pios_usart_cfg pios_usart_sbus_cfg = {
|
|||||||
static uint32_t pios_usart_sbus_id;
|
static uint32_t pios_usart_sbus_id;
|
||||||
void PIOS_USART_sbus_irq_handler(void)
|
void PIOS_USART_sbus_irq_handler(void)
|
||||||
{
|
{
|
||||||
SBUS_IRQHandler(pios_usart_sbus_id);
|
PIOS_SBUS_irq_handler(pios_usart_sbus_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
#include <pios_sbus_priv.h>
|
#include <pios_sbus_priv.h>
|
||||||
@ -587,7 +587,7 @@ void PIOS_SUPV_irq_handler() {
|
|||||||
if (RTC_GetITStatus(RTC_IT_SEC))
|
if (RTC_GetITStatus(RTC_IT_SEC))
|
||||||
{
|
{
|
||||||
/* Call the right handler */
|
/* Call the right handler */
|
||||||
PIOS_SBUS_irq_handler(pios_usart_sbus_id);
|
PIOS_SBUSSV_irq_handler(pios_usart_sbus_id);
|
||||||
|
|
||||||
/* Wait until last write operation on RTC registers has finished */
|
/* Wait until last write operation on RTC registers has finished */
|
||||||
RTC_WaitForLastTask();
|
RTC_WaitForLastTask();
|
||||||
@ -869,6 +869,13 @@ void PIOS_I2C_main_adapter_er_irq_handler(void)
|
|||||||
|
|
||||||
#endif /* PIOS_INCLUDE_I2C */
|
#endif /* PIOS_INCLUDE_I2C */
|
||||||
|
|
||||||
|
#if defined(PIOS_INCLUDE_RCVR)
|
||||||
|
#include "pios_rcvr_priv.h"
|
||||||
|
|
||||||
|
uint32_t pios_rcvr_channel_to_id_map[PIOS_RCVR_MAX_DEVS];
|
||||||
|
uint32_t pios_rcvr_max_channel;
|
||||||
|
#endif /* PIOS_INCLUDE_RCVR */
|
||||||
|
|
||||||
extern const struct pios_com_driver pios_usb_com_driver;
|
extern const struct pios_com_driver pios_usb_com_driver;
|
||||||
|
|
||||||
uint32_t pios_com_telem_rf_id;
|
uint32_t pios_com_telem_rf_id;
|
||||||
@ -897,18 +904,6 @@ void PIOS_Board_Init(void) {
|
|||||||
|
|
||||||
PIOS_FLASHFS_Init();
|
PIOS_FLASHFS_Init();
|
||||||
|
|
||||||
#if defined(PIOS_INCLUDE_SPEKTRUM)
|
|
||||||
/* SPEKTRUM init must come before comms */
|
|
||||||
PIOS_SPEKTRUM_Init();
|
|
||||||
|
|
||||||
if (PIOS_USART_Init(&pios_usart_spektrum_id, &pios_usart_spektrum_cfg)) {
|
|
||||||
PIOS_DEBUG_Assert(0);
|
|
||||||
}
|
|
||||||
if (PIOS_COM_Init(&pios_com_spektrum_id, &pios_usart_com_driver, pios_usart_spektrum_id)) {
|
|
||||||
PIOS_DEBUG_Assert(0);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Initialize UAVObject libraries */
|
/* Initialize UAVObject libraries */
|
||||||
EventDispatcherInitialize();
|
EventDispatcherInitialize();
|
||||||
UAVObjInitialize();
|
UAVObjInitialize();
|
||||||
@ -938,6 +933,26 @@ void PIOS_Board_Init(void) {
|
|||||||
PIOS_DEBUG_Assert(0);
|
PIOS_DEBUG_Assert(0);
|
||||||
}
|
}
|
||||||
#endif /* PIOS_INCLUDE_GPS */
|
#endif /* PIOS_INCLUDE_GPS */
|
||||||
|
#if defined(PIOS_INCLUDE_SPEKTRUM)
|
||||||
|
/* SPEKTRUM init must come before comms */
|
||||||
|
PIOS_SPEKTRUM_Init();
|
||||||
|
|
||||||
|
if (PIOS_USART_Init(&pios_usart_spektrum_id, &pios_usart_spektrum_cfg)) {
|
||||||
|
PIOS_DEBUG_Assert(0);
|
||||||
|
}
|
||||||
|
if (PIOS_COM_Init(&pios_com_spektrum_id, &pios_usart_com_driver, pios_usart_spektrum_id)) {
|
||||||
|
PIOS_DEBUG_Assert(0);
|
||||||
|
}
|
||||||
|
for (uint8_t i = 0; i < PIOS_SPEKTRUM_NUM_INPUTS; i++) {
|
||||||
|
if (!PIOS_RCVR_Init(&pios_rcvr_channel_to_id_map[pios_rcvr_max_channel],
|
||||||
|
&pios_spektrum_rcvr_driver,
|
||||||
|
i)) {
|
||||||
|
pios_rcvr_max_channel++;
|
||||||
|
} else {
|
||||||
|
PIOS_DEBUG_Assert(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
#if defined(PIOS_INCLUDE_SBUS)
|
#if defined(PIOS_INCLUDE_SBUS)
|
||||||
PIOS_SBUS_Init();
|
PIOS_SBUS_Init();
|
||||||
|
|
||||||
@ -947,6 +962,16 @@ void PIOS_Board_Init(void) {
|
|||||||
if (PIOS_COM_Init(&pios_com_sbus_id, &pios_usart_com_driver, pios_usart_sbus_id)) {
|
if (PIOS_COM_Init(&pios_com_sbus_id, &pios_usart_com_driver, pios_usart_sbus_id)) {
|
||||||
PIOS_DEBUG_Assert(0);
|
PIOS_DEBUG_Assert(0);
|
||||||
}
|
}
|
||||||
|
for (uint8_t i = 0; i < SBUS_NUMBER_OF_CHANNELS; i++) {
|
||||||
|
if (!PIOS_RCVR_Init(&pios_rcvr_channel_to_id_map[pios_rcvr_max_channel],
|
||||||
|
&pios_sbus_rcvr_driver,
|
||||||
|
i)) {
|
||||||
|
pios_rcvr_max_channel++;
|
||||||
|
} else {
|
||||||
|
PIOS_DEBUG_Assert(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#endif /* PIOS_INCLUDE_SBUS */
|
#endif /* PIOS_INCLUDE_SBUS */
|
||||||
#endif /* PIOS_INCLUDE_COM */
|
#endif /* PIOS_INCLUDE_COM */
|
||||||
|
|
||||||
@ -958,10 +983,34 @@ void PIOS_Board_Init(void) {
|
|||||||
PIOS_GPIO_Init();
|
PIOS_GPIO_Init();
|
||||||
|
|
||||||
#if defined(PIOS_INCLUDE_PWM)
|
#if defined(PIOS_INCLUDE_PWM)
|
||||||
|
#if (PIOS_PWM_NUM_INPUTS > PIOS_RCVR_MAX_DEVS)
|
||||||
|
#error More receiver inputs than available devices
|
||||||
|
#endif
|
||||||
PIOS_PWM_Init();
|
PIOS_PWM_Init();
|
||||||
|
for (uint8_t i = 0; i < PIOS_PWM_NUM_INPUTS; i++) {
|
||||||
|
if (!PIOS_RCVR_Init(&pios_rcvr_channel_to_id_map[pios_rcvr_max_channel],
|
||||||
|
&pios_pwm_rcvr_driver,
|
||||||
|
i)) {
|
||||||
|
pios_rcvr_max_channel++;
|
||||||
|
} else {
|
||||||
|
PIOS_DEBUG_Assert(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
#if defined(PIOS_INCLUDE_PPM)
|
#if defined(PIOS_INCLUDE_PPM)
|
||||||
|
#if (PIOS_PPM_NUM_INPUTS > PIOS_RCVR_MAX_DEVS)
|
||||||
|
#error More receiver inputs than available devices
|
||||||
|
#endif
|
||||||
PIOS_PPM_Init();
|
PIOS_PPM_Init();
|
||||||
|
for (uint8_t i = 0; i < PIOS_PPM_NUM_INPUTS; i++) {
|
||||||
|
if (!PIOS_RCVR_Init(&pios_rcvr_channel_to_id_map[pios_rcvr_max_channel],
|
||||||
|
&pios_ppm_rcvr_driver,
|
||||||
|
i)) {
|
||||||
|
pios_rcvr_max_channel++;
|
||||||
|
} else {
|
||||||
|
PIOS_DEBUG_Assert(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
#if defined(PIOS_INCLUDE_USB_HID)
|
#if defined(PIOS_INCLUDE_USB_HID)
|
||||||
PIOS_USB_HID_Init(0);
|
PIOS_USB_HID_Init(0);
|
||||||
|
@ -1,630 +1,623 @@
|
|||||||
/**
|
/**
|
||||||
******************************************************************************
|
******************************************************************************
|
||||||
* @addtogroup OpenPilotModules OpenPilot Modules
|
* @addtogroup OpenPilotModules OpenPilot Modules
|
||||||
* @{
|
* @{
|
||||||
* @addtogroup ManualControlModule Manual Control Module
|
* @addtogroup ManualControlModule Manual Control Module
|
||||||
* @brief Provide manual control or allow it alter flight mode.
|
* @brief Provide manual control or allow it alter flight mode.
|
||||||
* @{
|
* @{
|
||||||
*
|
*
|
||||||
* Reads in the ManualControlCommand FlightMode setting from receiver then either
|
* Reads in the ManualControlCommand FlightMode setting from receiver then either
|
||||||
* pass the settings straght to ActuatorDesired object (manual mode) or to
|
* pass the settings straght to ActuatorDesired object (manual mode) or to
|
||||||
* AttitudeDesired object (stabilized mode)
|
* AttitudeDesired object (stabilized mode)
|
||||||
*
|
*
|
||||||
* @file manualcontrol.c
|
* @file manualcontrol.c
|
||||||
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
|
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
|
||||||
* @brief ManualControl module. Handles safety R/C link and flight mode.
|
* @brief ManualControl module. Handles safety R/C link and flight mode.
|
||||||
*
|
*
|
||||||
* @see The GNU Public License (GPL) Version 3
|
* @see The GNU Public License (GPL) Version 3
|
||||||
*
|
*
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
/*
|
/*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
* the Free Software Foundation; either version 3 of the License, or
|
* the Free Software Foundation; either version 3 of the License, or
|
||||||
* (at your option) any later version.
|
* (at your option) any later version.
|
||||||
*
|
*
|
||||||
* This program is distributed in the hope that it will be useful, but
|
* This program is distributed in the hope that it will be useful, but
|
||||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
* for more details.
|
* for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License along
|
* You should have received a copy of the GNU General Public License along
|
||||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "openpilot.h"
|
#include "openpilot.h"
|
||||||
#include "manualcontrol.h"
|
#include "manualcontrol.h"
|
||||||
#include "manualcontrolsettings.h"
|
#include "manualcontrolsettings.h"
|
||||||
#include "stabilizationsettings.h"
|
#include "stabilizationsettings.h"
|
||||||
#include "manualcontrolcommand.h"
|
#include "manualcontrolcommand.h"
|
||||||
#include "actuatordesired.h"
|
#include "actuatordesired.h"
|
||||||
#include "stabilizationdesired.h"
|
#include "stabilizationdesired.h"
|
||||||
#include "flighttelemetrystats.h"
|
#include "flighttelemetrystats.h"
|
||||||
#include "flightstatus.h"
|
#include "flightstatus.h"
|
||||||
#include "accessorydesired.h"
|
#include "accessorydesired.h"
|
||||||
|
|
||||||
// Private constants
|
// Private constants
|
||||||
#if defined(PIOS_MANUAL_STACK_SIZE)
|
#if defined(PIOS_MANUAL_STACK_SIZE)
|
||||||
#define STACK_SIZE_BYTES PIOS_MANUAL_STACK_SIZE
|
#define STACK_SIZE_BYTES PIOS_MANUAL_STACK_SIZE
|
||||||
#else
|
#else
|
||||||
#define STACK_SIZE_BYTES 824
|
#define STACK_SIZE_BYTES 824
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define TASK_PRIORITY (tskIDLE_PRIORITY+4)
|
#define TASK_PRIORITY (tskIDLE_PRIORITY+4)
|
||||||
#define UPDATE_PERIOD_MS 20
|
#define UPDATE_PERIOD_MS 20
|
||||||
#define THROTTLE_FAILSAFE -0.1
|
#define THROTTLE_FAILSAFE -0.1
|
||||||
#define FLIGHT_MODE_LIMIT 1.0/3.0
|
#define FLIGHT_MODE_LIMIT 1.0/3.0
|
||||||
#define ARMED_TIME_MS 1000
|
#define ARMED_TIME_MS 1000
|
||||||
#define ARMED_THRESHOLD 0.50
|
#define ARMED_THRESHOLD 0.50
|
||||||
//safe band to allow a bit of calibration error or trim offset (in microseconds)
|
//safe band to allow a bit of calibration error or trim offset (in microseconds)
|
||||||
#define CONNECTION_OFFSET 150
|
#define CONNECTION_OFFSET 150
|
||||||
|
|
||||||
// Private types
|
// Private types
|
||||||
typedef enum
|
typedef enum
|
||||||
{
|
{
|
||||||
ARM_STATE_DISARMED,
|
ARM_STATE_DISARMED,
|
||||||
ARM_STATE_ARMING_MANUAL,
|
ARM_STATE_ARMING_MANUAL,
|
||||||
ARM_STATE_ARMED,
|
ARM_STATE_ARMED,
|
||||||
ARM_STATE_DISARMING_MANUAL,
|
ARM_STATE_DISARMING_MANUAL,
|
||||||
ARM_STATE_DISARMING_TIMEOUT
|
ARM_STATE_DISARMING_TIMEOUT
|
||||||
} ArmState_t;
|
} ArmState_t;
|
||||||
|
|
||||||
// Private variables
|
// Private variables
|
||||||
static xTaskHandle taskHandle;
|
static xTaskHandle taskHandle;
|
||||||
static ArmState_t armState;
|
static ArmState_t armState;
|
||||||
static portTickType lastSysTime;
|
static portTickType lastSysTime;
|
||||||
|
|
||||||
// Private functions
|
// Private functions
|
||||||
static void updateActuatorDesired(ManualControlCommandData * cmd);
|
static void updateActuatorDesired(ManualControlCommandData * cmd);
|
||||||
static void updateStabilizationDesired(ManualControlCommandData * cmd, ManualControlSettingsData * settings);
|
static void updateStabilizationDesired(ManualControlCommandData * cmd, ManualControlSettingsData * settings);
|
||||||
static void processFlightMode(ManualControlSettingsData * settings, float flightMode);
|
static void processFlightMode(ManualControlSettingsData * settings, float flightMode);
|
||||||
static void processArm(ManualControlCommandData * cmd, ManualControlSettingsData * settings);
|
static void processArm(ManualControlCommandData * cmd, ManualControlSettingsData * settings);
|
||||||
|
|
||||||
static void manualControlTask(void *parameters);
|
static void manualControlTask(void *parameters);
|
||||||
static float scaleChannel(int16_t value, int16_t max, int16_t min, int16_t neutral);
|
static float scaleChannel(int16_t value, int16_t max, int16_t min, int16_t neutral);
|
||||||
static uint32_t timeDifferenceMs(portTickType start_time, portTickType end_time);
|
static uint32_t timeDifferenceMs(portTickType start_time, portTickType end_time);
|
||||||
static bool okToArm(void);
|
static bool okToArm(void);
|
||||||
static bool validInputRange(int16_t min, int16_t max, uint16_t value);
|
static bool validInputRange(int16_t min, int16_t max, uint16_t value);
|
||||||
|
|
||||||
#define assumptions1 ( \
|
#define assumptions1 ( \
|
||||||
((int)MANUALCONTROLSETTINGS_STABILIZATION1SETTINGS_NONE == (int)STABILIZATIONDESIRED_STABILIZATIONMODE_NONE) && \
|
((int)MANUALCONTROLSETTINGS_STABILIZATION1SETTINGS_NONE == (int)STABILIZATIONDESIRED_STABILIZATIONMODE_NONE) && \
|
||||||
((int)MANUALCONTROLSETTINGS_STABILIZATION1SETTINGS_RATE == (int)STABILIZATIONDESIRED_STABILIZATIONMODE_RATE) && \
|
((int)MANUALCONTROLSETTINGS_STABILIZATION1SETTINGS_RATE == (int)STABILIZATIONDESIRED_STABILIZATIONMODE_RATE) && \
|
||||||
((int)MANUALCONTROLSETTINGS_STABILIZATION1SETTINGS_ATTITUDE == (int)STABILIZATIONDESIRED_STABILIZATIONMODE_ATTITUDE) \
|
((int)MANUALCONTROLSETTINGS_STABILIZATION1SETTINGS_ATTITUDE == (int)STABILIZATIONDESIRED_STABILIZATIONMODE_ATTITUDE) \
|
||||||
)
|
)
|
||||||
|
|
||||||
#define assumptions3 ( \
|
#define assumptions3 ( \
|
||||||
((int)MANUALCONTROLSETTINGS_STABILIZATION2SETTINGS_NONE == (int)STABILIZATIONDESIRED_STABILIZATIONMODE_NONE) && \
|
((int)MANUALCONTROLSETTINGS_STABILIZATION2SETTINGS_NONE == (int)STABILIZATIONDESIRED_STABILIZATIONMODE_NONE) && \
|
||||||
((int)MANUALCONTROLSETTINGS_STABILIZATION2SETTINGS_RATE == (int)STABILIZATIONDESIRED_STABILIZATIONMODE_RATE) && \
|
((int)MANUALCONTROLSETTINGS_STABILIZATION2SETTINGS_RATE == (int)STABILIZATIONDESIRED_STABILIZATIONMODE_RATE) && \
|
||||||
((int)MANUALCONTROLSETTINGS_STABILIZATION2SETTINGS_ATTITUDE == (int)STABILIZATIONDESIRED_STABILIZATIONMODE_ATTITUDE) \
|
((int)MANUALCONTROLSETTINGS_STABILIZATION2SETTINGS_ATTITUDE == (int)STABILIZATIONDESIRED_STABILIZATIONMODE_ATTITUDE) \
|
||||||
)
|
)
|
||||||
|
|
||||||
#define assumptions5 ( \
|
#define assumptions5 ( \
|
||||||
((int)MANUALCONTROLSETTINGS_STABILIZATION3SETTINGS_NONE == (int)STABILIZATIONDESIRED_STABILIZATIONMODE_NONE) && \
|
((int)MANUALCONTROLSETTINGS_STABILIZATION3SETTINGS_NONE == (int)STABILIZATIONDESIRED_STABILIZATIONMODE_NONE) && \
|
||||||
((int)MANUALCONTROLSETTINGS_STABILIZATION3SETTINGS_RATE == (int)STABILIZATIONDESIRED_STABILIZATIONMODE_RATE) && \
|
((int)MANUALCONTROLSETTINGS_STABILIZATION3SETTINGS_RATE == (int)STABILIZATIONDESIRED_STABILIZATIONMODE_RATE) && \
|
||||||
((int)MANUALCONTROLSETTINGS_STABILIZATION3SETTINGS_ATTITUDE == (int)STABILIZATIONDESIRED_STABILIZATIONMODE_ATTITUDE) \
|
((int)MANUALCONTROLSETTINGS_STABILIZATION3SETTINGS_ATTITUDE == (int)STABILIZATIONDESIRED_STABILIZATIONMODE_ATTITUDE) \
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#define ARMING_CHANNEL_ROLL 0
|
#define ARMING_CHANNEL_ROLL 0
|
||||||
#define ARMING_CHANNEL_PITCH 1
|
#define ARMING_CHANNEL_PITCH 1
|
||||||
#define ARMING_CHANNEL_YAW 2
|
#define ARMING_CHANNEL_YAW 2
|
||||||
|
|
||||||
#define assumptions7 ( \
|
#define assumptions7 ( \
|
||||||
( ((int)MANUALCONTROLSETTINGS_ARMING_ROLLLEFT -(int)MANUALCONTROLSETTINGS_ARMING_ROLLLEFT)/2 == ARMING_CHANNEL_ROLL) && \
|
( ((int)MANUALCONTROLSETTINGS_ARMING_ROLLLEFT -(int)MANUALCONTROLSETTINGS_ARMING_ROLLLEFT)/2 == ARMING_CHANNEL_ROLL) && \
|
||||||
( ((int)MANUALCONTROLSETTINGS_ARMING_ROLLRIGHT -(int)MANUALCONTROLSETTINGS_ARMING_ROLLLEFT)/2 == ARMING_CHANNEL_ROLL) && \
|
( ((int)MANUALCONTROLSETTINGS_ARMING_ROLLRIGHT -(int)MANUALCONTROLSETTINGS_ARMING_ROLLLEFT)/2 == ARMING_CHANNEL_ROLL) && \
|
||||||
( ((int)MANUALCONTROLSETTINGS_ARMING_PITCHFORWARD -(int)MANUALCONTROLSETTINGS_ARMING_ROLLLEFT)/2 == ARMING_CHANNEL_PITCH) && \
|
( ((int)MANUALCONTROLSETTINGS_ARMING_PITCHFORWARD -(int)MANUALCONTROLSETTINGS_ARMING_ROLLLEFT)/2 == ARMING_CHANNEL_PITCH) && \
|
||||||
( ((int)MANUALCONTROLSETTINGS_ARMING_PITCHAFT -(int)MANUALCONTROLSETTINGS_ARMING_ROLLLEFT)/2 == ARMING_CHANNEL_PITCH) && \
|
( ((int)MANUALCONTROLSETTINGS_ARMING_PITCHAFT -(int)MANUALCONTROLSETTINGS_ARMING_ROLLLEFT)/2 == ARMING_CHANNEL_PITCH) && \
|
||||||
( ((int)MANUALCONTROLSETTINGS_ARMING_YAWLEFT -(int)MANUALCONTROLSETTINGS_ARMING_ROLLLEFT)/2 == ARMING_CHANNEL_YAW) && \
|
( ((int)MANUALCONTROLSETTINGS_ARMING_YAWLEFT -(int)MANUALCONTROLSETTINGS_ARMING_ROLLLEFT)/2 == ARMING_CHANNEL_YAW) && \
|
||||||
( ((int)MANUALCONTROLSETTINGS_ARMING_YAWRIGHT -(int)MANUALCONTROLSETTINGS_ARMING_ROLLLEFT)/2 == ARMING_CHANNEL_YAW) \
|
( ((int)MANUALCONTROLSETTINGS_ARMING_YAWRIGHT -(int)MANUALCONTROLSETTINGS_ARMING_ROLLLEFT)/2 == ARMING_CHANNEL_YAW) \
|
||||||
)
|
)
|
||||||
|
|
||||||
#define assumptions8 ( \
|
#define assumptions8 ( \
|
||||||
( ((int)MANUALCONTROLSETTINGS_ARMING_ROLLLEFT -(int)MANUALCONTROLSETTINGS_ARMING_ROLLLEFT)%2 == 0) && \
|
( ((int)MANUALCONTROLSETTINGS_ARMING_ROLLLEFT -(int)MANUALCONTROLSETTINGS_ARMING_ROLLLEFT)%2 == 0) && \
|
||||||
( ((int)MANUALCONTROLSETTINGS_ARMING_ROLLRIGHT -(int)MANUALCONTROLSETTINGS_ARMING_ROLLLEFT)%2 != 0) && \
|
( ((int)MANUALCONTROLSETTINGS_ARMING_ROLLRIGHT -(int)MANUALCONTROLSETTINGS_ARMING_ROLLLEFT)%2 != 0) && \
|
||||||
( ((int)MANUALCONTROLSETTINGS_ARMING_PITCHFORWARD -(int)MANUALCONTROLSETTINGS_ARMING_ROLLLEFT)%2 == 0) && \
|
( ((int)MANUALCONTROLSETTINGS_ARMING_PITCHFORWARD -(int)MANUALCONTROLSETTINGS_ARMING_ROLLLEFT)%2 == 0) && \
|
||||||
( ((int)MANUALCONTROLSETTINGS_ARMING_PITCHAFT -(int)MANUALCONTROLSETTINGS_ARMING_ROLLLEFT)%2 != 0) && \
|
( ((int)MANUALCONTROLSETTINGS_ARMING_PITCHAFT -(int)MANUALCONTROLSETTINGS_ARMING_ROLLLEFT)%2 != 0) && \
|
||||||
( ((int)MANUALCONTROLSETTINGS_ARMING_YAWLEFT -(int)MANUALCONTROLSETTINGS_ARMING_ROLLLEFT)%2 == 0) && \
|
( ((int)MANUALCONTROLSETTINGS_ARMING_YAWLEFT -(int)MANUALCONTROLSETTINGS_ARMING_ROLLLEFT)%2 == 0) && \
|
||||||
( ((int)MANUALCONTROLSETTINGS_ARMING_YAWRIGHT -(int)MANUALCONTROLSETTINGS_ARMING_ROLLLEFT)%2 != 0) \
|
( ((int)MANUALCONTROLSETTINGS_ARMING_YAWRIGHT -(int)MANUALCONTROLSETTINGS_ARMING_ROLLLEFT)%2 != 0) \
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
#define assumptions_flightmode ( \
|
#define assumptions_flightmode ( \
|
||||||
( (int)MANUALCONTROLSETTINGS_FLIGHTMODEPOSITION_MANUAL == (int) FLIGHTSTATUS_FLIGHTMODE_MANUAL) && \
|
( (int)MANUALCONTROLSETTINGS_FLIGHTMODEPOSITION_MANUAL == (int) FLIGHTSTATUS_FLIGHTMODE_MANUAL) && \
|
||||||
( (int)MANUALCONTROLSETTINGS_FLIGHTMODEPOSITION_STABILIZED1 == (int) FLIGHTSTATUS_FLIGHTMODE_STABILIZED1) && \
|
( (int)MANUALCONTROLSETTINGS_FLIGHTMODEPOSITION_STABILIZED1 == (int) FLIGHTSTATUS_FLIGHTMODE_STABILIZED1) && \
|
||||||
( (int)MANUALCONTROLSETTINGS_FLIGHTMODEPOSITION_STABILIZED2 == (int) FLIGHTSTATUS_FLIGHTMODE_STABILIZED2) && \
|
( (int)MANUALCONTROLSETTINGS_FLIGHTMODEPOSITION_STABILIZED2 == (int) FLIGHTSTATUS_FLIGHTMODE_STABILIZED2) && \
|
||||||
( (int)MANUALCONTROLSETTINGS_FLIGHTMODEPOSITION_STABILIZED3 == (int) FLIGHTSTATUS_FLIGHTMODE_STABILIZED3) && \
|
( (int)MANUALCONTROLSETTINGS_FLIGHTMODEPOSITION_STABILIZED3 == (int) FLIGHTSTATUS_FLIGHTMODE_STABILIZED3) && \
|
||||||
( (int)MANUALCONTROLSETTINGS_FLIGHTMODEPOSITION_VELOCITYCONTROL == (int) FLIGHTSTATUS_FLIGHTMODE_VELOCITYCONTROL) && \
|
( (int)MANUALCONTROLSETTINGS_FLIGHTMODEPOSITION_VELOCITYCONTROL == (int) FLIGHTSTATUS_FLIGHTMODE_VELOCITYCONTROL) && \
|
||||||
( (int)MANUALCONTROLSETTINGS_FLIGHTMODEPOSITION_POSITIONHOLD == (int) FLIGHTSTATUS_FLIGHTMODE_POSITIONHOLD) \
|
( (int)MANUALCONTROLSETTINGS_FLIGHTMODEPOSITION_POSITIONHOLD == (int) FLIGHTSTATUS_FLIGHTMODE_POSITIONHOLD) \
|
||||||
)
|
)
|
||||||
|
|
||||||
#define assumptions (assumptions1 && assumptions3 && assumptions5 && assumptions7 && assumptions8 && assumptions_flightmode)
|
#define assumptions (assumptions1 && assumptions3 && assumptions5 && assumptions7 && assumptions8 && assumptions_flightmode)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Module initialization
|
* Module initialization
|
||||||
*/
|
*/
|
||||||
int32_t ManualControlInitialize()
|
int32_t ManualControlInitialize()
|
||||||
{
|
{
|
||||||
/* Check the assumptions about uavobject enum's are correct */
|
/* Check the assumptions about uavobject enum's are correct */
|
||||||
if(!assumptions)
|
if(!assumptions)
|
||||||
return -1;
|
return -1;
|
||||||
// Start main task
|
// Start main task
|
||||||
xTaskCreate(manualControlTask, (signed char *)"ManualControl", STACK_SIZE_BYTES/4, NULL, TASK_PRIORITY, &taskHandle);
|
xTaskCreate(manualControlTask, (signed char *)"ManualControl", STACK_SIZE_BYTES/4, NULL, TASK_PRIORITY, &taskHandle);
|
||||||
TaskMonitorAdd(TASKINFO_RUNNING_MANUALCONTROL, taskHandle);
|
TaskMonitorAdd(TASKINFO_RUNNING_MANUALCONTROL, taskHandle);
|
||||||
PIOS_WDG_RegisterFlag(PIOS_WDG_MANUAL);
|
PIOS_WDG_RegisterFlag(PIOS_WDG_MANUAL);
|
||||||
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Module task
|
* Module task
|
||||||
*/
|
*/
|
||||||
static void manualControlTask(void *parameters)
|
static void manualControlTask(void *parameters)
|
||||||
{
|
{
|
||||||
ManualControlSettingsData settings;
|
ManualControlSettingsData settings;
|
||||||
ManualControlCommandData cmd;
|
ManualControlCommandData cmd;
|
||||||
FlightStatusData flightStatus;
|
FlightStatusData flightStatus;
|
||||||
float flightMode = 0;
|
float flightMode = 0;
|
||||||
|
|
||||||
uint8_t disconnected_count = 0;
|
uint8_t disconnected_count = 0;
|
||||||
uint8_t connected_count = 0;
|
uint8_t connected_count = 0;
|
||||||
|
|
||||||
// For now manual instantiate extra instances of Accessory Desired. In future should be done dynamically
|
// For now manual instantiate extra instances of Accessory Desired. In future should be done dynamically
|
||||||
// this includes not even registering it if not used
|
// this includes not even registering it if not used
|
||||||
AccessoryDesiredCreateInstance();
|
AccessoryDesiredCreateInstance();
|
||||||
AccessoryDesiredCreateInstance();
|
AccessoryDesiredCreateInstance();
|
||||||
|
|
||||||
// Make sure unarmed on power up
|
// Make sure unarmed on power up
|
||||||
ManualControlCommandGet(&cmd);
|
ManualControlCommandGet(&cmd);
|
||||||
FlightStatusGet(&flightStatus);
|
FlightStatusGet(&flightStatus);
|
||||||
flightStatus.Armed = FLIGHTSTATUS_ARMED_DISARMED;
|
flightStatus.Armed = FLIGHTSTATUS_ARMED_DISARMED;
|
||||||
armState = ARM_STATE_DISARMED;
|
armState = ARM_STATE_DISARMED;
|
||||||
|
|
||||||
// Main task loop
|
// Main task loop
|
||||||
lastSysTime = xTaskGetTickCount();
|
lastSysTime = xTaskGetTickCount();
|
||||||
while (1) {
|
while (1) {
|
||||||
float scaledChannel[MANUALCONTROLCOMMAND_CHANNEL_NUMELEM];
|
float scaledChannel[MANUALCONTROLCOMMAND_CHANNEL_NUMELEM];
|
||||||
|
|
||||||
// Wait until next update
|
// Wait until next update
|
||||||
vTaskDelayUntil(&lastSysTime, UPDATE_PERIOD_MS / portTICK_RATE_MS);
|
vTaskDelayUntil(&lastSysTime, UPDATE_PERIOD_MS / portTICK_RATE_MS);
|
||||||
PIOS_WDG_UpdateFlag(PIOS_WDG_MANUAL);
|
PIOS_WDG_UpdateFlag(PIOS_WDG_MANUAL);
|
||||||
|
|
||||||
// Read settings
|
// Read settings
|
||||||
ManualControlSettingsGet(&settings);
|
ManualControlSettingsGet(&settings);
|
||||||
|
|
||||||
if (ManualControlCommandReadOnly(&cmd)) {
|
if (ManualControlCommandReadOnly(&cmd)) {
|
||||||
FlightTelemetryStatsData flightTelemStats;
|
FlightTelemetryStatsData flightTelemStats;
|
||||||
FlightTelemetryStatsGet(&flightTelemStats);
|
FlightTelemetryStatsGet(&flightTelemStats);
|
||||||
if(flightTelemStats.Status != FLIGHTTELEMETRYSTATS_STATUS_CONNECTED) {
|
if(flightTelemStats.Status != FLIGHTTELEMETRYSTATS_STATUS_CONNECTED) {
|
||||||
/* trying to fly via GCS and lost connection. fall back to transmitter */
|
/* trying to fly via GCS and lost connection. fall back to transmitter */
|
||||||
UAVObjMetadata metadata;
|
UAVObjMetadata metadata;
|
||||||
UAVObjGetMetadata(&cmd, &metadata);
|
UAVObjGetMetadata(&cmd, &metadata);
|
||||||
metadata.access = ACCESS_READWRITE;
|
metadata.access = ACCESS_READWRITE;
|
||||||
UAVObjSetMetadata(&cmd, &metadata);
|
UAVObjSetMetadata(&cmd, &metadata);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!ManualControlCommandReadOnly(&cmd)) {
|
if (!ManualControlCommandReadOnly(&cmd)) {
|
||||||
|
|
||||||
// Read channel values in us
|
// Read channel values in us
|
||||||
// TODO: settings.InputMode is currently ignored because PIOS will not allow runtime
|
for (int n = 0; n < MANUALCONTROLCOMMAND_CHANNEL_NUMELEM; ++n) {
|
||||||
// selection of PWM and PPM. The configuration is currently done at compile time in
|
if (pios_rcvr_channel_to_id_map[n]) {
|
||||||
// the pios_config.h file.
|
cmd.Channel[n] = PIOS_RCVR_Read(pios_rcvr_channel_to_id_map[n]);
|
||||||
for (int n = 0; n < MANUALCONTROLCOMMAND_CHANNEL_NUMELEM; ++n) {
|
} else {
|
||||||
#if defined(PIOS_INCLUDE_PWM)
|
cmd.Channel[n] = -1;
|
||||||
cmd.Channel[n] = PIOS_PWM_Get(n);
|
}
|
||||||
#elif defined(PIOS_INCLUDE_PPM)
|
scaledChannel[n] = scaleChannel(cmd.Channel[n], settings.ChannelMax[n], settings.ChannelMin[n], settings.ChannelNeutral[n]);
|
||||||
cmd.Channel[n] = PIOS_PPM_Get(n);
|
}
|
||||||
#elif defined(PIOS_INCLUDE_SPEKTRUM)
|
|
||||||
cmd.Channel[n] = PIOS_SPEKTRUM_Get(n);
|
// Check settings, if error raise alarm
|
||||||
#elif defined(PIOS_INCLUDE_SBUS)
|
if (settings.Roll >= MANUALCONTROLSETTINGS_ROLL_NONE ||
|
||||||
cmd.Channel[n] = PIOS_SBUS_Get(n);
|
settings.Pitch >= MANUALCONTROLSETTINGS_PITCH_NONE ||
|
||||||
#endif
|
settings.Yaw >= MANUALCONTROLSETTINGS_YAW_NONE ||
|
||||||
scaledChannel[n] = scaleChannel(cmd.Channel[n], settings.ChannelMax[n], settings.ChannelMin[n], settings.ChannelNeutral[n]);
|
settings.Throttle >= MANUALCONTROLSETTINGS_THROTTLE_NONE ||
|
||||||
}
|
settings.FlightMode >= MANUALCONTROLSETTINGS_FLIGHTMODE_NONE) {
|
||||||
|
AlarmsSet(SYSTEMALARMS_ALARM_MANUALCONTROL, SYSTEMALARMS_ALARM_CRITICAL);
|
||||||
// Check settings, if error raise alarm
|
cmd.Connected = MANUALCONTROLCOMMAND_CONNECTED_FALSE;
|
||||||
if (settings.Roll >= MANUALCONTROLSETTINGS_ROLL_NONE ||
|
ManualControlCommandSet(&cmd);
|
||||||
settings.Pitch >= MANUALCONTROLSETTINGS_PITCH_NONE ||
|
continue;
|
||||||
settings.Yaw >= MANUALCONTROLSETTINGS_YAW_NONE ||
|
}
|
||||||
settings.Throttle >= MANUALCONTROLSETTINGS_THROTTLE_NONE ||
|
|
||||||
settings.FlightMode >= MANUALCONTROLSETTINGS_FLIGHTMODE_NONE) {
|
// decide if we have valid manual input or not
|
||||||
AlarmsSet(SYSTEMALARMS_ALARM_MANUALCONTROL, SYSTEMALARMS_ALARM_CRITICAL);
|
bool valid_input_detected = validInputRange(settings.ChannelMin[settings.Throttle], settings.ChannelMax[settings.Throttle], cmd.Channel[settings.Throttle]) &&
|
||||||
cmd.Connected = MANUALCONTROLCOMMAND_CONNECTED_FALSE;
|
validInputRange(settings.ChannelMin[settings.Roll], settings.ChannelMax[settings.Roll], cmd.Channel[settings.Roll]) &&
|
||||||
ManualControlCommandSet(&cmd);
|
validInputRange(settings.ChannelMin[settings.Yaw], settings.ChannelMax[settings.Yaw], cmd.Channel[settings.Yaw]) &&
|
||||||
continue;
|
validInputRange(settings.ChannelMin[settings.Pitch], settings.ChannelMax[settings.Pitch], cmd.Channel[settings.Pitch]);
|
||||||
}
|
|
||||||
|
// Implement hysteresis loop on connection status
|
||||||
// decide if we have valid manual input or not
|
if (valid_input_detected && (++connected_count > 10)) {
|
||||||
bool valid_input_detected = validInputRange(settings.ChannelMin[settings.Throttle], settings.ChannelMax[settings.Throttle], cmd.Channel[settings.Throttle]) &&
|
cmd.Connected = MANUALCONTROLCOMMAND_CONNECTED_TRUE;
|
||||||
validInputRange(settings.ChannelMin[settings.Roll], settings.ChannelMax[settings.Roll], cmd.Channel[settings.Roll]) &&
|
connected_count = 0;
|
||||||
validInputRange(settings.ChannelMin[settings.Yaw], settings.ChannelMax[settings.Yaw], cmd.Channel[settings.Yaw]) &&
|
disconnected_count = 0;
|
||||||
validInputRange(settings.ChannelMin[settings.Pitch], settings.ChannelMax[settings.Pitch], cmd.Channel[settings.Pitch]);
|
} else if (!valid_input_detected && (++disconnected_count > 10)) {
|
||||||
|
cmd.Connected = MANUALCONTROLCOMMAND_CONNECTED_FALSE;
|
||||||
// Implement hysteresis loop on connection status
|
connected_count = 0;
|
||||||
if (valid_input_detected && (++connected_count > 10)) {
|
disconnected_count = 0;
|
||||||
cmd.Connected = MANUALCONTROLCOMMAND_CONNECTED_TRUE;
|
}
|
||||||
connected_count = 0;
|
|
||||||
disconnected_count = 0;
|
if (cmd.Connected == MANUALCONTROLCOMMAND_CONNECTED_FALSE) {
|
||||||
} else if (!valid_input_detected && (++disconnected_count > 10)) {
|
cmd.Throttle = -1; // Shut down engine with no control
|
||||||
cmd.Connected = MANUALCONTROLCOMMAND_CONNECTED_FALSE;
|
cmd.Roll = 0;
|
||||||
connected_count = 0;
|
cmd.Yaw = 0;
|
||||||
disconnected_count = 0;
|
cmd.Pitch = 0;
|
||||||
}
|
//cmd.FlightMode = MANUALCONTROLCOMMAND_FLIGHTMODE_AUTO; // don't do until AUTO implemented and functioning
|
||||||
|
// Important: Throttle < 0 will reset Stabilization coefficients among other things. Either change this,
|
||||||
if (cmd.Connected == MANUALCONTROLCOMMAND_CONNECTED_FALSE) {
|
// or leave throttle at IDLE speed or above when going into AUTO-failsafe.
|
||||||
cmd.Throttle = -1; // Shut down engine with no control
|
AlarmsSet(SYSTEMALARMS_ALARM_MANUALCONTROL, SYSTEMALARMS_ALARM_WARNING);
|
||||||
cmd.Roll = 0;
|
ManualControlCommandSet(&cmd);
|
||||||
cmd.Yaw = 0;
|
} else {
|
||||||
cmd.Pitch = 0;
|
AlarmsClear(SYSTEMALARMS_ALARM_MANUALCONTROL);
|
||||||
//cmd.FlightMode = MANUALCONTROLCOMMAND_FLIGHTMODE_AUTO; // don't do until AUTO implemented and functioning
|
|
||||||
// Important: Throttle < 0 will reset Stabilization coefficients among other things. Either change this,
|
// Scale channels to -1 -> +1 range
|
||||||
// or leave throttle at IDLE speed or above when going into AUTO-failsafe.
|
cmd.Roll = scaledChannel[settings.Roll];
|
||||||
AlarmsSet(SYSTEMALARMS_ALARM_MANUALCONTROL, SYSTEMALARMS_ALARM_WARNING);
|
cmd.Pitch = scaledChannel[settings.Pitch];
|
||||||
ManualControlCommandSet(&cmd);
|
cmd.Yaw = scaledChannel[settings.Yaw];
|
||||||
} else {
|
cmd.Throttle = scaledChannel[settings.Throttle];
|
||||||
AlarmsClear(SYSTEMALARMS_ALARM_MANUALCONTROL);
|
flightMode = scaledChannel[settings.FlightMode];
|
||||||
|
|
||||||
// Scale channels to -1 -> +1 range
|
AccessoryDesiredData accessory;
|
||||||
cmd.Roll = scaledChannel[settings.Roll];
|
// Set Accessory 0
|
||||||
cmd.Pitch = scaledChannel[settings.Pitch];
|
if(settings.Accessory0 != MANUALCONTROLSETTINGS_ACCESSORY0_NONE) {
|
||||||
cmd.Yaw = scaledChannel[settings.Yaw];
|
accessory.AccessoryVal = scaledChannel[settings.Accessory0];
|
||||||
cmd.Throttle = scaledChannel[settings.Throttle];
|
if(AccessoryDesiredInstSet(0, &accessory) != 0)
|
||||||
flightMode = scaledChannel[settings.FlightMode];
|
AlarmsSet(SYSTEMALARMS_ALARM_MANUALCONTROL, SYSTEMALARMS_ALARM_WARNING);
|
||||||
|
}
|
||||||
AccessoryDesiredData accessory;
|
// Set Accessory 1
|
||||||
// Set Accessory 0
|
if(settings.Accessory1 != MANUALCONTROLSETTINGS_ACCESSORY1_NONE) {
|
||||||
if(settings.Accessory0 != MANUALCONTROLSETTINGS_ACCESSORY0_NONE) {
|
accessory.AccessoryVal = scaledChannel[settings.Accessory1];
|
||||||
accessory.AccessoryVal = scaledChannel[settings.Accessory0];
|
if(AccessoryDesiredInstSet(1, &accessory) != 0)
|
||||||
if(AccessoryDesiredInstSet(0, &accessory) != 0)
|
AlarmsSet(SYSTEMALARMS_ALARM_MANUALCONTROL, SYSTEMALARMS_ALARM_WARNING);
|
||||||
AlarmsSet(SYSTEMALARMS_ALARM_MANUALCONTROL, SYSTEMALARMS_ALARM_WARNING);
|
}
|
||||||
}
|
// Set Accsesory 2
|
||||||
// Set Accessory 1
|
if(settings.Accessory2 != MANUALCONTROLSETTINGS_ACCESSORY2_NONE) {
|
||||||
if(settings.Accessory1 != MANUALCONTROLSETTINGS_ACCESSORY1_NONE) {
|
accessory.AccessoryVal = scaledChannel[settings.Accessory2];
|
||||||
accessory.AccessoryVal = scaledChannel[settings.Accessory1];
|
if(AccessoryDesiredInstSet(2, &accessory) != 0)
|
||||||
if(AccessoryDesiredInstSet(1, &accessory) != 0)
|
AlarmsSet(SYSTEMALARMS_ALARM_MANUALCONTROL, SYSTEMALARMS_ALARM_WARNING);
|
||||||
AlarmsSet(SYSTEMALARMS_ALARM_MANUALCONTROL, SYSTEMALARMS_ALARM_WARNING);
|
}
|
||||||
}
|
|
||||||
// Set Accsesory 2
|
|
||||||
if(settings.Accessory2 != MANUALCONTROLSETTINGS_ACCESSORY2_NONE) {
|
processFlightMode(&settings, flightMode);
|
||||||
accessory.AccessoryVal = scaledChannel[settings.Accessory2];
|
processArm(&cmd, &settings);
|
||||||
if(AccessoryDesiredInstSet(2, &accessory) != 0)
|
|
||||||
AlarmsSet(SYSTEMALARMS_ALARM_MANUALCONTROL, SYSTEMALARMS_ALARM_WARNING);
|
// Update cmd object
|
||||||
}
|
ManualControlCommandSet(&cmd);
|
||||||
|
|
||||||
|
}
|
||||||
processFlightMode(&settings, flightMode);
|
|
||||||
processArm(&cmd, &settings);
|
} else {
|
||||||
|
ManualControlCommandGet(&cmd); /* Under GCS control */
|
||||||
// Update cmd object
|
}
|
||||||
ManualControlCommandSet(&cmd);
|
|
||||||
|
|
||||||
}
|
FlightStatusGet(&flightStatus);
|
||||||
|
|
||||||
} else {
|
// Depending on the mode update the Stabilization or Actuator objects
|
||||||
ManualControlCommandGet(&cmd); /* Under GCS control */
|
switch(PARSE_FLIGHT_MODE(flightStatus.FlightMode)) {
|
||||||
}
|
case FLIGHTMODE_UNDEFINED:
|
||||||
|
// This reflects a bug in the code architecture!
|
||||||
|
AlarmsSet(SYSTEMALARMS_ALARM_MANUALCONTROL, SYSTEMALARMS_ALARM_CRITICAL);
|
||||||
FlightStatusGet(&flightStatus);
|
break;
|
||||||
|
case FLIGHTMODE_MANUAL:
|
||||||
// Depending on the mode update the Stabilization or Actuator objects
|
updateActuatorDesired(&cmd);
|
||||||
switch(PARSE_FLIGHT_MODE(flightStatus.FlightMode)) {
|
break;
|
||||||
case FLIGHTMODE_UNDEFINED:
|
case FLIGHTMODE_STABILIZED:
|
||||||
// This reflects a bug in the code architecture!
|
updateStabilizationDesired(&cmd, &settings);
|
||||||
AlarmsSet(SYSTEMALARMS_ALARM_MANUALCONTROL, SYSTEMALARMS_ALARM_CRITICAL);
|
break;
|
||||||
break;
|
case FLIGHTMODE_GUIDANCE:
|
||||||
case FLIGHTMODE_MANUAL:
|
// TODO: Implement
|
||||||
updateActuatorDesired(&cmd);
|
break;
|
||||||
break;
|
}
|
||||||
case FLIGHTMODE_STABILIZED:
|
}
|
||||||
updateStabilizationDesired(&cmd, &settings);
|
}
|
||||||
break;
|
|
||||||
case FLIGHTMODE_GUIDANCE:
|
static void updateActuatorDesired(ManualControlCommandData * cmd)
|
||||||
// TODO: Implement
|
{
|
||||||
break;
|
ActuatorDesiredData actuator;
|
||||||
}
|
ActuatorDesiredGet(&actuator);
|
||||||
}
|
actuator.Roll = cmd->Roll;
|
||||||
}
|
actuator.Pitch = cmd->Pitch;
|
||||||
|
actuator.Yaw = cmd->Yaw;
|
||||||
static void updateActuatorDesired(ManualControlCommandData * cmd)
|
actuator.Throttle = (cmd->Throttle < 0) ? -1 : cmd->Throttle;
|
||||||
{
|
ActuatorDesiredSet(&actuator);
|
||||||
ActuatorDesiredData actuator;
|
}
|
||||||
ActuatorDesiredGet(&actuator);
|
|
||||||
actuator.Roll = cmd->Roll;
|
static void updateStabilizationDesired(ManualControlCommandData * cmd, ManualControlSettingsData * settings)
|
||||||
actuator.Pitch = cmd->Pitch;
|
{
|
||||||
actuator.Yaw = cmd->Yaw;
|
StabilizationDesiredData stabilization;
|
||||||
actuator.Throttle = (cmd->Throttle < 0) ? -1 : cmd->Throttle;
|
StabilizationDesiredGet(&stabilization);
|
||||||
ActuatorDesiredSet(&actuator);
|
|
||||||
}
|
StabilizationSettingsData stabSettings;
|
||||||
|
StabilizationSettingsGet(&stabSettings);
|
||||||
static void updateStabilizationDesired(ManualControlCommandData * cmd, ManualControlSettingsData * settings)
|
|
||||||
{
|
uint8_t * stab_settings;
|
||||||
StabilizationDesiredData stabilization;
|
FlightStatusData flightStatus;
|
||||||
StabilizationDesiredGet(&stabilization);
|
FlightStatusGet(&flightStatus);
|
||||||
|
switch(flightStatus.FlightMode) {
|
||||||
StabilizationSettingsData stabSettings;
|
case FLIGHTSTATUS_FLIGHTMODE_STABILIZED1:
|
||||||
StabilizationSettingsGet(&stabSettings);
|
stab_settings = settings->Stabilization1Settings;
|
||||||
|
break;
|
||||||
uint8_t * stab_settings;
|
case FLIGHTSTATUS_FLIGHTMODE_STABILIZED2:
|
||||||
FlightStatusData flightStatus;
|
stab_settings = settings->Stabilization2Settings;
|
||||||
FlightStatusGet(&flightStatus);
|
break;
|
||||||
switch(flightStatus.FlightMode) {
|
case FLIGHTSTATUS_FLIGHTMODE_STABILIZED3:
|
||||||
case FLIGHTSTATUS_FLIGHTMODE_STABILIZED1:
|
stab_settings = settings->Stabilization3Settings;
|
||||||
stab_settings = settings->Stabilization1Settings;
|
break;
|
||||||
break;
|
default:
|
||||||
case FLIGHTSTATUS_FLIGHTMODE_STABILIZED2:
|
// Major error, this should not occur because only enter this block when one of these is true
|
||||||
stab_settings = settings->Stabilization2Settings;
|
AlarmsSet(SYSTEMALARMS_ALARM_MANUALCONTROL, SYSTEMALARMS_ALARM_CRITICAL);
|
||||||
break;
|
return;
|
||||||
case FLIGHTSTATUS_FLIGHTMODE_STABILIZED3:
|
}
|
||||||
stab_settings = settings->Stabilization3Settings;
|
|
||||||
break;
|
// TOOD: Add assumption about order of stabilization desired and manual control stabilization mode fields having same order
|
||||||
default:
|
stabilization.StabilizationMode[STABILIZATIONDESIRED_STABILIZATIONMODE_ROLL] = stab_settings[0];
|
||||||
// Major error, this should not occur because only enter this block when one of these is true
|
stabilization.StabilizationMode[STABILIZATIONDESIRED_STABILIZATIONMODE_PITCH] = stab_settings[1];
|
||||||
AlarmsSet(SYSTEMALARMS_ALARM_MANUALCONTROL, SYSTEMALARMS_ALARM_CRITICAL);
|
stabilization.StabilizationMode[STABILIZATIONDESIRED_STABILIZATIONMODE_YAW] = stab_settings[2];
|
||||||
return;
|
|
||||||
}
|
stabilization.Roll = (stab_settings[0] == STABILIZATIONDESIRED_STABILIZATIONMODE_NONE) ? cmd->Roll :
|
||||||
|
(stab_settings[0] == STABILIZATIONDESIRED_STABILIZATIONMODE_RATE) ? cmd->Roll * stabSettings.ManualRate[STABILIZATIONSETTINGS_MANUALRATE_ROLL] :
|
||||||
// TOOD: Add assumption about order of stabilization desired and manual control stabilization mode fields having same order
|
(stab_settings[0] == STABILIZATIONDESIRED_STABILIZATIONMODE_ATTITUDE) ? cmd->Roll * stabSettings.RollMax :
|
||||||
stabilization.StabilizationMode[STABILIZATIONDESIRED_STABILIZATIONMODE_ROLL] = stab_settings[0];
|
0; // this is an invalid mode
|
||||||
stabilization.StabilizationMode[STABILIZATIONDESIRED_STABILIZATIONMODE_PITCH] = stab_settings[1];
|
;
|
||||||
stabilization.StabilizationMode[STABILIZATIONDESIRED_STABILIZATIONMODE_YAW] = stab_settings[2];
|
stabilization.Pitch = (stab_settings[1] == STABILIZATIONDESIRED_STABILIZATIONMODE_NONE) ? cmd->Pitch :
|
||||||
|
(stab_settings[1] == STABILIZATIONDESIRED_STABILIZATIONMODE_RATE) ? cmd->Pitch * stabSettings.ManualRate[STABILIZATIONSETTINGS_MANUALRATE_PITCH] :
|
||||||
stabilization.Roll = (stab_settings[0] == STABILIZATIONDESIRED_STABILIZATIONMODE_NONE) ? cmd->Roll :
|
(stab_settings[1] == STABILIZATIONDESIRED_STABILIZATIONMODE_ATTITUDE) ? cmd->Pitch * stabSettings.PitchMax :
|
||||||
(stab_settings[0] == STABILIZATIONDESIRED_STABILIZATIONMODE_RATE) ? cmd->Roll * stabSettings.ManualRate[STABILIZATIONSETTINGS_MANUALRATE_ROLL] :
|
0; // this is an invalid mode
|
||||||
(stab_settings[0] == STABILIZATIONDESIRED_STABILIZATIONMODE_ATTITUDE) ? cmd->Roll * stabSettings.RollMax :
|
|
||||||
0; // this is an invalid mode
|
stabilization.Yaw = (stab_settings[2] == STABILIZATIONDESIRED_STABILIZATIONMODE_NONE) ? cmd->Yaw :
|
||||||
;
|
(stab_settings[2] == STABILIZATIONDESIRED_STABILIZATIONMODE_RATE) ? cmd->Yaw * stabSettings.ManualRate[STABILIZATIONSETTINGS_MANUALRATE_YAW] :
|
||||||
stabilization.Pitch = (stab_settings[1] == STABILIZATIONDESIRED_STABILIZATIONMODE_NONE) ? cmd->Pitch :
|
(stab_settings[2] == STABILIZATIONDESIRED_STABILIZATIONMODE_ATTITUDE) ? fmod(cmd->Yaw * 180.0, 360) :
|
||||||
(stab_settings[1] == STABILIZATIONDESIRED_STABILIZATIONMODE_RATE) ? cmd->Pitch * stabSettings.ManualRate[STABILIZATIONSETTINGS_MANUALRATE_PITCH] :
|
0; // this is an invalid mode
|
||||||
(stab_settings[1] == STABILIZATIONDESIRED_STABILIZATIONMODE_ATTITUDE) ? cmd->Pitch * stabSettings.PitchMax :
|
|
||||||
0; // this is an invalid mode
|
stabilization.Throttle = (cmd->Throttle < 0) ? -1 : cmd->Throttle;
|
||||||
|
StabilizationDesiredSet(&stabilization);
|
||||||
stabilization.Yaw = (stab_settings[2] == STABILIZATIONDESIRED_STABILIZATIONMODE_NONE) ? cmd->Yaw :
|
}
|
||||||
(stab_settings[2] == STABILIZATIONDESIRED_STABILIZATIONMODE_RATE) ? cmd->Yaw * stabSettings.ManualRate[STABILIZATIONSETTINGS_MANUALRATE_YAW] :
|
|
||||||
(stab_settings[2] == STABILIZATIONDESIRED_STABILIZATIONMODE_ATTITUDE) ? fmod(cmd->Yaw * 180.0, 360) :
|
/**
|
||||||
0; // this is an invalid mode
|
* Convert channel from servo pulse duration (microseconds) to scaled -1/+1 range.
|
||||||
|
*/
|
||||||
stabilization.Throttle = (cmd->Throttle < 0) ? -1 : cmd->Throttle;
|
static float scaleChannel(int16_t value, int16_t max, int16_t min, int16_t neutral)
|
||||||
StabilizationDesiredSet(&stabilization);
|
{
|
||||||
}
|
float valueScaled;
|
||||||
|
|
||||||
/**
|
// Scale
|
||||||
* Convert channel from servo pulse duration (microseconds) to scaled -1/+1 range.
|
if ((max > min && value >= neutral) || (min > max && value <= neutral))
|
||||||
*/
|
{
|
||||||
static float scaleChannel(int16_t value, int16_t max, int16_t min, int16_t neutral)
|
if (max != neutral)
|
||||||
{
|
valueScaled = (float)(value - neutral) / (float)(max - neutral);
|
||||||
float valueScaled;
|
else
|
||||||
|
valueScaled = 0;
|
||||||
// Scale
|
}
|
||||||
if ((max > min && value >= neutral) || (min > max && value <= neutral))
|
else
|
||||||
{
|
{
|
||||||
if (max != neutral)
|
if (min != neutral)
|
||||||
valueScaled = (float)(value - neutral) / (float)(max - neutral);
|
valueScaled = (float)(value - neutral) / (float)(neutral - min);
|
||||||
else
|
else
|
||||||
valueScaled = 0;
|
valueScaled = 0;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
// Bound
|
||||||
if (min != neutral)
|
if (valueScaled > 1.0) valueScaled = 1.0;
|
||||||
valueScaled = (float)(value - neutral) / (float)(neutral - min);
|
else
|
||||||
else
|
if (valueScaled < -1.0) valueScaled = -1.0;
|
||||||
valueScaled = 0;
|
|
||||||
}
|
return valueScaled;
|
||||||
|
}
|
||||||
// Bound
|
|
||||||
if (valueScaled > 1.0) valueScaled = 1.0;
|
static uint32_t timeDifferenceMs(portTickType start_time, portTickType end_time) {
|
||||||
else
|
if(end_time > start_time)
|
||||||
if (valueScaled < -1.0) valueScaled = -1.0;
|
return (end_time - start_time) * portTICK_RATE_MS;
|
||||||
|
return ((((portTICK_RATE_MS) -1) - start_time) + end_time) * portTICK_RATE_MS;
|
||||||
return valueScaled;
|
}
|
||||||
}
|
|
||||||
|
/**
|
||||||
static uint32_t timeDifferenceMs(portTickType start_time, portTickType end_time) {
|
* @brief Determine if the aircraft is safe to arm
|
||||||
if(end_time > start_time)
|
* @returns True if safe to arm, false otherwise
|
||||||
return (end_time - start_time) * portTICK_RATE_MS;
|
*/
|
||||||
return ((((portTICK_RATE_MS) -1) - start_time) + end_time) * portTICK_RATE_MS;
|
static bool okToArm(void)
|
||||||
}
|
{
|
||||||
|
// read alarms
|
||||||
/**
|
SystemAlarmsData alarms;
|
||||||
* @brief Determine if the aircraft is safe to arm
|
SystemAlarmsGet(&alarms);
|
||||||
* @returns True if safe to arm, false otherwise
|
|
||||||
*/
|
|
||||||
static bool okToArm(void)
|
// Check each alarm
|
||||||
{
|
for (int i = 0; i < SYSTEMALARMS_ALARM_NUMELEM; i++)
|
||||||
// read alarms
|
{
|
||||||
SystemAlarmsData alarms;
|
if (alarms.Alarm[i] >= SYSTEMALARMS_ALARM_ERROR)
|
||||||
SystemAlarmsGet(&alarms);
|
{ // found an alarm thats set
|
||||||
|
if (i == SYSTEMALARMS_ALARM_GPS || i == SYSTEMALARMS_ALARM_TELEMETRY)
|
||||||
|
continue;
|
||||||
// Check each alarm
|
|
||||||
for (int i = 0; i < SYSTEMALARMS_ALARM_NUMELEM; i++)
|
return false;
|
||||||
{
|
}
|
||||||
if (alarms.Alarm[i] >= SYSTEMALARMS_ALARM_ERROR)
|
}
|
||||||
{ // found an alarm thats set
|
|
||||||
if (i == SYSTEMALARMS_ALARM_GPS || i == SYSTEMALARMS_ALARM_TELEMETRY)
|
return true;
|
||||||
continue;
|
}
|
||||||
|
|
||||||
return false;
|
/**
|
||||||
}
|
* @brief Update the flightStatus object only if value changed. Reduces callbacks
|
||||||
}
|
* @param[in] val The new value
|
||||||
|
*/
|
||||||
return true;
|
static void setArmedIfChanged(uint8_t val) {
|
||||||
}
|
FlightStatusData flightStatus;
|
||||||
|
FlightStatusGet(&flightStatus);
|
||||||
/**
|
|
||||||
* @brief Update the flightStatus object only if value changed. Reduces callbacks
|
if(flightStatus.Armed != val) {
|
||||||
* @param[in] val The new value
|
flightStatus.Armed = val;
|
||||||
*/
|
FlightStatusSet(&flightStatus);
|
||||||
static void setArmedIfChanged(uint8_t val) {
|
}
|
||||||
FlightStatusData flightStatus;
|
}
|
||||||
FlightStatusGet(&flightStatus);
|
|
||||||
|
/**
|
||||||
if(flightStatus.Armed != val) {
|
* @brief Process the inputs and determine whether to arm or not
|
||||||
flightStatus.Armed = val;
|
* @param[out] cmd The structure to set the armed in
|
||||||
FlightStatusSet(&flightStatus);
|
* @param[in] settings Settings indicating the necessary position
|
||||||
}
|
*/
|
||||||
}
|
static void processArm(ManualControlCommandData * cmd, ManualControlSettingsData * settings)
|
||||||
|
{
|
||||||
/**
|
|
||||||
* @brief Process the inputs and determine whether to arm or not
|
bool lowThrottle = cmd->Throttle <= 0;
|
||||||
* @param[out] cmd The structure to set the armed in
|
|
||||||
* @param[in] settings Settings indicating the necessary position
|
if (settings->Arming == MANUALCONTROLSETTINGS_ARMING_ALWAYSDISARMED) {
|
||||||
*/
|
// In this configuration we always disarm
|
||||||
static void processArm(ManualControlCommandData * cmd, ManualControlSettingsData * settings)
|
setArmedIfChanged(FLIGHTSTATUS_ARMED_DISARMED);
|
||||||
{
|
} else {
|
||||||
|
// Not really needed since this function not called when disconnected
|
||||||
bool lowThrottle = cmd->Throttle <= 0;
|
if (cmd->Connected == MANUALCONTROLCOMMAND_CONNECTED_FALSE)
|
||||||
|
return;
|
||||||
if (settings->Arming == MANUALCONTROLSETTINGS_ARMING_ALWAYSDISARMED) {
|
|
||||||
// In this configuration we always disarm
|
// The throttle is not low, in case we where arming or disarming, abort
|
||||||
setArmedIfChanged(FLIGHTSTATUS_ARMED_DISARMED);
|
if (!lowThrottle) {
|
||||||
} else {
|
switch(armState) {
|
||||||
// Not really needed since this function not called when disconnected
|
case ARM_STATE_DISARMING_MANUAL:
|
||||||
if (cmd->Connected == MANUALCONTROLCOMMAND_CONNECTED_FALSE)
|
case ARM_STATE_DISARMING_TIMEOUT:
|
||||||
return;
|
armState = ARM_STATE_ARMED;
|
||||||
|
break;
|
||||||
// The throttle is not low, in case we where arming or disarming, abort
|
case ARM_STATE_ARMING_MANUAL:
|
||||||
if (!lowThrottle) {
|
armState = ARM_STATE_DISARMED;
|
||||||
switch(armState) {
|
break;
|
||||||
case ARM_STATE_DISARMING_MANUAL:
|
default:
|
||||||
case ARM_STATE_DISARMING_TIMEOUT:
|
// Nothing needs to be done in the other states
|
||||||
armState = ARM_STATE_ARMED;
|
break;
|
||||||
break;
|
}
|
||||||
case ARM_STATE_ARMING_MANUAL:
|
return;
|
||||||
armState = ARM_STATE_DISARMED;
|
}
|
||||||
break;
|
|
||||||
default:
|
// The rest of these cases throttle is low
|
||||||
// Nothing needs to be done in the other states
|
if (settings->Arming == MANUALCONTROLSETTINGS_ARMING_ALWAYSARMED) {
|
||||||
break;
|
// In this configuration, we go into armed state as soon as the throttle is low, never disarm
|
||||||
}
|
setArmedIfChanged(FLIGHTSTATUS_ARMED_ARMED);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// The rest of these cases throttle is low
|
|
||||||
if (settings->Arming == MANUALCONTROLSETTINGS_ARMING_ALWAYSARMED) {
|
// When the configuration is not "Always armed" and no "Always disarmed",
|
||||||
// In this configuration, we go into armed state as soon as the throttle is low, never disarm
|
// the state will not be changed when the throttle is not low
|
||||||
setArmedIfChanged(FLIGHTSTATUS_ARMED_ARMED);
|
static portTickType armedDisarmStart;
|
||||||
return;
|
float armingInputLevel = 0;
|
||||||
}
|
|
||||||
|
// Calc channel see assumptions7
|
||||||
|
int8_t sign = ((settings->Arming-MANUALCONTROLSETTINGS_ARMING_ROLLLEFT)%2) ? -1 : 1;
|
||||||
// When the configuration is not "Always armed" and no "Always disarmed",
|
switch ( (settings->Arming-MANUALCONTROLSETTINGS_ARMING_ROLLLEFT)/2 ) {
|
||||||
// the state will not be changed when the throttle is not low
|
case ARMING_CHANNEL_ROLL: armingInputLevel = sign * cmd->Roll; break;
|
||||||
static portTickType armedDisarmStart;
|
case ARMING_CHANNEL_PITCH: armingInputLevel = sign * cmd->Pitch; break;
|
||||||
float armingInputLevel = 0;
|
case ARMING_CHANNEL_YAW: armingInputLevel = sign * cmd->Yaw; break;
|
||||||
|
}
|
||||||
// Calc channel see assumptions7
|
|
||||||
int8_t sign = ((settings->Arming-MANUALCONTROLSETTINGS_ARMING_ROLLLEFT)%2) ? -1 : 1;
|
bool manualArm = false;
|
||||||
switch ( (settings->Arming-MANUALCONTROLSETTINGS_ARMING_ROLLLEFT)/2 ) {
|
bool manualDisarm = false;
|
||||||
case ARMING_CHANNEL_ROLL: armingInputLevel = sign * cmd->Roll; break;
|
|
||||||
case ARMING_CHANNEL_PITCH: armingInputLevel = sign * cmd->Pitch; break;
|
if (armingInputLevel <= -ARMED_THRESHOLD)
|
||||||
case ARMING_CHANNEL_YAW: armingInputLevel = sign * cmd->Yaw; break;
|
manualArm = true;
|
||||||
}
|
else if (armingInputLevel >= +ARMED_THRESHOLD)
|
||||||
|
manualDisarm = true;
|
||||||
bool manualArm = false;
|
|
||||||
bool manualDisarm = false;
|
switch(armState) {
|
||||||
|
case ARM_STATE_DISARMED:
|
||||||
if (armingInputLevel <= -ARMED_THRESHOLD)
|
setArmedIfChanged(FLIGHTSTATUS_ARMED_DISARMED);
|
||||||
manualArm = true;
|
|
||||||
else if (armingInputLevel >= +ARMED_THRESHOLD)
|
// only allow arming if it's OK too
|
||||||
manualDisarm = true;
|
if (manualArm && okToArm()) {
|
||||||
|
armedDisarmStart = lastSysTime;
|
||||||
switch(armState) {
|
armState = ARM_STATE_ARMING_MANUAL;
|
||||||
case ARM_STATE_DISARMED:
|
}
|
||||||
setArmedIfChanged(FLIGHTSTATUS_ARMED_DISARMED);
|
break;
|
||||||
|
|
||||||
// only allow arming if it's OK too
|
case ARM_STATE_ARMING_MANUAL:
|
||||||
if (manualArm && okToArm()) {
|
setArmedIfChanged(FLIGHTSTATUS_ARMED_ARMING);
|
||||||
armedDisarmStart = lastSysTime;
|
|
||||||
armState = ARM_STATE_ARMING_MANUAL;
|
if (manualArm && (timeDifferenceMs(armedDisarmStart, lastSysTime) > ARMED_TIME_MS))
|
||||||
}
|
armState = ARM_STATE_ARMED;
|
||||||
break;
|
else if (!manualArm)
|
||||||
|
armState = ARM_STATE_DISARMED;
|
||||||
case ARM_STATE_ARMING_MANUAL:
|
break;
|
||||||
setArmedIfChanged(FLIGHTSTATUS_ARMED_ARMING);
|
|
||||||
|
case ARM_STATE_ARMED:
|
||||||
if (manualArm && (timeDifferenceMs(armedDisarmStart, lastSysTime) > ARMED_TIME_MS))
|
// When we get here, the throttle is low,
|
||||||
armState = ARM_STATE_ARMED;
|
// we go immediately to disarming due to timeout, also when the disarming mechanism is not enabled
|
||||||
else if (!manualArm)
|
armedDisarmStart = lastSysTime;
|
||||||
armState = ARM_STATE_DISARMED;
|
armState = ARM_STATE_DISARMING_TIMEOUT;
|
||||||
break;
|
setArmedIfChanged(FLIGHTSTATUS_ARMED_ARMED);
|
||||||
|
break;
|
||||||
case ARM_STATE_ARMED:
|
|
||||||
// When we get here, the throttle is low,
|
case ARM_STATE_DISARMING_TIMEOUT:
|
||||||
// we go immediately to disarming due to timeout, also when the disarming mechanism is not enabled
|
// We get here when armed while throttle low, even when the arming timeout is not enabled
|
||||||
armedDisarmStart = lastSysTime;
|
if ((settings->ArmedTimeout != 0) && (timeDifferenceMs(armedDisarmStart, lastSysTime) > settings->ArmedTimeout))
|
||||||
armState = ARM_STATE_DISARMING_TIMEOUT;
|
armState = ARM_STATE_DISARMED;
|
||||||
setArmedIfChanged(FLIGHTSTATUS_ARMED_ARMED);
|
|
||||||
break;
|
// Switch to disarming due to manual control when needed
|
||||||
|
if (manualDisarm) {
|
||||||
case ARM_STATE_DISARMING_TIMEOUT:
|
armedDisarmStart = lastSysTime;
|
||||||
// We get here when armed while throttle low, even when the arming timeout is not enabled
|
armState = ARM_STATE_DISARMING_MANUAL;
|
||||||
if ((settings->ArmedTimeout != 0) && (timeDifferenceMs(armedDisarmStart, lastSysTime) > settings->ArmedTimeout))
|
}
|
||||||
armState = ARM_STATE_DISARMED;
|
break;
|
||||||
|
|
||||||
// Switch to disarming due to manual control when needed
|
case ARM_STATE_DISARMING_MANUAL:
|
||||||
if (manualDisarm) {
|
if (manualDisarm &&(timeDifferenceMs(armedDisarmStart, lastSysTime) > ARMED_TIME_MS))
|
||||||
armedDisarmStart = lastSysTime;
|
armState = ARM_STATE_DISARMED;
|
||||||
armState = ARM_STATE_DISARMING_MANUAL;
|
else if (!manualDisarm)
|
||||||
}
|
armState = ARM_STATE_ARMED;
|
||||||
break;
|
break;
|
||||||
|
} // End Switch
|
||||||
case ARM_STATE_DISARMING_MANUAL:
|
}
|
||||||
if (manualDisarm &&(timeDifferenceMs(armedDisarmStart, lastSysTime) > ARMED_TIME_MS))
|
}
|
||||||
armState = ARM_STATE_DISARMED;
|
|
||||||
else if (!manualDisarm)
|
/**
|
||||||
armState = ARM_STATE_ARMED;
|
* @brief Determine which of three positions the flight mode switch is in and set flight mode accordingly
|
||||||
break;
|
* @param[out] cmd Pointer to the command structure to set the flight mode in
|
||||||
} // End Switch
|
* @param[in] settings The settings which indicate which position is which mode
|
||||||
}
|
* @param[in] flightMode the value of the switch position
|
||||||
}
|
*/
|
||||||
|
static void processFlightMode(ManualControlSettingsData * settings, float flightMode)
|
||||||
/**
|
{
|
||||||
* @brief Determine which of three positions the flight mode switch is in and set flight mode accordingly
|
FlightStatusData flightStatus;
|
||||||
* @param[out] cmd Pointer to the command structure to set the flight mode in
|
FlightStatusGet(&flightStatus);
|
||||||
* @param[in] settings The settings which indicate which position is which mode
|
|
||||||
* @param[in] flightMode the value of the switch position
|
uint8_t newMode;
|
||||||
*/
|
// Note here the code is ass
|
||||||
static void processFlightMode(ManualControlSettingsData * settings, float flightMode)
|
if (flightMode < -FLIGHT_MODE_LIMIT)
|
||||||
{
|
newMode = settings->FlightModePosition[0];
|
||||||
FlightStatusData flightStatus;
|
else if (flightMode > FLIGHT_MODE_LIMIT)
|
||||||
FlightStatusGet(&flightStatus);
|
newMode = settings->FlightModePosition[2];
|
||||||
|
else
|
||||||
uint8_t newMode;
|
newMode = settings->FlightModePosition[1];
|
||||||
// Note here the code is ass
|
|
||||||
if (flightMode < -FLIGHT_MODE_LIMIT)
|
if(flightStatus.FlightMode != newMode) {
|
||||||
newMode = settings->FlightModePosition[0];
|
flightStatus.FlightMode = newMode;
|
||||||
else if (flightMode > FLIGHT_MODE_LIMIT)
|
FlightStatusSet(&flightStatus);
|
||||||
newMode = settings->FlightModePosition[2];
|
}
|
||||||
else
|
|
||||||
newMode = settings->FlightModePosition[1];
|
}
|
||||||
|
|
||||||
if(flightStatus.FlightMode != newMode) {
|
/**
|
||||||
flightStatus.FlightMode = newMode;
|
* @brief Determine if the manual input value is within acceptable limits
|
||||||
FlightStatusSet(&flightStatus);
|
* @returns return TRUE if so, otherwise return FALSE
|
||||||
}
|
*/
|
||||||
|
bool validInputRange(int16_t min, int16_t max, uint16_t value)
|
||||||
}
|
{
|
||||||
|
if (min > max)
|
||||||
/**
|
{
|
||||||
* @brief Determine if the manual input value is within acceptable limits
|
int16_t tmp = min;
|
||||||
* @returns return TRUE if so, otherwise return FALSE
|
min = max;
|
||||||
*/
|
max = tmp;
|
||||||
bool validInputRange(int16_t min, int16_t max, uint16_t value)
|
}
|
||||||
{
|
return (value >= min - CONNECTION_OFFSET && value <= max + CONNECTION_OFFSET);
|
||||||
if (min > max)
|
}
|
||||||
{
|
|
||||||
int16_t tmp = min;
|
/**
|
||||||
min = max;
|
* @}
|
||||||
max = tmp;
|
* @}
|
||||||
}
|
*/
|
||||||
return (value >= min - CONNECTION_OFFSET && value <= max + CONNECTION_OFFSET);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @}
|
|
||||||
* @}
|
|
||||||
*/
|
|
||||||
|
@ -196,6 +196,7 @@ SRC += $(PIOSCOMMON)/pios_hcsr04.c
|
|||||||
SRC += $(PIOSCOMMON)/pios_i2c_esc.c
|
SRC += $(PIOSCOMMON)/pios_i2c_esc.c
|
||||||
SRC += $(PIOSCOMMON)/pios_iap.c
|
SRC += $(PIOSCOMMON)/pios_iap.c
|
||||||
SRC += $(PIOSCOMMON)/pios_bl_helper.c
|
SRC += $(PIOSCOMMON)/pios_bl_helper.c
|
||||||
|
SRC += $(PIOSCOMMON)/pios_rcvr.c
|
||||||
SRC += $(PIOSCOMMON)/printf-stdarg.c
|
SRC += $(PIOSCOMMON)/printf-stdarg.c
|
||||||
SRC += $(FLIGHTLIB)/ahrs_spi_comm.c
|
SRC += $(FLIGHTLIB)/ahrs_spi_comm.c
|
||||||
SRC += $(FLIGHTLIB)/ahrs_comm_objects.c
|
SRC += $(FLIGHTLIB)/ahrs_comm_objects.c
|
||||||
|
@ -42,6 +42,8 @@
|
|||||||
#define PIOS_INCLUDE_IRQ
|
#define PIOS_INCLUDE_IRQ
|
||||||
#define PIOS_INCLUDE_LED
|
#define PIOS_INCLUDE_LED
|
||||||
|
|
||||||
|
#define PIOS_INCLUDE_RCVR
|
||||||
|
|
||||||
#if defined(USE_SPEKTRUM)
|
#if defined(USE_SPEKTRUM)
|
||||||
#define PIOS_INCLUDE_SPEKTRUM
|
#define PIOS_INCLUDE_SPEKTRUM
|
||||||
#elif defined(USE_SBUS)
|
#elif defined(USE_SBUS)
|
||||||
|
@ -497,13 +497,13 @@ const struct pios_usart_cfg pios_usart_spektrum_cfg = {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#include <pios_spektrum_priv.h>
|
||||||
static uint32_t pios_usart_spektrum_id;
|
static uint32_t pios_usart_spektrum_id;
|
||||||
void PIOS_USART_spektrum_irq_handler(void)
|
void PIOS_USART_spektrum_irq_handler(void)
|
||||||
{
|
{
|
||||||
SPEKTRUM_IRQHandler(pios_usart_spektrum_id);
|
PIOS_SPEKTRUM_irq_handler(pios_usart_spektrum_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
#include <pios_spektrum_priv.h>
|
|
||||||
void RTC_IRQHandler();
|
void RTC_IRQHandler();
|
||||||
void RTC_IRQHandler() __attribute__ ((alias ("PIOS_SUPV_irq_handler")));
|
void RTC_IRQHandler() __attribute__ ((alias ("PIOS_SUPV_irq_handler")));
|
||||||
const struct pios_spektrum_cfg pios_spektrum_cfg = {
|
const struct pios_spektrum_cfg pios_spektrum_cfg = {
|
||||||
@ -525,11 +525,11 @@ const struct pios_spektrum_cfg pios_spektrum_cfg = {
|
|||||||
.pin = GPIO_Pin_10,
|
.pin = GPIO_Pin_10,
|
||||||
};
|
};
|
||||||
|
|
||||||
void PIOS_SUPV_irq_handler() {
|
void PIOS_SUPV_irq_handler(void) {
|
||||||
if (RTC_GetITStatus(RTC_IT_SEC))
|
if (RTC_GetITStatus(RTC_IT_SEC))
|
||||||
{
|
{
|
||||||
/* Call the right handler */
|
/* Call the right handler */
|
||||||
PIOS_SPEKTRUM_irq_handler(pios_usart_spektrum_id);
|
PIOS_SPEKTRUMSV_irq_handler(pios_usart_spektrum_id);
|
||||||
|
|
||||||
/* Wait until last write operation on RTC registers has finished */
|
/* Wait until last write operation on RTC registers has finished */
|
||||||
RTC_WaitForLastTask();
|
RTC_WaitForLastTask();
|
||||||
@ -802,7 +802,7 @@ const struct pios_ppmsv_cfg pios_ppmsv_cfg = {
|
|||||||
.ccr = TIM_IT_Update,
|
.ccr = TIM_IT_Update,
|
||||||
};
|
};
|
||||||
|
|
||||||
void PIOS_TIM6_irq_handler()
|
void PIOS_TIM6_irq_handler(void)
|
||||||
{
|
{
|
||||||
PIOS_PPMSV_irq_handler();
|
PIOS_PPMSV_irq_handler();
|
||||||
}
|
}
|
||||||
@ -844,7 +844,7 @@ const struct pios_ppm_cfg pios_ppm_cfg = {
|
|||||||
.ccr = TIM_IT_CC2,
|
.ccr = TIM_IT_CC2,
|
||||||
};
|
};
|
||||||
|
|
||||||
void PIOS_TIM1_CC_irq_handler()
|
void PIOS_TIM1_CC_irq_handler(void)
|
||||||
{
|
{
|
||||||
PIOS_PPM_irq_handler();
|
PIOS_PPM_irq_handler();
|
||||||
}
|
}
|
||||||
@ -1013,6 +1013,13 @@ static const struct stm32_gpio pios_debug_pins[] = {
|
|||||||
|
|
||||||
#endif /* PIOS_ENABLE_DEBUG_PINS */
|
#endif /* PIOS_ENABLE_DEBUG_PINS */
|
||||||
|
|
||||||
|
#if defined(PIOS_INCLUDE_RCVR)
|
||||||
|
#include "pios_rcvr_priv.h"
|
||||||
|
|
||||||
|
uint32_t pios_rcvr_channel_to_id_map[PIOS_RCVR_MAX_DEVS];
|
||||||
|
uint32_t pios_rcvr_max_channel;
|
||||||
|
#endif /* PIOS_INCLUDE_RCVR */
|
||||||
|
|
||||||
extern const struct pios_com_driver pios_usb_com_driver;
|
extern const struct pios_com_driver pios_usb_com_driver;
|
||||||
|
|
||||||
uint32_t pios_com_telem_rf_id;
|
uint32_t pios_com_telem_rf_id;
|
||||||
@ -1050,18 +1057,6 @@ void PIOS_Board_Init(void) {
|
|||||||
PIOS_SDCARD_MountFS(0);
|
PIOS_SDCARD_MountFS(0);
|
||||||
#endif /* PIOS_INCLUDE_SPI */
|
#endif /* PIOS_INCLUDE_SPI */
|
||||||
|
|
||||||
#if defined(PIOS_INCLUDE_SPEKTRUM)
|
|
||||||
/* SPEKTRUM init must come before comms */
|
|
||||||
PIOS_RTC_Init(); // Spektrum uses RTC to check for frame failures
|
|
||||||
PIOS_SPEKTRUM_Init();
|
|
||||||
|
|
||||||
if (PIOS_USART_Init(&pios_usart_spektrum_id, &pios_usart_spektrum_cfg)) {
|
|
||||||
PIOS_DEBUG_Assert(0);
|
|
||||||
}
|
|
||||||
if (PIOS_COM_Init(&pios_com_spektrum_id, &pios_usart_com_driver, pios_usart_spektrum_id)) {
|
|
||||||
PIOS_DEBUG_Assert(0);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
/* Initialize UAVObject libraries */
|
/* Initialize UAVObject libraries */
|
||||||
EventDispatcherInitialize();
|
EventDispatcherInitialize();
|
||||||
UAVObjInitialize();
|
UAVObjInitialize();
|
||||||
@ -1105,11 +1100,59 @@ void PIOS_Board_Init(void) {
|
|||||||
PIOS_ADC_Init();
|
PIOS_ADC_Init();
|
||||||
PIOS_GPIO_Init();
|
PIOS_GPIO_Init();
|
||||||
|
|
||||||
|
#if defined(PIOS_INCLUDE_SPEKTRUM)
|
||||||
|
#if (PIOS_SPEKTRUM_NUM_INPUTS > PIOS_RCVR_MAX_DEVS)
|
||||||
|
#error More receiver inputs than available devices
|
||||||
|
#endif
|
||||||
|
/* SPEKTRUM init must come before comms */
|
||||||
|
PIOS_SPEKTRUM_Init();
|
||||||
|
|
||||||
|
if (PIOS_USART_Init(&pios_usart_spektrum_id, &pios_usart_spektrum_cfg)) {
|
||||||
|
PIOS_DEBUG_Assert(0);
|
||||||
|
}
|
||||||
|
if (PIOS_COM_Init(&pios_com_spektrum_id, &pios_usart_com_driver, pios_usart_spektrum_id)) {
|
||||||
|
PIOS_DEBUG_Assert(0);
|
||||||
|
}
|
||||||
|
for (uint8_t i = 0; i < PIOS_SPEKTRUM_NUM_INPUTS; i++) {
|
||||||
|
if (!PIOS_RCVR_Init(&pios_rcvr_channel_to_id_map[pios_rcvr_max_channel],
|
||||||
|
&pios_spektrum_rcvr_driver,
|
||||||
|
i)) {
|
||||||
|
pios_rcvr_max_channel++;
|
||||||
|
} else {
|
||||||
|
PIOS_DEBUG_Assert(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#if defined(PIOS_INCLUDE_PWM)
|
#if defined(PIOS_INCLUDE_PWM)
|
||||||
|
#if (PIOS_PWM_NUM_INPUTS > PIOS_RCVR_MAX_DEVS)
|
||||||
|
#error More receiver inputs than available devices
|
||||||
|
#endif
|
||||||
PIOS_PWM_Init();
|
PIOS_PWM_Init();
|
||||||
|
for (uint8_t i = 0; i < PIOS_PWM_NUM_INPUTS; i++) {
|
||||||
|
if (!PIOS_RCVR_Init(&pios_rcvr_channel_to_id_map[pios_rcvr_max_channel],
|
||||||
|
&pios_pwm_rcvr_driver,
|
||||||
|
i)) {
|
||||||
|
pios_rcvr_max_channel++;
|
||||||
|
} else {
|
||||||
|
PIOS_DEBUG_Assert(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
#if defined(PIOS_INCLUDE_PPM)
|
#if defined(PIOS_INCLUDE_PPM)
|
||||||
|
#if (PIOS_PPM_NUM_INPUTS > PIOS_RCVR_MAX_DEVS)
|
||||||
|
#error More receiver inputs than available devices
|
||||||
|
#endif
|
||||||
PIOS_PPM_Init();
|
PIOS_PPM_Init();
|
||||||
|
for (uint8_t i = 0; i < PIOS_PPM_NUM_INPUTS; i++) {
|
||||||
|
if (!PIOS_RCVR_Init(&pios_rcvr_channel_to_id_map[pios_rcvr_max_channel],
|
||||||
|
&pios_ppm_rcvr_driver,
|
||||||
|
i)) {
|
||||||
|
pios_rcvr_max_channel++;
|
||||||
|
} else {
|
||||||
|
PIOS_DEBUG_Assert(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
#if defined(PIOS_INCLUDE_USB_HID)
|
#if defined(PIOS_INCLUDE_USB_HID)
|
||||||
PIOS_USB_HID_Init(0);
|
PIOS_USB_HID_Init(0);
|
||||||
|
@ -225,10 +225,27 @@ extern uint32_t pios_com_sbus_id;
|
|||||||
#define PIOS_ADC_RATE (72.0e6 / 1.0 / 8.0 / 252.0 / (PIOS_ADC_NUM_CHANNELS >> PIOS_ADC_USE_ADC2))
|
#define PIOS_ADC_RATE (72.0e6 / 1.0 / 8.0 / 252.0 / (PIOS_ADC_NUM_CHANNELS >> PIOS_ADC_USE_ADC2))
|
||||||
#define PIOS_ADC_MAX_OVERSAMPLING 36
|
#define PIOS_ADC_MAX_OVERSAMPLING 36
|
||||||
|
|
||||||
|
//------------------------
|
||||||
|
// PIOS_RCVR
|
||||||
|
// See also pios_board.c
|
||||||
|
//------------------------
|
||||||
|
#define PIOS_RCVR_MAX_DEVS 12
|
||||||
|
|
||||||
//-------------------------
|
//-------------------------
|
||||||
// Receiver PWM inputs
|
// Receiver PPM input
|
||||||
//-------------------------
|
//-------------------------
|
||||||
#define PIOS_PWM_MAX_INPUTS 6
|
#define PIOS_PPM_NUM_INPUTS 6 //Could be more if needed
|
||||||
|
#define PIOS_PPM_SUPV_ENABLED 1
|
||||||
|
|
||||||
|
//-------------------------
|
||||||
|
// Receiver PWM input
|
||||||
|
//-------------------------
|
||||||
|
#define PIOS_PWM_NUM_INPUTS 6
|
||||||
|
|
||||||
|
//-------------------------
|
||||||
|
// Receiver SPEKTRUM input
|
||||||
|
//-------------------------
|
||||||
|
#define PIOS_SPEKTRUM_NUM_INPUTS 12
|
||||||
|
|
||||||
//-------------------------
|
//-------------------------
|
||||||
// Servo outputs
|
// Servo outputs
|
||||||
|
@ -199,37 +199,33 @@ extern uint32_t pios_com_sbus_id;
|
|||||||
#define PIOS_IRQ_PRIO_HIGH 5 // for SPI, ADC, I2C etc...
|
#define PIOS_IRQ_PRIO_HIGH 5 // for SPI, ADC, I2C etc...
|
||||||
#define PIOS_IRQ_PRIO_HIGHEST 4 // for USART etc...
|
#define PIOS_IRQ_PRIO_HIGHEST 4 // for USART etc...
|
||||||
|
|
||||||
//-------------------------
|
//------------------------
|
||||||
// Receiver PWM inputs
|
// PIOS_RCVR
|
||||||
//-------------------------
|
// See also pios_board.c
|
||||||
/*#define PIOS_PWM_SUPV_ENABLED 1
|
//------------------------
|
||||||
#define PIOS_PWM_SUPV_TIMER TIM6
|
#define PIOS_RCVR_MAX_DEVS 12
|
||||||
#define PIOS_PWM_SUPV_TIMER_RCC_FUNC RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM6, ENABLE)
|
|
||||||
#define PIOS_PWM_SUPV_HZ 25
|
|
||||||
#define PIOS_PWM_SUPV_IRQ_CHANNEL TIM6_IRQn
|
|
||||||
#define PIOS_PWM_SUPV_IRQ_FUNC void TIM6_IRQHandler(void)*/
|
|
||||||
|
|
||||||
//-------------------------
|
//-------------------------
|
||||||
// Receiver PPM input
|
// Receiver PPM input
|
||||||
//-------------------------
|
//-------------------------
|
||||||
#define PIOS_PPM_NUM_INPUTS 8 //Could be more if needed
|
#define PIOS_PPM_NUM_INPUTS 8 //Could be more if needed
|
||||||
#define PIOS_PPM_SUPV_ENABLED 1
|
#define PIOS_PPM_SUPV_ENABLED 1
|
||||||
|
|
||||||
//-------------------------
|
//-------------------------
|
||||||
// SPEKTRUM input
|
// Receiver PWM input
|
||||||
//-------------------------
|
//-------------------------
|
||||||
//#define PIOS_SPEKTRUM_SUPV_ENABLED 1
|
#define PIOS_PWM_NUM_INPUTS 8
|
||||||
//#define PIOS_SPEKTRUM_SUPV_TIMER TIM6
|
|
||||||
//#define PIOS_SPEKTRUM_SUPV_TIMER_RCC_FUNC RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM6, ENABLE)
|
//-------------------------
|
||||||
//#define PIOS_SPEKTRUM_SUPV_HZ 60 // 1/22ms
|
// Receiver SPEKTRUM input
|
||||||
//#define PIOS_SPEKTRUM_SUPV_IRQ_CHANNEL TIM6_IRQn
|
//-------------------------
|
||||||
//#define PIOS_SPEKTRUM_SUPV_IRQ_FUNC void TIM6_IRQHandler(void)
|
#define PIOS_SPEKTRUM_NUM_INPUTS 12
|
||||||
|
|
||||||
//-------------------------
|
//-------------------------
|
||||||
// Servo outputs
|
// Servo outputs
|
||||||
//-------------------------
|
//-------------------------
|
||||||
#define PIOS_SERVO_UPDATE_HZ 50
|
#define PIOS_SERVO_UPDATE_HZ 50
|
||||||
#define PIOS_SERVOS_INITIAL_POSITION 0 /* dont want to start motors, have no pulse till settings loaded */
|
#define PIOS_SERVOS_INITIAL_POSITION 0 /* dont want to start motors, have no pulse till settings loaded */
|
||||||
#define PIOS_PWM_MAX_INPUTS 8
|
|
||||||
|
|
||||||
//-------------------------
|
//-------------------------
|
||||||
// ADC
|
// ADC
|
||||||
|
@ -34,8 +34,14 @@
|
|||||||
|
|
||||||
#if defined(PIOS_INCLUDE_PPM)
|
#if defined(PIOS_INCLUDE_PPM)
|
||||||
|
|
||||||
/* Local Variables */
|
/* Provide a RCVR driver */
|
||||||
|
static int32_t PIOS_PPM_Get(uint32_t chan_id);
|
||||||
|
|
||||||
|
const struct pios_rcvr_driver pios_ppm_rcvr_driver = {
|
||||||
|
.read = PIOS_PPM_Get,
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Local Variables */
|
||||||
static TIM_ICInitTypeDef TIM_ICInitStructure;
|
static TIM_ICInitTypeDef TIM_ICInitStructure;
|
||||||
static uint8_t PulseIndex;
|
static uint8_t PulseIndex;
|
||||||
static uint32_t PreviousValue;
|
static uint32_t PreviousValue;
|
||||||
@ -208,13 +214,13 @@ void PIOS_PPM_Init(void)
|
|||||||
* \output -1 Channel not available
|
* \output -1 Channel not available
|
||||||
* \output >0 Channel value
|
* \output >0 Channel value
|
||||||
*/
|
*/
|
||||||
int32_t PIOS_PPM_Get(int8_t Channel)
|
static int32_t PIOS_PPM_Get(uint32_t chan_id)
|
||||||
{
|
{
|
||||||
/* Return error if channel not available */
|
/* Return error if channel not available */
|
||||||
if (Channel >= PIOS_PPM_NUM_INPUTS) {
|
if (chan_id >= PIOS_PPM_NUM_INPUTS) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
return CaptureValue[Channel];
|
return CaptureValue[chan_id];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -34,15 +34,20 @@
|
|||||||
|
|
||||||
#if defined(PIOS_INCLUDE_PWM)
|
#if defined(PIOS_INCLUDE_PWM)
|
||||||
|
|
||||||
/* Local Variables */
|
/* Provide a RCVR driver */
|
||||||
static uint8_t CaptureState[PIOS_PWM_MAX_INPUTS];
|
static int32_t PIOS_PWM_Get(uint32_t chan_id);
|
||||||
static uint16_t RiseValue[PIOS_PWM_MAX_INPUTS];
|
|
||||||
static uint16_t FallValue[PIOS_PWM_MAX_INPUTS];
|
|
||||||
static uint32_t CaptureValue[PIOS_PWM_MAX_INPUTS];
|
|
||||||
|
|
||||||
//static uint8_t SupervisorState = 0;
|
const struct pios_rcvr_driver pios_pwm_rcvr_driver = {
|
||||||
static uint32_t CapCounter[PIOS_PWM_MAX_INPUTS];
|
.read = PIOS_PWM_Get,
|
||||||
//static uint32_t CapCounterPrev[MAX_CHANNELS];
|
};
|
||||||
|
|
||||||
|
/* Local Variables */
|
||||||
|
static uint8_t CaptureState[PIOS_PWM_NUM_INPUTS];
|
||||||
|
static uint16_t RiseValue[PIOS_PWM_NUM_INPUTS];
|
||||||
|
static uint16_t FallValue[PIOS_PWM_NUM_INPUTS];
|
||||||
|
static uint32_t CaptureValue[PIOS_PWM_NUM_INPUTS];
|
||||||
|
|
||||||
|
static uint32_t CapCounter[PIOS_PWM_NUM_INPUTS];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initialises all the pins
|
* Initialises all the pins
|
||||||
@ -127,52 +132,6 @@ void PIOS_PWM_Init(void)
|
|||||||
/* Warning, I don't think this will work for multiple remaps at once */
|
/* Warning, I don't think this will work for multiple remaps at once */
|
||||||
GPIO_PinRemapConfig(pios_pwm_cfg.remap, ENABLE);
|
GPIO_PinRemapConfig(pios_pwm_cfg.remap, ENABLE);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
|
||||||
/* Supervisor Setup */
|
|
||||||
#if (PIOS_PWM_SUPV_ENABLED)
|
|
||||||
/* Flush counter variables */
|
|
||||||
for (i = 0; i < PIOS_PWM_NUM_INPUTS; i++) {
|
|
||||||
CapCounter[i] = 0;
|
|
||||||
}
|
|
||||||
for (i = 0; i < PIOS_PWM_NUM_INPUTS; i++) {
|
|
||||||
CapCounterPrev[i] = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Enable timer clock */
|
|
||||||
PIOS_PWM_SUPV_TIMER_RCC_FUNC;
|
|
||||||
|
|
||||||
/* Configure interrupts */
|
|
||||||
NVIC_InitStructure.NVIC_IRQChannel = PIOS_PWM_SUPV_IRQ_CHANNEL;
|
|
||||||
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = PIOS_IRQ_PRIO_MID;
|
|
||||||
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
|
|
||||||
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
|
|
||||||
NVIC_Init(&NVIC_InitStructure);
|
|
||||||
|
|
||||||
/* Time base configuration */
|
|
||||||
TIM_TimeBaseStructInit(&TIM_TimeBaseStructure);
|
|
||||||
TIM_TimeBaseStructure.TIM_Period = ((1000000 / PIOS_PWM_SUPV_HZ) - 1);
|
|
||||||
TIM_TimeBaseStructure.TIM_Prescaler = (PIOS_MASTER_CLOCK / 1000000) - 1; /* For 1 uS accuracy */
|
|
||||||
TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
|
|
||||||
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
|
|
||||||
TIM_TimeBaseInit(PIOS_PWM_SUPV_TIMER, &TIM_TimeBaseStructure);
|
|
||||||
|
|
||||||
/* Enable the CC2 Interrupt Request */
|
|
||||||
TIM_ITConfig(PIOS_PWM_SUPV_TIMER, TIM_IT_Update, ENABLE);
|
|
||||||
|
|
||||||
/* Clear update pending flag */
|
|
||||||
TIM_ClearFlag(TIM2, TIM_FLAG_Update);
|
|
||||||
|
|
||||||
/* Enable counter */
|
|
||||||
TIM_Cmd(PIOS_PWM_SUPV_TIMER, ENABLE);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Setup local variable which stays in this scope */
|
|
||||||
/* Doing this here and using a local variable saves doing it in the ISR */
|
|
||||||
TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI;
|
|
||||||
TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;
|
|
||||||
TIM_ICInitStructure.TIM_ICFilter = 0x0;
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -181,13 +140,13 @@ void PIOS_PWM_Init(void)
|
|||||||
* \output -1 Channel not available
|
* \output -1 Channel not available
|
||||||
* \output >0 Channel value
|
* \output >0 Channel value
|
||||||
*/
|
*/
|
||||||
int32_t PIOS_PWM_Get(int8_t Channel)
|
static int32_t PIOS_PWM_Get(uint32_t chan_id)
|
||||||
{
|
{
|
||||||
/* Return error if channel not available */
|
/* Return error if channel not available */
|
||||||
if (Channel >= pios_pwm_cfg.num_channels) {
|
if (chan_id >= pios_pwm_cfg.num_channels) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
return CaptureValue[Channel];
|
return CaptureValue[chan_id];
|
||||||
}
|
}
|
||||||
|
|
||||||
void PIOS_PWM_irq_handler(TIM_TypeDef * timer)
|
void PIOS_PWM_irq_handler(TIM_TypeDef * timer)
|
||||||
@ -254,84 +213,6 @@ void PIOS_PWM_irq_handler(TIM_TypeDef * timer)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
|
||||||
/**
|
|
||||||
* Handle TIM5 global interrupt request
|
|
||||||
*/
|
|
||||||
void TIM5_IRQHandler(void)
|
|
||||||
{
|
|
||||||
/* Do this as it's more efficient */
|
|
||||||
if (TIM_GetITStatus(PIOS_PWM_TIM_PORT[2], PIOS_PWM_TIM_CCR[2]) == SET) {
|
|
||||||
if (CaptureState[2] == 0) {
|
|
||||||
RiseValue[2] = TIM_GetCapture1(PIOS_PWM_TIM_PORT[2]);
|
|
||||||
} else {
|
|
||||||
FallValue[2] = TIM_GetCapture1(PIOS_PWM_TIM_PORT[2]);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Clear TIM3 Capture compare interrupt pending bit */
|
|
||||||
TIM_ClearITPendingBit(PIOS_PWM_TIM_PORT[2], PIOS_PWM_TIM_CCR[2]);
|
|
||||||
|
|
||||||
/* Simple rise or fall state machine */
|
|
||||||
if (CaptureState[2] == 0) {
|
|
||||||
/* Switch states */
|
|
||||||
CaptureState[2] = 1;
|
|
||||||
|
|
||||||
/* Switch polarity of input capture */
|
|
||||||
TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Falling;
|
|
||||||
TIM_ICInitStructure.TIM_Channel = PIOS_PWM_TIM_CHANNEL[2];
|
|
||||||
TIM_ICInit(PIOS_PWM_TIM_PORT[2], &TIM_ICInitStructure);
|
|
||||||
|
|
||||||
} else {
|
|
||||||
/* Capture computation */
|
|
||||||
if (FallValue[2] > RiseValue[2]) {
|
|
||||||
CaptureValue[2] = (FallValue[2] - RiseValue[2]);
|
|
||||||
} else {
|
|
||||||
CaptureValue[2] = ((0xFFFF - RiseValue[2]) + FallValue[2]);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Switch states */
|
|
||||||
CaptureState[2] = 0;
|
|
||||||
|
|
||||||
/* Increase supervisor counter */
|
|
||||||
CapCounter[2]++;
|
|
||||||
|
|
||||||
/* Switch polarity of input capture */
|
|
||||||
TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising;
|
|
||||||
TIM_ICInitStructure.TIM_Channel = PIOS_PWM_TIM_CHANNEL[2];
|
|
||||||
TIM_ICInit(PIOS_PWM_TIM_PORT[2], &TIM_ICInitStructure);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This function handles TIM3 global interrupt request.
|
|
||||||
*/
|
|
||||||
PIOS_PWM_SUPV_IRQ_FUNC {
|
|
||||||
/* Clear timer interrupt pending bit */
|
|
||||||
TIM_ClearITPendingBit(PIOS_PWM_SUPV_TIMER, TIM_IT_Update);
|
|
||||||
|
|
||||||
/* Simple state machine */
|
|
||||||
if (SupervisorState == 0) {
|
|
||||||
/* Save this states values */
|
|
||||||
for (int32_t i = 0; i < PIOS_PWM_NUM_INPUTS; i++) {
|
|
||||||
CapCounterPrev[i] = CapCounter[i];
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Move to next state */
|
|
||||||
SupervisorState = 1;
|
|
||||||
} else {
|
|
||||||
/* See what channels have been updated */
|
|
||||||
for (int32_t i = 0; i < PIOS_PWM_NUM_INPUTS; i++) {
|
|
||||||
if (CapCounter[i] == CapCounterPrev[i]) {
|
|
||||||
CaptureValue[i] = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Move to next state */
|
|
||||||
SupervisorState = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -36,6 +36,13 @@
|
|||||||
|
|
||||||
/* Global Variables */
|
/* Global Variables */
|
||||||
|
|
||||||
|
/* Provide a RCVR driver */
|
||||||
|
static int32_t PIOS_SBUS_Get(uint32_t chan_id);
|
||||||
|
|
||||||
|
const struct pios_rcvr_driver pios_sbus_rcvr_driver = {
|
||||||
|
.read = PIOS_SBUS_Get,
|
||||||
|
};
|
||||||
|
|
||||||
/* Local Variables */
|
/* Local Variables */
|
||||||
static uint16_t channel_data[SBUS_NUMBER_OF_CHANNELS];
|
static uint16_t channel_data[SBUS_NUMBER_OF_CHANNELS];
|
||||||
static uint8_t received_data[SBUS_FRAME_LENGTH - 2];
|
static uint8_t received_data[SBUS_FRAME_LENGTH - 2];
|
||||||
@ -154,19 +161,19 @@ void PIOS_SBUS_Init(void)
|
|||||||
* \output -1 channel not available
|
* \output -1 channel not available
|
||||||
* \output >0 channel value
|
* \output >0 channel value
|
||||||
*/
|
*/
|
||||||
int16_t PIOS_SBUS_Get(int8_t channel)
|
static int32_t PIOS_SBUS_Get(uint32_t chan_id)
|
||||||
{
|
{
|
||||||
/* return error if channel is not available */
|
/* return error if channel is not available */
|
||||||
if (channel >= SBUS_NUMBER_OF_CHANNELS) {
|
if (chan_id >= SBUS_NUMBER_OF_CHANNELS) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
return channel_data[channel];
|
return channel_data[chan_id];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Interrupt handler for USART
|
* Interrupt handler for USART
|
||||||
*/
|
*/
|
||||||
void SBUS_IRQHandler(uint32_t usart_id)
|
void PIOS_SBUS_irq_handler(uint32_t usart_id)
|
||||||
{
|
{
|
||||||
/* by always reading DR after SR make sure to clear any error interrupts */
|
/* by always reading DR after SR make sure to clear any error interrupts */
|
||||||
volatile uint16_t sr = pios_sbus_cfg.pios_usart_sbus_cfg->regs->SR;
|
volatile uint16_t sr = pios_sbus_cfg.pios_usart_sbus_cfg->regs->SR;
|
||||||
@ -198,7 +205,7 @@ void SBUS_IRQHandler(uint32_t usart_id)
|
|||||||
* data reception. If no new data received in 100ms, we must call the
|
* data reception. If no new data received in 100ms, we must call the
|
||||||
* failsafe function which clears all channels.
|
* failsafe function which clears all channels.
|
||||||
*/
|
*/
|
||||||
void PIOS_SBUS_irq_handler()
|
void PIOS_SBUSSV_irq_handler()
|
||||||
{
|
{
|
||||||
/* waiting for new frame if no bytes were received in 3.2ms */
|
/* waiting for new frame if no bytes were received in 3.2ms */
|
||||||
if (++receive_timer > 2) {
|
if (++receive_timer > 2) {
|
||||||
|
@ -51,8 +51,15 @@
|
|||||||
|
|
||||||
/* Global Variables */
|
/* Global Variables */
|
||||||
|
|
||||||
|
/* Provide a RCVR driver */
|
||||||
|
static int32_t PIOS_SPEKTRUM_Get(uint32_t chan_id);
|
||||||
|
|
||||||
|
const struct pios_rcvr_driver pios_spektrum_rcvr_driver = {
|
||||||
|
.read = PIOS_SPEKTRUM_Get,
|
||||||
|
};
|
||||||
|
|
||||||
/* Local Variables */
|
/* Local Variables */
|
||||||
static uint16_t CaptureValue[12],CaptureValueTemp[12];
|
static uint16_t CaptureValue[PIOS_SPEKTRUM_NUM_INPUTS],CaptureValueTemp[PIOS_SPEKTRUM_NUM_INPUTS];
|
||||||
static uint8_t prev_byte = 0xFF, sync = 0, bytecount = 0, datalength=0, frame_error=0, byte_array[20] = { 0 };
|
static uint8_t prev_byte = 0xFF, sync = 0, bytecount = 0, datalength=0, frame_error=0, byte_array[20] = { 0 };
|
||||||
uint8_t sync_of = 0;
|
uint8_t sync_of = 0;
|
||||||
uint16_t supv_timer=0;
|
uint16_t supv_timer=0;
|
||||||
@ -84,13 +91,13 @@ void PIOS_SPEKTRUM_Init(void)
|
|||||||
* \output -1 Channel not available
|
* \output -1 Channel not available
|
||||||
* \output >0 Channel value
|
* \output >0 Channel value
|
||||||
*/
|
*/
|
||||||
int16_t PIOS_SPEKTRUM_Get(int8_t Channel)
|
static int32_t PIOS_SPEKTRUM_Get(uint32_t chan_id)
|
||||||
{
|
{
|
||||||
/* Return error if channel not available */
|
/* Return error if channel not available */
|
||||||
if (Channel >= 12) {
|
if (chan_id >= PIOS_SPEKTRUM_NUM_INPUTS) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
return CaptureValue[Channel];
|
return CaptureValue[chan_id];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -201,7 +208,7 @@ int32_t PIOS_SPEKTRUM_Decode(uint8_t b)
|
|||||||
{
|
{
|
||||||
frame_error=1;
|
frame_error=1;
|
||||||
}
|
}
|
||||||
if (channeln < 12 && !frame_error)
|
if (channeln < PIOS_SPEKTRUM_NUM_INPUTS && !frame_error)
|
||||||
CaptureValueTemp[channeln] = data;
|
CaptureValueTemp[channeln] = data;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -212,7 +219,7 @@ int32_t PIOS_SPEKTRUM_Decode(uint8_t b)
|
|||||||
sync_of = 0;
|
sync_of = 0;
|
||||||
if (!frame_error)
|
if (!frame_error)
|
||||||
{
|
{
|
||||||
for(int i=0;i<12;i++)
|
for(int i=0;i<PIOS_SPEKTRUM_NUM_INPUTS;i++)
|
||||||
{
|
{
|
||||||
CaptureValue[i] = CaptureValueTemp[i];
|
CaptureValue[i] = CaptureValueTemp[i];
|
||||||
}
|
}
|
||||||
@ -224,7 +231,7 @@ int32_t PIOS_SPEKTRUM_Decode(uint8_t b)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Interrupt handler for USART */
|
/* Interrupt handler for USART */
|
||||||
void SPEKTRUM_IRQHandler(uint32_t usart_id) {
|
void PIOS_SPEKTRUM_irq_handler(uint32_t usart_id) {
|
||||||
/* by always reading DR after SR make sure to clear any error interrupts */
|
/* by always reading DR after SR make sure to clear any error interrupts */
|
||||||
volatile uint16_t sr = pios_spektrum_cfg.pios_usart_spektrum_cfg->regs->SR;
|
volatile uint16_t sr = pios_spektrum_cfg.pios_usart_spektrum_cfg->regs->SR;
|
||||||
volatile uint8_t b = pios_spektrum_cfg.pios_usart_spektrum_cfg->regs->DR;
|
volatile uint8_t b = pios_spektrum_cfg.pios_usart_spektrum_cfg->regs->DR;
|
||||||
@ -248,7 +255,7 @@ void SPEKTRUM_IRQHandler(uint32_t usart_id) {
|
|||||||
*@brief This function is called between frames and when a spektrum word hasnt been decoded for too long
|
*@brief This function is called between frames and when a spektrum word hasnt been decoded for too long
|
||||||
*@brief clears the channel values
|
*@brief clears the channel values
|
||||||
*/
|
*/
|
||||||
void PIOS_SPEKTRUM_irq_handler() {
|
void PIOS_SPEKTRUMSV_irq_handler() {
|
||||||
/* 125hz */
|
/* 125hz */
|
||||||
supv_timer++;
|
supv_timer++;
|
||||||
if(supv_timer > 5) {
|
if(supv_timer > 5) {
|
||||||
@ -262,7 +269,7 @@ void PIOS_SPEKTRUM_irq_handler() {
|
|||||||
if (sync_of > 12) {
|
if (sync_of > 12) {
|
||||||
/* signal lost */
|
/* signal lost */
|
||||||
sync_of = 0;
|
sync_of = 0;
|
||||||
for (int i = 0; i < 12; i++) {
|
for (int i = 0; i < PIOS_SPEKTRUM_NUM_INPUTS; i++) {
|
||||||
CaptureValue[i] = 0;
|
CaptureValue[i] = 0;
|
||||||
CaptureValueTemp[i] = 0;
|
CaptureValueTemp[i] = 0;
|
||||||
}
|
}
|
||||||
|
@ -30,8 +30,4 @@
|
|||||||
#ifndef PIOS_PPM_H
|
#ifndef PIOS_PPM_H
|
||||||
#define PIOS_PPM_H
|
#define PIOS_PPM_H
|
||||||
|
|
||||||
/* Public Functions */
|
|
||||||
extern void PIOS_PPM_Init(void);
|
|
||||||
extern int32_t PIOS_PPM_Get(int8_t Channel);
|
|
||||||
|
|
||||||
#endif /* PIOS_PPM_H */
|
#endif /* PIOS_PPM_H */
|
||||||
|
@ -59,6 +59,10 @@ extern uint8_t pios_ppm_num_channels;
|
|||||||
extern const struct pios_ppm_cfg pios_ppm_cfg;
|
extern const struct pios_ppm_cfg pios_ppm_cfg;
|
||||||
extern const struct pios_ppmsv_cfg pios_ppmsv_cfg;
|
extern const struct pios_ppmsv_cfg pios_ppmsv_cfg;
|
||||||
|
|
||||||
|
extern const struct pios_rcvr_driver pios_ppm_rcvr_driver;
|
||||||
|
|
||||||
|
extern void PIOS_PPM_Init(void);
|
||||||
|
|
||||||
#endif /* PIOS_PPM_PRIV_H */
|
#endif /* PIOS_PPM_PRIV_H */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -30,9 +30,4 @@
|
|||||||
#ifndef PIOS_PWM_H
|
#ifndef PIOS_PWM_H
|
||||||
#define PIOS_PWM_H
|
#define PIOS_PWM_H
|
||||||
|
|
||||||
/* Public Functions */
|
|
||||||
extern void PIOS_PWM_Init(void);
|
|
||||||
extern int32_t PIOS_PWM_Get(int8_t Channel);
|
|
||||||
//extern void PIOS_PWM_irq_handler(TIM_TypeDef * timer);
|
|
||||||
|
|
||||||
#endif /* PIOS_PWM_H */
|
#endif /* PIOS_PWM_H */
|
||||||
|
@ -57,6 +57,10 @@ extern void PIOS_PWM_irq_handler(TIM_TypeDef * timer);
|
|||||||
extern uint8_t pios_pwm_num_channels;
|
extern uint8_t pios_pwm_num_channels;
|
||||||
extern const struct pios_pwm_cfg pios_pwm_cfg;
|
extern const struct pios_pwm_cfg pios_pwm_cfg;
|
||||||
|
|
||||||
|
extern const struct pios_rcvr_driver pios_pwm_rcvr_driver;
|
||||||
|
|
||||||
|
extern void PIOS_PWM_Init(void);
|
||||||
|
|
||||||
#endif /* PIOS_PWM_PRIV_H */
|
#endif /* PIOS_PWM_PRIV_H */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -33,9 +33,6 @@
|
|||||||
/* Global Types */
|
/* Global Types */
|
||||||
|
|
||||||
/* Public Functions */
|
/* Public Functions */
|
||||||
extern void PIOS_SBUS_Init(void);
|
|
||||||
extern int16_t PIOS_SBUS_Get(int8_t Channel);
|
|
||||||
extern void SBUS_IRQHandler(uint32_t usart_id);
|
|
||||||
|
|
||||||
#endif /* PIOS_SBUS_H */
|
#endif /* PIOS_SBUS_H */
|
||||||
|
|
||||||
|
@ -76,9 +76,16 @@ struct pios_sbus_cfg {
|
|||||||
GPIO_InitTypeDef gpio_inv_init;
|
GPIO_InitTypeDef gpio_inv_init;
|
||||||
BitAction gpio_inv_enable;
|
BitAction gpio_inv_enable;
|
||||||
};
|
};
|
||||||
extern const struct pios_sbus_cfg pios_sbus_cfg;
|
|
||||||
|
|
||||||
extern void PIOS_SBUS_irq_handler();
|
extern void PIOS_SBUS_irq_handler();
|
||||||
|
extern void PIOS_SBUSSV_irq_handler();
|
||||||
|
|
||||||
|
extern uint8_t pios_sbus_num_channels;
|
||||||
|
extern const struct pios_sbus_cfg pios_sbus_cfg;
|
||||||
|
|
||||||
|
extern const struct pios_rcvr_driver pios_sbus_rcvr_driver;
|
||||||
|
|
||||||
|
extern void PIOS_SBUS_Init(void);
|
||||||
|
|
||||||
#endif /* PIOS_SBUS_PRIV_H */
|
#endif /* PIOS_SBUS_PRIV_H */
|
||||||
|
|
||||||
|
@ -34,11 +34,8 @@
|
|||||||
/* Global Types */
|
/* Global Types */
|
||||||
|
|
||||||
/* Public Functions */
|
/* Public Functions */
|
||||||
extern void PIOS_SPEKTRUM_Init(void);
|
|
||||||
extern uint8_t PIOS_SPEKTRUM_Bind(void);
|
extern uint8_t PIOS_SPEKTRUM_Bind(void);
|
||||||
extern int32_t PIOS_SPEKTRUM_Decode(uint8_t b);
|
extern int32_t PIOS_SPEKTRUM_Decode(uint8_t b);
|
||||||
extern int16_t PIOS_SPEKTRUM_Get(int8_t Channel);
|
|
||||||
extern void SPEKTRUM_IRQHandler(uint32_t usart_id);
|
|
||||||
|
|
||||||
#endif /* PIOS_SPEKTRUM_H */
|
#endif /* PIOS_SPEKTRUM_H */
|
||||||
|
|
||||||
|
@ -45,10 +45,15 @@ struct pios_spektrum_cfg {
|
|||||||
};
|
};
|
||||||
|
|
||||||
extern void PIOS_SPEKTRUM_irq_handler();
|
extern void PIOS_SPEKTRUM_irq_handler();
|
||||||
|
extern void PIOS_SPEKTRUMSV_irq_handler();
|
||||||
|
|
||||||
extern uint8_t pios_spektrum_num_channels;
|
extern uint8_t pios_spektrum_num_channels;
|
||||||
extern const struct pios_spektrum_cfg pios_spektrum_cfg;
|
extern const struct pios_spektrum_cfg pios_spektrum_cfg;
|
||||||
|
|
||||||
|
extern const struct pios_rcvr_driver pios_spektrum_rcvr_driver;
|
||||||
|
|
||||||
|
extern void PIOS_SPEKTRUM_Init(void);
|
||||||
|
|
||||||
#endif /* PIOS_PWM_PRIV_H */
|
#endif /* PIOS_PWM_PRIV_H */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
Loading…
Reference in New Issue
Block a user