1
0
mirror of https://bitbucket.org/librepilot/librepilot.git synced 2025-02-27 16:54:15 +01:00

Merge branch 'master' into bugfix-flight

Conflicts:
	flight/CopterControl/System/inc/pios_config.h
This commit is contained in:
James Cotton 2011-07-12 11:40:47 -05:00
commit 59798701a2
77 changed files with 7902 additions and 5109 deletions

View File

@ -27,6 +27,10 @@ N: Pedro Assuncao
E: pedro (dot) agda (plus) openpilot (at) gmail (dot) com E: pedro (dot) agda (plus) openpilot (at) gmail (dot) com
D: Initial GCS Settings Gadget work D: Initial GCS Settings Gadget work
N: Werner Backes
E: werner (at) bit-1 (dot) de
D: Port of CopterControl to PS3 Move Controller (MoveCopter)
N: Jose Barros N: Jose Barros
E: josembarros (at) hotmail (dot) com E: josembarros (at) hotmail (dot) com
D: Next-Gen OP Map Lib, Y-Modem Library, Uploader Plugin D: Next-Gen OP Map Lib, Y-Modem Library, Uploader Plugin

View File

@ -117,11 +117,35 @@ C: Sami Korhonen (Sambas)
D: May 2011 D: May 2011
V: http://vimeo.com/24258192 V: http://vimeo.com/24258192
M: First CopterControl flip on a Flybarless Heli M: First Y6 CopterControl flight
C: Michel Pet
D: June 2011
V: http://www.youtube.com/watch?v=QsE2MQELPZY
M: First MoveControl flight
C: Werner Backes
D: July 2011
V: http://vimeo.com/25983655
M: First Altitude Hold using Sonar
C: C:
D: D:
V: V:
M: First CopterControl Navigation on RC Ground Vechicle
C:
D:
V:
M: First CopterControl Navigation on RC Water Vechicle
C:
D:
V:
M: First CopterControl flip on a Flybarless Heli
C:
D:
V:
An incomplete list of some future Milestones is below: An incomplete list of some future Milestones is below:
@ -131,8 +155,7 @@ An incomplete list of some future Milestones is below:
* First successful flight using the GCS only and no RC TX * First successful flight using the GCS only and no RC TX
* First use of Magic Waypoint * First use of Magic Waypoint
* First Flybarless Helicopter flight with OpenPilot * First Flybarless Helicopter flight with OpenPilot
* First flight with CopterControl * First fixed wing navigation flight
* First fixed wing navigation flight
* First Multirotor navigation flight * First Multirotor navigation flight
* First Helicopter navigation flight * First Helicopter navigation flight
* First over 1km navigation flight * First over 1km navigation flight

View File

@ -71,6 +71,7 @@ help:
@echo " qt_sdk_install - Install the QT v4.6.2 tools" @echo " qt_sdk_install - Install the QT v4.6.2 tools"
@echo " arm_sdk_install - Install the Code Sourcery ARM gcc toolchain" @echo " arm_sdk_install - Install the Code Sourcery ARM gcc toolchain"
@echo " openocd_install - Install the OpenOCD JTAG daemon" @echo " openocd_install - Install the OpenOCD JTAG daemon"
@echo " stm32flash_install - Install the stm32flash tool for unbricking boards"
@echo @echo
@echo " [Big Hammer]" @echo " [Big Hammer]"
@echo " all - Generate UAVObjects, build openpilot firmware and gcs" @echo " all - Generate UAVObjects, build openpilot firmware and gcs"
@ -92,21 +93,25 @@ help:
@echo " <board> - Build firmware for <board>" @echo " <board> - Build firmware for <board>"
@echo " supported boards are ($(ALL_BOARDS))" @echo " supported boards are ($(ALL_BOARDS))"
@echo " fw_<board> - Build firmware for <board>" @echo " fw_<board> - Build firmware for <board>"
@echo " supported boards are ($(FW_TARGETS))" @echo " supported boards are ($(FW_BOARDS))"
@echo " fw_<board>_clean - Remove firmware for <board>" @echo " fw_<board>_clean - Remove firmware for <board>"
@echo " fw_<board>_program - Use OpenOCD + JTAG to write firmware to <board>" @echo " fw_<board>_program - Use OpenOCD + JTAG to write firmware to <board>"
@echo @echo
@echo " [Bootloader]" @echo " [Bootloader]"
@echo " bl_<board> - Build bootloader for <board>" @echo " bl_<board> - Build bootloader for <board>"
@echo " supported boards are ($(BL_TARGETS))" @echo " supported boards are ($(BL_BOARDS))"
@echo " bl_<board>_clean - Remove bootloader for <board>" @echo " bl_<board>_clean - Remove bootloader for <board>"
@echo " bl_<board>_program - Use OpenOCD + JTAG to write bootloader to <board>" @echo " bl_<board>_program - Use OpenOCD + JTAG to write bootloader to <board>"
@echo @echo
@echo " [Bootloader Updater]" @echo " [Bootloader Updater]"
@echo " bu_<board> - Build bootloader updater for <board>" @echo " bu_<board> - Build bootloader updater for <board>"
@echo " supported boards are ($(BU_TARGETS))" @echo " supported boards are ($(BU_BOARDS))"
@echo " bu_<board>_clean - Remove bootloader updater for <board>" @echo " bu_<board>_clean - Remove bootloader updater for <board>"
@echo @echo
@echo " [Unbrick a board]"
@echo " unbrick_<board> - Use the STM32's built in boot ROM to write a bootloader to <board>"
@echo " supported boards are ($(BL_BOARDS))"
@echo
@echo " [Simulation]" @echo " [Simulation]"
@echo " sim_posix - Build OpenPilot simulation firmware for" @echo " sim_posix - Build OpenPilot simulation firmware for"
@echo " a POSIX compatible system (Linux, Mac OS X, ...)" @echo " a POSIX compatible system (Linux, Mac OS X, ...)"
@ -226,6 +231,25 @@ openocd_install: openocd_clean
openocd_clean: openocd_clean:
$(V1) [ ! -d "$(OPENOCD_DIR)" ] || $(RM) -r "$(OPENOCD_DIR)" $(V1) [ ! -d "$(OPENOCD_DIR)" ] || $(RM) -r "$(OPENOCD_DIR)"
STM32FLASH_DIR := $(TOOLS_DIR)/stm32flash
.PHONY: stm32flash_install
stm32flash_install: STM32FLASH_URL := http://stm32flash.googlecode.com/svn/trunk
stm32flash_install: STM32FLASH_REV := 52
stm32flash_install: stm32flash_clean
# download the source
$(V0) @echo " DOWNLOAD $(STM32FLASH_URL) @ r$(STM32FLASH_REV)"
$(V1) svn export -q -r "$(STM32FLASH_REV)" "$(STM32FLASH_URL)" "$(STM32FLASH_DIR)"
# build
$(V0) @echo " BUILD $(STM32FLASH_DIR)"
$(V1) $(MAKE) --silent -C $(STM32FLASH_DIR) all
.PHONY: stm32flash_clean
stm32flash_clean:
$(V0) @echo " CLEAN $(STM32FLASH_DIR)"
$(V1) [ ! -d "$(STM32FLASH_DIR)" ] || $(RM) -r "$(STM32FLASH_DIR)"
############################## ##############################
# #
# Set up paths to tools # Set up paths to tools
@ -277,7 +301,7 @@ openpilotgcs: uavobjects_gcs
.PHONY: openpilotgcs_clean .PHONY: openpilotgcs_clean
openpilotgcs_clean: openpilotgcs_clean:
$(V0) @echo " CLEAN $@" $(V0) @echo " CLEAN $@"
$(V1) [ ! -d "$(BUILD_DIR)/ground/openpilotgcs" ] || $(RM) -r "$(BUILD_DIR)/ground/openpilotgcs" $(V1) [ ! -d "$(BUILD_DIR)/ground/openpilotgcs" ] || $(RM) -r "$(BUILD_DIR)/ground/openpilotgcs"
.PHONY: uavobjgenerator .PHONY: uavobjgenerator
@ -307,7 +331,7 @@ uavobjects_test: $(UAVOBJ_OUT_DIR) uavobjgenerator
$(V1) $(UAVOBJGENERATOR) -v -none $(UAVOBJ_XML_DIR) $(ROOT_DIR) $(V1) $(UAVOBJGENERATOR) -v -none $(UAVOBJ_XML_DIR) $(ROOT_DIR)
uavobjects_clean: uavobjects_clean:
$(V0) @echo " CLEAN $@" $(V0) @echo " CLEAN $@"
$(V1) [ ! -d "$(UAVOBJ_OUT_DIR)" ] || $(RM) -r "$(UAVOBJ_OUT_DIR)" $(V1) [ ! -d "$(UAVOBJ_OUT_DIR)" ] || $(RM) -r "$(UAVOBJ_OUT_DIR)"
############################## ##############################
@ -335,7 +359,7 @@ fw_$(1)_%: uavobjects_flight
.PHONY: $(1)_clean .PHONY: $(1)_clean
$(1)_clean: fw_$(1)_clean $(1)_clean: fw_$(1)_clean
fw_$(1)_clean: fw_$(1)_clean:
$(V0) @echo " CLEAN $$@" $(V0) @echo " CLEAN $$@"
$(V1) $(RM) -fr $(BUILD_DIR)/fw_$(1) $(V1) $(RM) -fr $(BUILD_DIR)/fw_$(1)
endef endef
@ -355,9 +379,23 @@ bl_$(1)_%:
REMOVE_CMD="$(RM)" OOCD_EXE="$(OPENOCD)" \ REMOVE_CMD="$(RM)" OOCD_EXE="$(OPENOCD)" \
$$* $$*
.PHONY: unbrick_$(1)
unbrick_$(1): bl_$(1)_hex
$(if $(filter-out undefined,$(origin UNBRICK_TTY)),
$(V0) @echo " UNBRICK $(1) via $$(UNBRICK_TTY)"
$(V1) $(STM32FLASH_DIR)/stm32flash \
-w $(BUILD_DIR)/bl_$(1)/bl_$(1).hex \
-g 0x0 \
$$(UNBRICK_TTY)
,
$(V0) @echo
$(V0) @echo "ERROR: You must specify UNBRICK_TTY=<serial-device> to use for unbricking."
$(V0) @echo " eg. $$(MAKE) $$@ UNBRICK_TTY=/dev/ttyUSB0"
)
.PHONY: bl_$(1)_clean .PHONY: bl_$(1)_clean
bl_$(1)_clean: bl_$(1)_clean:
$(V0) @echo " CLEAN $$@" $(V0) @echo " CLEAN $$@"
$(V1) $(RM) -fr $(BUILD_DIR)/bl_$(1) $(V1) $(RM) -fr $(BUILD_DIR)/bl_$(1)
endef endef
@ -377,7 +415,7 @@ bu_$(1)_%: bl_$(1)_bino
.PHONY: bu_$(1)_clean .PHONY: bu_$(1)_clean
bu_$(1)_clean: bu_$(1)_clean:
$(V0) @echo " CLEAN $$@" $(V0) @echo " CLEAN $$@"
$(V1) $(RM) -fr $(BUILD_DIR)/bu_$(1) $(V1) $(RM) -fr $(BUILD_DIR)/bu_$(1)
endef endef
@ -403,14 +441,20 @@ pipxtreme_friendly := PipXtreme
ins_friendly := INS ins_friendly := INS
ahrs_friendly := AHRS ahrs_friendly := AHRS
FW_TARGETS := $(addprefix fw_, $(ALL_BOARDS)) # Start out assuming that we'll build fw, bl and bu for all boards
BL_TARGETS := $(addprefix bl_, $(ALL_BOARDS)) FW_BOARDS := $(ALL_BOARDS)
BU_TARGETS := $(addprefix bu_, $(ALL_BOARDS)) BL_BOARDS := $(ALL_BOARDS)
BU_BOARDS := $(ALL_BOARDS)
# FIXME: The INS build doesn't have a bootloader or bootloader # FIXME: The INS build doesn't have a bootloader or bootloader
# updater yet so we need to filter them out to prevent errors. # updater yet so we need to filter them out to prevent errors.
BL_TARGETS := $(filter-out bl_ins, $(BL_TARGETS)) BL_BOARDS := $(filter-out ins, $(ALL_BOARDS))
BU_TARGETS := $(filter-out bu_ins, $(BU_TARGETS)) BU_BOARDS := $(filter-out ins, $(ALL_BOARDS))
# Generate the targets for whatever boards are left in each list
FW_TARGETS := $(addprefix fw_, $(FW_BOARDS))
BL_TARGETS := $(addprefix bl_, $(BL_BOARDS))
BU_TARGETS := $(addprefix bu_, $(BU_BOARDS))
.PHONY: all_fw all_fw_clean .PHONY: all_fw all_fw_clean
all_fw: $(addsuffix _opfw, $(FW_TARGETS)) all_fw: $(addsuffix _opfw, $(FW_TARGETS))
@ -428,6 +472,7 @@ all_bu_clean: $(addsuffix _clean, $(BU_TARGETS))
all_flight: all_fw all_bl all_bu all_flight: all_fw all_bl all_bu
all_flight_clean: all_fw_clean all_bl_clean all_bu_clean all_flight_clean: all_fw_clean all_bl_clean all_bu_clean
# Expand the groups of targets for each board
$(foreach board, $(ALL_BOARDS), $(eval $(call BOARD_PHONY_TEMPLATE,$(board)))) $(foreach board, $(ALL_BOARDS), $(eval $(call BOARD_PHONY_TEMPLATE,$(board))))
# Expand the bootloader updater rules # Expand the bootloader updater rules

View File

@ -54,7 +54,7 @@ static const struct pios_spi_cfg pios_spi_op_cfg = {
.ahb_clk = RCC_AHBPeriph_DMA1, .ahb_clk = RCC_AHBPeriph_DMA1,
.irq = { .irq = {
.handler = PIOS_SPI_op_irq_handler, .handler = NULL,
.flags = .flags =
(DMA1_FLAG_TC4 | DMA1_FLAG_TE4 | DMA1_FLAG_HT4 | (DMA1_FLAG_TC4 | DMA1_FLAG_TE4 | DMA1_FLAG_HT4 |
DMA1_FLAG_GL4), DMA1_FLAG_GL4),
@ -153,11 +153,11 @@ void PIOS_SPI_op_irq_handler(void)
extern void PIOS_ADC_handler(void); extern void PIOS_ADC_handler(void);
void DMA1_Channel1_IRQHandler() __attribute__ ((alias("PIOS_ADC_handler"))); void DMA1_Channel1_IRQHandler() __attribute__ ((alias("PIOS_ADC_handler")));
// Remap the ADC DMA handler to this one // Remap the ADC DMA handler to this one
const struct pios_adc_cfg pios_adc_cfg = { static const struct pios_adc_cfg pios_adc_cfg = {
.dma = { .dma = {
.ahb_clk = RCC_AHBPeriph_DMA1, .ahb_clk = RCC_AHBPeriph_DMA1,
.irq = { .irq = {
.handler = PIOS_ADC_DMA_Handler, .handler = NULL,
.flags = (DMA1_FLAG_TC1 | DMA1_FLAG_TE1 | DMA1_FLAG_HT1 | DMA1_FLAG_GL1), .flags = (DMA1_FLAG_TC1 | DMA1_FLAG_TE1 | DMA1_FLAG_HT1 | DMA1_FLAG_GL1),
.init = { .init = {
.NVIC_IRQChannel = DMA1_Channel1_IRQn, .NVIC_IRQChannel = DMA1_Channel1_IRQn,
@ -205,17 +205,10 @@ void PIOS_ADC_handler() {
/* /*
* AUX USART * AUX USART
*/ */
void PIOS_USART_aux_irq_handler(void); static const struct pios_usart_cfg pios_usart_aux_cfg = {
void USART3_IRQHandler()
__attribute__ ((alias("PIOS_USART_aux_irq_handler")));
const struct pios_usart_cfg pios_usart_aux_cfg = {
.regs = USART3, .regs = USART3,
.init = { .init = {
#if defined (PIOS_USART_BAUDRATE) .USART_BaudRate = 230400,
.USART_BaudRate = PIOS_USART_BAUDRATE,
#else
.USART_BaudRate = 57600,
#endif
.USART_WordLength = USART_WordLength_8b, .USART_WordLength = USART_WordLength_8b,
.USART_Parity = USART_Parity_No, .USART_Parity = USART_Parity_No,
.USART_StopBits = USART_StopBits_1, .USART_StopBits = USART_StopBits_1,
@ -224,7 +217,7 @@ const struct pios_usart_cfg pios_usart_aux_cfg = {
.USART_Mode = USART_Mode_Rx | USART_Mode_Tx, .USART_Mode = USART_Mode_Rx | USART_Mode_Tx,
}, },
.irq = { .irq = {
.handler = PIOS_USART_aux_irq_handler, .handler = NULL,
.init = { .init = {
.NVIC_IRQChannel = USART3_IRQn, .NVIC_IRQChannel = USART3_IRQn,
.NVIC_IRQChannelPreemptionPriority = PIOS_IRQ_PRIO_HIGH, .NVIC_IRQChannelPreemptionPriority = PIOS_IRQ_PRIO_HIGH,
@ -250,12 +243,6 @@ const struct pios_usart_cfg pios_usart_aux_cfg = {
}, },
}; };
static uint32_t pios_usart_aux_id;
void PIOS_USART_aux_irq_handler(void)
{
PIOS_USART_IRQ_Handler(pios_usart_aux_id);
}
#endif /* PIOS_INCLUDE_USART */ #endif /* PIOS_INCLUDE_USART */
#if defined(PIOS_INCLUDE_COM) #if defined(PIOS_INCLUDE_COM)
@ -279,7 +266,7 @@ void I2C1_EV_IRQHandler()
void I2C1_ER_IRQHandler() void I2C1_ER_IRQHandler()
__attribute__ ((alias("PIOS_I2C_main_adapter_er_irq_handler"))); __attribute__ ((alias("PIOS_I2C_main_adapter_er_irq_handler")));
const struct pios_i2c_adapter_cfg pios_i2c_main_adapter_cfg = { static const struct pios_i2c_adapter_cfg pios_i2c_main_adapter_cfg = {
.regs = I2C1, .regs = I2C1,
.init = { .init = {
.I2C_Mode = I2C_Mode_I2C, .I2C_Mode = I2C_Mode_I2C,
@ -307,7 +294,7 @@ const struct pios_i2c_adapter_cfg pios_i2c_main_adapter_cfg = {
}, },
}, },
.event = { .event = {
.handler = PIOS_I2C_main_adapter_ev_irq_handler, .handler = NULL,
.flags = 0, /* FIXME: check this */ .flags = 0, /* FIXME: check this */
.init = { .init = {
.NVIC_IRQChannel = I2C1_EV_IRQn, .NVIC_IRQChannel = I2C1_EV_IRQn,
@ -317,7 +304,7 @@ const struct pios_i2c_adapter_cfg pios_i2c_main_adapter_cfg = {
}, },
}, },
.error = { .error = {
.handler = PIOS_I2C_main_adapter_er_irq_handler, .handler = NULL,
.flags = 0, /* FIXME: check this */ .flags = 0, /* FIXME: check this */
.init = { .init = {
.NVIC_IRQChannel = I2C1_ER_IRQn, .NVIC_IRQChannel = I2C1_ER_IRQn,
@ -388,6 +375,7 @@ void PIOS_Board_Init(void) {
/* Communication system */ /* Communication system */
#if !defined(PIOS_ENABLE_DEBUG_PINS) #if !defined(PIOS_ENABLE_DEBUG_PINS)
#if defined(PIOS_INCLUDE_COM) #if defined(PIOS_INCLUDE_COM)
uint32_t pios_usart_aux_id;
if (PIOS_USART_Init(&pios_usart_aux_id, &pios_usart_aux_cfg)) { if (PIOS_USART_Init(&pios_usart_aux_id, &pios_usart_aux_cfg)) {
PIOS_DEBUG_Assert(0); PIOS_DEBUG_Assert(0);
} }

View File

@ -55,7 +55,7 @@ static const struct pios_spi_cfg
.ahb_clk = RCC_AHBPeriph_DMA1, .ahb_clk = RCC_AHBPeriph_DMA1,
.irq = { .irq = {
.handler = PIOS_SPI_op_irq_handler, .handler = NULL,
.flags = (DMA1_FLAG_TC4 | DMA1_FLAG_TE4 | DMA1_FLAG_HT4 | DMA1_FLAG_GL4), .flags = (DMA1_FLAG_TC4 | DMA1_FLAG_TE4 | DMA1_FLAG_HT4 | DMA1_FLAG_GL4),
.init = { .init = {
.NVIC_IRQChannel = DMA1_Channel4_IRQn, .NVIC_IRQChannel = DMA1_Channel4_IRQn,

View File

@ -60,7 +60,7 @@ const struct pios_spi_cfg
.ahb_clk = RCC_AHBPeriph_DMA1, .ahb_clk = RCC_AHBPeriph_DMA1,
.irq = { .irq = {
.handler = PIOS_SPI_ahrs_irq_handler, .handler = NULL,
.flags = (DMA1_FLAG_TC4 | DMA1_FLAG_TE4 | DMA1_FLAG_HT4 | DMA1_FLAG_GL4), .flags = (DMA1_FLAG_TC4 | DMA1_FLAG_TE4 | DMA1_FLAG_HT4 | DMA1_FLAG_GL4),
.init = { .init = {
.NVIC_IRQChannel = DMA1_Channel4_IRQn, .NVIC_IRQChannel = DMA1_Channel4_IRQn,
@ -143,9 +143,9 @@ void PIOS_SPI_ahrs_irq_handler(void) {
/* /*
* Telemetry USART * Telemetry USART
*/ */
void PIOS_USART_telem_irq_handler(void); const struct pios_usart_cfg pios_usart_telem_cfg = {
void USART2_IRQHandler() __attribute__ ((alias ("PIOS_USART_telem_irq_handler"))); .regs = USART2,
const struct pios_usart_cfg pios_usart_telem_cfg = { .regs = USART2, .init = { .init = {
#if defined (PIOS_COM_TELEM_BAUDRATE) #if defined (PIOS_COM_TELEM_BAUDRATE)
.USART_BaudRate = PIOS_COM_TELEM_BAUDRATE, .USART_BaudRate = PIOS_COM_TELEM_BAUDRATE,
#else #else
@ -157,7 +157,7 @@ const struct pios_usart_cfg pios_usart_telem_cfg = { .regs = USART2, .init = {
.USART_HardwareFlowControl = USART_HardwareFlowControl_None, .USART_HardwareFlowControl = USART_HardwareFlowControl_None,
.USART_Mode = USART_Mode_Rx | USART_Mode_Tx, .USART_Mode = USART_Mode_Rx | USART_Mode_Tx,
}, .irq = { }, .irq = {
.handler = PIOS_USART_telem_irq_handler, .handler = NULL,
.init = { .init = {
.NVIC_IRQChannel = USART2_IRQn, .NVIC_IRQChannel = USART2_IRQn,
.NVIC_IRQChannelPreemptionPriority = PIOS_IRQ_PRIO_HIGH, .NVIC_IRQChannelPreemptionPriority = PIOS_IRQ_PRIO_HIGH,
@ -180,11 +180,6 @@ const struct pios_usart_cfg pios_usart_telem_cfg = { .regs = USART2, .init = {
}, },
}, }; }, };
static uint32_t pios_usart_telem_rf_id;
void PIOS_USART_telem_irq_handler(void) {
PIOS_USART_IRQ_Handler(pios_usart_telem_rf_id);
}
#endif /* PIOS_INCLUDE_USART */ #endif /* PIOS_INCLUDE_USART */
#if defined(PIOS_INCLUDE_COM) #if defined(PIOS_INCLUDE_COM)
@ -218,6 +213,7 @@ void PIOS_Board_Init(void) {
/* Initialize the PiOS library */ /* Initialize the PiOS library */
#if defined(PIOS_INCLUDE_COM) #if defined(PIOS_INCLUDE_COM)
uint32_t pios_usart_telem_rf_id;
if (PIOS_USART_Init(&pios_usart_telem_rf_id, &pios_usart_telem_cfg)) { if (PIOS_USART_Init(&pios_usart_telem_rf_id, &pios_usart_telem_cfg)) {
PIOS_DEBUG_Assert(0); PIOS_DEBUG_Assert(0);
} }

View File

@ -45,7 +45,7 @@ ENABLE_DEBUG_PINS ?= NO
# Set to Yes to enable the AUX UART which is mapped on the S1 (Tx) and S2 (Rx) servo outputs # Set to Yes to enable the AUX UART which is mapped on the S1 (Tx) and S2 (Rx) servo outputs
ENABLE_AUX_UART ?= NO ENABLE_AUX_UART ?= NO
USE_SPEKTRUM ?= NO USE_GPS ?= NO
USE_I2C ?= NO USE_I2C ?= NO
@ -166,6 +166,7 @@ SRC += $(OPUAVSYNTHDIR)/mixersettings.c
SRC += $(OPUAVSYNTHDIR)/mixerstatus.c SRC += $(OPUAVSYNTHDIR)/mixerstatus.c
SRC += $(OPUAVSYNTHDIR)/firmwareiapobj.c SRC += $(OPUAVSYNTHDIR)/firmwareiapobj.c
SRC += $(OPUAVSYNTHDIR)/attitudesettings.c SRC += $(OPUAVSYNTHDIR)/attitudesettings.c
SRC += $(OPUAVSYNTHDIR)/hwsettings.c
#${wildcard ${OBJ}/$(shell echo $(VAR) | tr A-Z a-z)/*.c} #${wildcard ${OBJ}/$(shell echo $(VAR) | tr A-Z a-z)/*.c}
#SRC += ${foreach OBJ, ${UAVOBJECTS}, $(UAVOBJECTS)/$(OBJ).c} #SRC += ${foreach OBJ, ${UAVOBJECTS}, $(UAVOBJECTS)/$(OBJ).c}
# Cant use until i can automatically generate list of UAVObjects # Cant use until i can automatically generate list of UAVObjects
@ -185,6 +186,7 @@ SRC += $(PIOSSTM32F10X)/pios_spi.c
SRC += $(PIOSSTM32F10X)/pios_ppm.c SRC += $(PIOSSTM32F10X)/pios_ppm.c
SRC += $(PIOSSTM32F10X)/pios_pwm.c SRC += $(PIOSSTM32F10X)/pios_pwm.c
SRC += $(PIOSSTM32F10X)/pios_spektrum.c SRC += $(PIOSSTM32F10X)/pios_spektrum.c
SRC += $(PIOSSTM32F10X)/pios_sbus.c
SRC += $(PIOSSTM32F10X)/pios_debug.c SRC += $(PIOSSTM32F10X)/pios_debug.c
SRC += $(PIOSSTM32F10X)/pios_gpio.c SRC += $(PIOSSTM32F10X)/pios_gpio.c
SRC += $(PIOSSTM32F10X)/pios_exti.c SRC += $(PIOSSTM32F10X)/pios_exti.c
@ -207,6 +209,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
@ -379,15 +382,15 @@ endif
ifeq ($(ERASE_FLASH), YES) ifeq ($(ERASE_FLASH), YES)
CDEFS += -DERASE_FLASH CDEFS += -DERASE_FLASH
endif endif
ifeq ($(USE_SPEKTRUM), YES)
CDEFS += -DUSE_SPEKTRUM ifneq ($(USE_GPS), NO)
CDEFS += -DUSE_GPS
endif endif
ifeq ($(USE_I2C), YES) ifeq ($(USE_I2C), YES)
CDEFS += -DUSE_I2C CDEFS += -DUSE_I2C
endif endif
# Place project-specific -D and/or -U options for # Place project-specific -D and/or -U options for
# Assembler with preprocessor here. # Assembler with preprocessor here.
#ADEFS = -DUSE_IRQ_ASM_WRAPPER #ADEFS = -DUSE_IRQ_ASM_WRAPPER

View File

@ -29,7 +29,7 @@
#define configCPU_CLOCK_HZ ( ( unsigned long ) 72000000 ) #define configCPU_CLOCK_HZ ( ( unsigned long ) 72000000 )
#define configTICK_RATE_HZ ( ( portTickType ) 1000 ) #define configTICK_RATE_HZ ( ( portTickType ) 1000 )
#define configMAX_PRIORITIES ( ( unsigned portBASE_TYPE ) 5 ) #define configMAX_PRIORITIES ( ( unsigned portBASE_TYPE ) 5 )
#define configMINIMAL_STACK_SIZE ( ( unsigned short ) 128 ) #define configMINIMAL_STACK_SIZE ( ( unsigned short ) 48 )
#define configTOTAL_HEAP_SIZE ( ( size_t ) ( 14 * 1024 ) ) #define configTOTAL_HEAP_SIZE ( ( size_t ) ( 14 * 1024 ) )
#define configMAX_TASK_NAME_LEN ( 16 ) #define configMAX_TASK_NAME_LEN ( 16 )
#define configUSE_TRACE_FACILITY 0 #define configUSE_TRACE_FACILITY 0

View File

@ -1,107 +1,108 @@
/** /**
****************************************************************************** ******************************************************************************
* @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 */
#define PIOS_INCLUDE_ADC
/* Enable/Disable PiOS Modules */ #define PIOS_INCLUDE_DELAY
#define PIOS_INCLUDE_ADC #if defined(USE_I2C)
#define PIOS_INCLUDE_DELAY #define PIOS_INCLUDE_I2C
#if defined(USE_I2C) #define PIOS_INCLUDE_I2C_ESC
#define PIOS_INCLUDE_I2C #endif
#define PIOS_INCLUDE_I2C_ESC #define PIOS_INCLUDE_IRQ
#endif #define PIOS_INCLUDE_LED
#define PIOS_INCLUDE_IRQ
#define PIOS_INCLUDE_LED #define PIOS_INCLUDE_RCVR
#if defined(USE_SPEKTRUM) /* Supported receiver interfaces */
#define PIOS_INCLUDE_SPEKTRUM #define PIOS_INCLUDE_SPEKTRUM
#else #define PIOS_INCLUDE_SBUS
#define PIOS_INCLUDE_GPS //#define PIOS_INCLUDE_PPM
//#define PIOS_INCLUDE_PPM #define PIOS_INCLUDE_PWM
#define PIOS_INCLUDE_PWM
#endif /* Supported USART-based PIOS modules */
#define PIOS_INCLUDE_TELEMETRY_RF
//#define PIOS_INCLUDE_GPS
#define PIOS_INCLUDE_SERVO
#define PIOS_INCLUDE_SPI #define PIOS_INCLUDE_SERVO
#define PIOS_INCLUDE_SYS #define PIOS_INCLUDE_SPI
#define PIOS_INCLUDE_USART #define PIOS_INCLUDE_SYS
#define PIOS_INCLUDE_USB_HID #define PIOS_INCLUDE_USART
#define PIOS_INCLUDE_COM #define PIOS_INCLUDE_USB_HID
#define PIOS_INCLUDE_SETTINGS #define PIOS_INCLUDE_COM
#define PIOS_INCLUDE_FREERTOS #define PIOS_INCLUDE_SETTINGS
#define PIOS_INCLUDE_GPIO #define PIOS_INCLUDE_FREERTOS
#define PIOS_INCLUDE_EXTI #define PIOS_INCLUDE_GPIO
#define PIOS_INCLUDE_RTC #define PIOS_INCLUDE_EXTI
#define PIOS_INCLUDE_WDG #define PIOS_INCLUDE_RTC
#define PIOS_INCLUDE_BL_HELPER #define PIOS_INCLUDE_WDG
#define PIOS_INCLUDE_BL_HELPER
#define PIOS_INCLUDE_ADXL345
#define PIOS_INCLUDE_FLASH #define PIOS_INCLUDE_ADXL345
#define PIOS_INCLUDE_FLASH
/* A really shitty setting saving implementation */
#define PIOS_INCLUDE_FLASH_SECTOR_SETTINGS /* A really shitty setting saving implementation */
#define PIOS_INCLUDE_FLASH_SECTOR_SETTINGS
/* Defaults for Logging */
#define LOG_FILENAME "PIOS.LOG" /* Defaults for Logging */
#define STARTUP_LOG_ENABLED 1 #define LOG_FILENAME "PIOS.LOG"
#define STARTUP_LOG_ENABLED 1
/* COM Module */
#define GPS_BAUDRATE 19200 /* COM Module */
#define TELEM_BAUDRATE 19200 #define GPS_BAUDRATE 19200
#define AUXUART_ENABLED 0 #define TELEM_BAUDRATE 19200
#define AUXUART_BAUDRATE 19200 #define AUXUART_ENABLED 0
#define AUXUART_BAUDRATE 19200
/* Alarm Thresholds */
#define HEAP_LIMIT_WARNING 156 /* Alarm Thresholds */
#define HEAP_LIMIT_CRITICAL 130 #define HEAP_LIMIT_WARNING 220
#define CPULOAD_LIMIT_WARNING 80 #define HEAP_LIMIT_CRITICAL 40
#define CPULOAD_LIMIT_CRITICAL 95 #define CPULOAD_LIMIT_WARNING 85
#define CPULOAD_LIMIT_CRITICAL 95
/* Task stack sizes */
#define PIOS_ACTUATOR_STACK_SIZE 1020 /* Task stack sizes */
#define PIOS_MANUAL_STACK_SIZE 724 #define PIOS_ACTUATOR_STACK_SIZE 1020
#define PIOS_SYSTEM_STACK_SIZE 560 #define PIOS_MANUAL_STACK_SIZE 724
#define PIOS_STABILIZATION_STACK_SIZE 524 #define PIOS_SYSTEM_STACK_SIZE 560
#define PIOS_TELEM_STACK_SIZE 500 #define PIOS_STABILIZATION_STACK_SIZE 524
#define PIOS_TELEM_STACK_SIZE 500
#define IDLE_COUNTS_PER_SEC_AT_NO_LOAD 1995998
//#define PIOS_QUATERNION_STABILIZATION #define IDLE_COUNTS_PER_SEC_AT_NO_LOAD 1995998
//#define PIOS_QUATERNION_STABILIZATION
#endif /* PIOS_CONFIG_H */
/** #endif /* PIOS_CONFIG_H */
* @} /**
* @} * @}
*/ * @}
*/

View File

@ -30,10 +30,11 @@
#include <pios.h> #include <pios.h>
#include <openpilot.h> #include <openpilot.h>
#include <uavobjectsinit.h> #include <uavobjectsinit.h>
#include <hwsettings.h>
#include <manualcontrolsettings.h>
#if defined(PIOS_INCLUDE_SPI) #if defined(PIOS_INCLUDE_SPI)
#include <pios_spi_priv.h> #include <pios_spi_priv.h>
/* Flash/Accel Interface /* Flash/Accel Interface
@ -44,7 +45,7 @@
void PIOS_SPI_flash_accel_irq_handler(void); void PIOS_SPI_flash_accel_irq_handler(void);
void DMA1_Channel4_IRQHandler() __attribute__ ((alias ("PIOS_SPI_flash_accel_irq_handler"))); void DMA1_Channel4_IRQHandler() __attribute__ ((alias ("PIOS_SPI_flash_accel_irq_handler")));
void DMA1_Channel5_IRQHandler() __attribute__ ((alias ("PIOS_SPI_flash_accel_irq_handler"))); void DMA1_Channel5_IRQHandler() __attribute__ ((alias ("PIOS_SPI_flash_accel_irq_handler")));
const struct pios_spi_cfg pios_spi_flash_accel_cfg = { static const struct pios_spi_cfg pios_spi_flash_accel_cfg = {
.regs = SPI2, .regs = SPI2,
.init = { .init = {
.SPI_Mode = SPI_Mode_Master, .SPI_Mode = SPI_Mode_Master,
@ -62,7 +63,7 @@ const struct pios_spi_cfg pios_spi_flash_accel_cfg = {
.ahb_clk = RCC_AHBPeriph_DMA1, .ahb_clk = RCC_AHBPeriph_DMA1,
.irq = { .irq = {
.handler = PIOS_SPI_flash_accel_irq_handler, .handler = NULL,
.flags = (DMA1_FLAG_TC4 | DMA1_FLAG_TE4 | DMA1_FLAG_HT4 | DMA1_FLAG_GL4), .flags = (DMA1_FLAG_TC4 | DMA1_FLAG_TE4 | DMA1_FLAG_HT4 | DMA1_FLAG_GL4),
.init = { .init = {
.NVIC_IRQChannel = DMA1_Channel4_IRQn, .NVIC_IRQChannel = DMA1_Channel4_IRQn,
@ -151,11 +152,11 @@ void PIOS_SPI_flash_accel_irq_handler(void)
extern void PIOS_ADC_handler(void); extern void PIOS_ADC_handler(void);
void DMA1_Channel1_IRQHandler() __attribute__ ((alias("PIOS_ADC_handler"))); void DMA1_Channel1_IRQHandler() __attribute__ ((alias("PIOS_ADC_handler")));
// Remap the ADC DMA handler to this one // Remap the ADC DMA handler to this one
const struct pios_adc_cfg pios_adc_cfg = { static const struct pios_adc_cfg pios_adc_cfg = {
.dma = { .dma = {
.ahb_clk = RCC_AHBPeriph_DMA1, .ahb_clk = RCC_AHBPeriph_DMA1,
.irq = { .irq = {
.handler = PIOS_ADC_DMA_Handler, .handler = NULL,
.flags = (DMA1_FLAG_TC1 | DMA1_FLAG_TE1 | DMA1_FLAG_HT1 | DMA1_FLAG_GL1), .flags = (DMA1_FLAG_TC1 | DMA1_FLAG_TE1 | DMA1_FLAG_HT1 | DMA1_FLAG_GL1),
.init = { .init = {
.NVIC_IRQChannel = DMA1_Channel1_IRQn, .NVIC_IRQChannel = DMA1_Channel1_IRQn,
@ -200,19 +201,14 @@ void PIOS_ADC_handler() {
#include "pios_usart_priv.h" #include "pios_usart_priv.h"
#if defined(PIOS_INCLUDE_TELEMETRY_RF)
/* /*
* Telemetry USART * Telemetry USART
*/ */
void PIOS_USART_telem_irq_handler(void); static const struct pios_usart_cfg pios_usart_telem_main_cfg = {
void USART1_IRQHandler() __attribute__ ((alias ("PIOS_USART_telem_irq_handler")));
const struct pios_usart_cfg pios_usart_telem_cfg = {
.regs = USART1, .regs = USART1,
.init = { .init = {
#if defined (PIOS_COM_TELEM_BAUDRATE) .USART_BaudRate = 57600,
.USART_BaudRate = PIOS_COM_TELEM_BAUDRATE,
#else
.USART_BaudRate = 57600,
#endif
.USART_WordLength = USART_WordLength_8b, .USART_WordLength = USART_WordLength_8b,
.USART_Parity = USART_Parity_No, .USART_Parity = USART_Parity_No,
.USART_StopBits = USART_StopBits_1, .USART_StopBits = USART_StopBits_1,
@ -220,7 +216,7 @@ const struct pios_usart_cfg pios_usart_telem_cfg = {
.USART_Mode = USART_Mode_Rx | USART_Mode_Tx, .USART_Mode = USART_Mode_Rx | USART_Mode_Tx,
}, },
.irq = { .irq = {
.handler = PIOS_USART_telem_irq_handler, .handler = NULL,
.init = { .init = {
.NVIC_IRQChannel = USART1_IRQn, .NVIC_IRQChannel = USART1_IRQn,
.NVIC_IRQChannelPreemptionPriority = PIOS_IRQ_PRIO_MID, .NVIC_IRQChannelPreemptionPriority = PIOS_IRQ_PRIO_MID,
@ -246,20 +242,10 @@ const struct pios_usart_cfg pios_usart_telem_cfg = {
}, },
}; };
#if defined(PIOS_INCLUDE_GPS) static const struct pios_usart_cfg pios_usart_telem_flexi_cfg = {
/* .regs = USART3,
* GPS USART
*/
void PIOS_USART_gps_irq_handler(void);
void USART3_IRQHandler() __attribute__ ((alias ("PIOS_USART_gps_irq_handler")));
const struct pios_usart_cfg pios_usart_gps_cfg = {
.regs = USART3,
.init = { .init = {
#if defined (PIOS_COM_GPS_BAUDRATE) .USART_BaudRate = 57600,
.USART_BaudRate = PIOS_COM_GPS_BAUDRATE,
#else
.USART_BaudRate = 57600,
#endif
.USART_WordLength = USART_WordLength_8b, .USART_WordLength = USART_WordLength_8b,
.USART_Parity = USART_Parity_No, .USART_Parity = USART_Parity_No,
.USART_StopBits = USART_StopBits_1, .USART_StopBits = USART_StopBits_1,
@ -267,7 +253,7 @@ const struct pios_usart_cfg pios_usart_gps_cfg = {
.USART_Mode = USART_Mode_Rx | USART_Mode_Tx, .USART_Mode = USART_Mode_Rx | USART_Mode_Tx,
}, },
.irq = { .irq = {
.handler = PIOS_USART_gps_irq_handler, .handler = NULL,
.init = { .init = {
.NVIC_IRQChannel = USART3_IRQn, .NVIC_IRQChannel = USART3_IRQn,
.NVIC_IRQChannelPreemptionPriority = PIOS_IRQ_PRIO_MID, .NVIC_IRQChannelPreemptionPriority = PIOS_IRQ_PRIO_MID,
@ -292,22 +278,97 @@ const struct pios_usart_cfg pios_usart_gps_cfg = {
}, },
}, },
}; };
#endif #endif /* PIOS_INCLUDE_TELEMETRY_RF */
#if defined(PIOS_INCLUDE_GPS)
/*
* GPS USART
*/
static const struct pios_usart_cfg pios_usart_gps_main_cfg = {
.regs = USART1,
.init = {
.USART_BaudRate = 57600,
.USART_WordLength = USART_WordLength_8b,
.USART_Parity = USART_Parity_No,
.USART_StopBits = USART_StopBits_1,
.USART_HardwareFlowControl = USART_HardwareFlowControl_None,
.USART_Mode = USART_Mode_Rx | USART_Mode_Tx,
},
.irq = {
.handler = NULL,
.init = {
.NVIC_IRQChannel = USART1_IRQn,
.NVIC_IRQChannelPreemptionPriority = PIOS_IRQ_PRIO_MID,
.NVIC_IRQChannelSubPriority = 0,
.NVIC_IRQChannelCmd = ENABLE,
},
},
.rx = {
.gpio = GPIOA,
.init = {
.GPIO_Pin = GPIO_Pin_10,
.GPIO_Speed = GPIO_Speed_2MHz,
.GPIO_Mode = GPIO_Mode_IPU,
},
},
.tx = {
.gpio = GPIOA,
.init = {
.GPIO_Pin = GPIO_Pin_9,
.GPIO_Speed = GPIO_Speed_2MHz,
.GPIO_Mode = GPIO_Mode_AF_PP,
},
},
};
static const struct pios_usart_cfg pios_usart_gps_flexi_cfg = {
.regs = USART3,
.init = {
.USART_BaudRate = 57600,
.USART_WordLength = USART_WordLength_8b,
.USART_Parity = USART_Parity_No,
.USART_StopBits = USART_StopBits_1,
.USART_HardwareFlowControl = USART_HardwareFlowControl_None,
.USART_Mode = USART_Mode_Rx | USART_Mode_Tx,
},
.irq = {
.handler = NULL,
.init = {
.NVIC_IRQChannel = USART3_IRQn,
.NVIC_IRQChannelPreemptionPriority = PIOS_IRQ_PRIO_MID,
.NVIC_IRQChannelSubPriority = 0,
.NVIC_IRQChannelCmd = ENABLE,
},
},
.rx = {
.gpio = GPIOB,
.init = {
.GPIO_Pin = GPIO_Pin_11,
.GPIO_Speed = GPIO_Speed_2MHz,
.GPIO_Mode = GPIO_Mode_IPU,
},
},
.tx = {
.gpio = GPIOB,
.init = {
.GPIO_Pin = GPIO_Pin_10,
.GPIO_Speed = GPIO_Speed_2MHz,
.GPIO_Mode = GPIO_Mode_AF_PP,
},
},
};
#endif /* PIOS_INCLUDE_GPS */
#if defined(PIOS_INCLUDE_SPEKTRUM) #if defined(PIOS_INCLUDE_SPEKTRUM)
/* /*
* SPEKTRUM USART * SPEKTRUM USART
*/ */
void PIOS_USART_spektrum_irq_handler(void); #include <pios_spektrum_priv.h>
void USART3_IRQHandler() __attribute__ ((alias ("PIOS_USART_spektrum_irq_handler")));
const struct pios_usart_cfg pios_usart_spektrum_cfg = { static const struct pios_usart_cfg pios_usart_spektrum_main_cfg = {
.regs = USART3, .regs = USART1,
.init = { .init = {
#if defined (PIOS_COM_SPEKTRUM_BAUDRATE) .USART_BaudRate = 115200,
.USART_BaudRate = PIOS_COM_SPEKTRUM_BAUDRATE,
#else
.USART_BaudRate = 115200,
#endif
.USART_WordLength = USART_WordLength_8b, .USART_WordLength = USART_WordLength_8b,
.USART_Parity = USART_Parity_No, .USART_Parity = USART_Parity_No,
.USART_StopBits = USART_StopBits_1, .USART_StopBits = USART_StopBits_1,
@ -315,7 +376,56 @@ const struct pios_usart_cfg pios_usart_spektrum_cfg = {
.USART_Mode = USART_Mode_Rx, .USART_Mode = USART_Mode_Rx,
}, },
.irq = { .irq = {
.handler = PIOS_USART_spektrum_irq_handler, .handler = PIOS_SPEKTRUM_irq_handler,
.init = {
.NVIC_IRQChannel = USART1_IRQn,
.NVIC_IRQChannelPreemptionPriority = PIOS_IRQ_PRIO_HIGH,
.NVIC_IRQChannelSubPriority = 0,
.NVIC_IRQChannelCmd = ENABLE,
},
},
.rx = {
.gpio = GPIOA,
.init = {
.GPIO_Pin = GPIO_Pin_10,
.GPIO_Speed = GPIO_Speed_2MHz,
.GPIO_Mode = GPIO_Mode_IPU,
},
},
.tx = {
.gpio = GPIOA,
.init = {
.GPIO_Pin = GPIO_Pin_9,
.GPIO_Speed = GPIO_Speed_2MHz,
.GPIO_Mode = GPIO_Mode_IN_FLOATING,
},
},
};
static const struct pios_spektrum_cfg pios_spektrum_main_cfg = {
.bind = {
.gpio = GPIOA,
.init = {
.GPIO_Pin = GPIO_Pin_10,
.GPIO_Speed = GPIO_Speed_2MHz,
.GPIO_Mode = GPIO_Mode_Out_PP,
},
},
.remap = 0,
};
static const struct pios_usart_cfg pios_usart_spektrum_flexi_cfg = {
.regs = USART3,
.init = {
.USART_BaudRate = 115200,
.USART_WordLength = USART_WordLength_8b,
.USART_Parity = USART_Parity_No,
.USART_StopBits = USART_StopBits_1,
.USART_HardwareFlowControl = USART_HardwareFlowControl_None,
.USART_Mode = USART_Mode_Rx,
},
.irq = {
.handler = PIOS_SPEKTRUM_irq_handler,
.init = { .init = {
.NVIC_IRQChannel = USART3_IRQn, .NVIC_IRQChannel = USART3_IRQn,
.NVIC_IRQChannelPreemptionPriority = PIOS_IRQ_PRIO_HIGH, .NVIC_IRQChannelPreemptionPriority = PIOS_IRQ_PRIO_HIGH,
@ -324,7 +434,7 @@ const struct pios_usart_cfg pios_usart_spektrum_cfg = {
}, },
}, },
.rx = { .rx = {
.gpio = GPIOB, .gpio = GPIOA,
.init = { .init = {
.GPIO_Pin = GPIO_Pin_11, .GPIO_Pin = GPIO_Pin_11,
.GPIO_Speed = GPIO_Speed_2MHz, .GPIO_Speed = GPIO_Speed_2MHz,
@ -332,7 +442,7 @@ const struct pios_usart_cfg pios_usart_spektrum_cfg = {
}, },
}, },
.tx = { .tx = {
.gpio = GPIOB, .gpio = GPIOA,
.init = { .init = {
.GPIO_Pin = GPIO_Pin_10, .GPIO_Pin = GPIO_Pin_10,
.GPIO_Speed = GPIO_Speed_2MHz, .GPIO_Speed = GPIO_Speed_2MHz,
@ -341,63 +451,81 @@ const struct pios_usart_cfg pios_usart_spektrum_cfg = {
}, },
}; };
static uint32_t pios_usart_spektrum_id; static const struct pios_spektrum_cfg pios_spektrum_flexi_cfg = {
void PIOS_USART_spektrum_irq_handler(void) .bind = {
{ .gpio = GPIOB,
SPEKTRUM_IRQHandler(pios_usart_spektrum_id); .init = {
} .GPIO_Pin = GPIO_Pin_11,
.GPIO_Speed = GPIO_Speed_2MHz,
#include <pios_spektrum_priv.h> .GPIO_Mode = GPIO_Mode_Out_PP,
void RTC_IRQHandler();
void RTC_IRQHandler() __attribute__ ((alias ("PIOS_SUPV_irq_handler")));
const struct pios_spektrum_cfg pios_spektrum_cfg = {
.pios_usart_spektrum_cfg = &pios_usart_spektrum_cfg,
.gpio_init = { //used for bind feature
.GPIO_Mode = GPIO_Mode_Out_PP,
.GPIO_Speed = GPIO_Speed_2MHz,
},
.remap = 0,
.irq = {
.handler = RTC_IRQHandler,
.init = {
.NVIC_IRQChannelPreemptionPriority = PIOS_IRQ_PRIO_MID,
.NVIC_IRQChannelSubPriority = 0,
.NVIC_IRQChannelCmd = ENABLE,
}, },
}, },
.port = GPIOB, .remap = 0,
.pin = GPIO_Pin_11,
}; };
void PIOS_SUPV_irq_handler() {
if (RTC_GetITStatus(RTC_IT_SEC))
{
/* Call the right handler */
PIOS_SPEKTRUM_irq_handler(pios_usart_spektrum_id);
/* Wait until last write operation on RTC registers has finished */
RTC_WaitForLastTask();
/* Clear the RTC Second interrupt */
RTC_ClearITPendingBit(RTC_IT_SEC);
}
}
#endif /* PIOS_INCLUDE_SPEKTRUM */ #endif /* PIOS_INCLUDE_SPEKTRUM */
static uint32_t pios_usart_telem_rf_id; #if defined(PIOS_INCLUDE_SBUS)
void PIOS_USART_telem_irq_handler(void) /*
{ * SBUS USART
PIOS_USART_IRQ_Handler(pios_usart_telem_rf_id); */
} #include <pios_sbus_priv.h>
#if defined(PIOS_INCLUDE_GPS) static const struct pios_usart_cfg pios_usart_sbus_main_cfg = {
static uint32_t pios_usart_gps_id; .regs = USART1,
void PIOS_USART_gps_irq_handler(void) .init = {
{ .USART_BaudRate = 100000,
PIOS_USART_IRQ_Handler(pios_usart_gps_id); .USART_WordLength = USART_WordLength_8b,
} .USART_Parity = USART_Parity_Even,
#endif /* PIOS_INCLUDE_GPS */ .USART_StopBits = USART_StopBits_2,
.USART_HardwareFlowControl = USART_HardwareFlowControl_None,
.USART_Mode = USART_Mode_Rx,
},
.irq = {
.handler = PIOS_SBUS_irq_handler,
.init = {
.NVIC_IRQChannel = USART1_IRQn,
.NVIC_IRQChannelPreemptionPriority = PIOS_IRQ_PRIO_HIGH,
.NVIC_IRQChannelSubPriority = 0,
.NVIC_IRQChannelCmd = ENABLE,
},
},
.rx = {
.gpio = GPIOA,
.init = {
.GPIO_Pin = GPIO_Pin_10,
.GPIO_Speed = GPIO_Speed_2MHz,
.GPIO_Mode = GPIO_Mode_IPU,
},
},
.tx = {
.gpio = GPIOA,
.init = {
.GPIO_Pin = GPIO_Pin_9,
.GPIO_Speed = GPIO_Speed_2MHz,
.GPIO_Mode = GPIO_Mode_IN_FLOATING,
},
},
};
#endif /* PIOS_INCLUDE_USART */ static const struct pios_sbus_cfg pios_sbus_cfg = {
/* Inverter configuration */
.inv = {
.gpio = GPIOB,
.init = {
.GPIO_Pin = GPIO_Pin_2,
.GPIO_Mode = GPIO_Mode_Out_PP,
.GPIO_Speed = GPIO_Speed_2MHz,
},
},
.gpio_clk_func = RCC_APB2PeriphClockCmd,
.gpio_clk_periph = RCC_APB2Periph_GPIOB,
.gpio_inv_enable = Bit_SET,
};
#endif /* PIOS_INCLUDE_SBUS */
#endif /* PIOS_INCLUDE_USART */
#if defined(PIOS_INCLUDE_COM) #if defined(PIOS_INCLUDE_COM)
@ -405,11 +533,40 @@ void PIOS_USART_gps_irq_handler(void)
#endif /* PIOS_INCLUDE_COM */ #endif /* PIOS_INCLUDE_COM */
#if defined(PIOS_INCLUDE_RTC)
/*
* Realtime Clock (RTC)
*/
#include <pios_rtc_priv.h>
void PIOS_RTC_IRQ_Handler (void);
void RTC_IRQHandler() __attribute__ ((alias ("PIOS_RTC_IRQ_Handler")));
static const struct pios_rtc_cfg pios_rtc_main_cfg = {
.clksrc = RCC_RTCCLKSource_HSE_Div128,
.prescaler = 100,
.irq = {
.handler = NULL,
.init = {
.NVIC_IRQChannel = RTC_IRQn,
.NVIC_IRQChannelPreemptionPriority = PIOS_IRQ_PRIO_MID,
.NVIC_IRQChannelSubPriority = 0,
.NVIC_IRQChannelCmd = ENABLE,
},
},
};
void PIOS_RTC_IRQ_Handler (void)
{
PIOS_RTC_irq_handler ();
}
#endif
/* /*
* Servo outputs * Servo outputs
*/ */
#include <pios_servo_priv.h> #include <pios_servo_priv.h>
const struct pios_servo_channel pios_servo_channels[] = { static const struct pios_servo_channel pios_servo_channels[] = {
{ {
.timer = TIM4, .timer = TIM4,
.port = GPIOB, .port = GPIOB,
@ -475,13 +632,65 @@ const struct pios_servo_cfg pios_servo_cfg = {
.num_channels = NELEMENTS(pios_servo_channels), .num_channels = NELEMENTS(pios_servo_channels),
}; };
#if defined(PIOS_INCLUDE_PWM) && defined(PIOS_INCLUDE_PPM)
#error Cannot define both PIOS_INCLUDE_PWM and PIOS_INCLUDE_PPM at the same time (yet)
#endif
/*
* PPM Inputs
*/
#if defined(PIOS_INCLUDE_PPM)
#include <pios_ppm_priv.h>
void TIM4_IRQHandler();
void TIM4_IRQHandler() __attribute__ ((alias ("PIOS_TIM4_irq_handler")));
const struct pios_ppm_cfg pios_ppm_cfg = {
.tim_base_init = {
.TIM_Prescaler = (PIOS_MASTER_CLOCK / 1000000) - 1, /* For 1 uS accuracy */
.TIM_ClockDivision = TIM_CKD_DIV1,
.TIM_CounterMode = TIM_CounterMode_Up,
.TIM_Period = 0xFFFF, /* shared timer, make sure init correctly in outputs */
.TIM_RepetitionCounter = 0x0000,
},
.tim_ic_init = {
.TIM_Channel = TIM_Channel_1,
.TIM_ICPolarity = TIM_ICPolarity_Rising,
.TIM_ICSelection = TIM_ICSelection_DirectTI,
.TIM_ICPrescaler = TIM_ICPSC_DIV1,
.TIM_ICFilter = 0x0,
},
.gpio_init = {
.GPIO_Pin = GPIO_Pin_6,
.GPIO_Mode = GPIO_Mode_IPD,
.GPIO_Speed = GPIO_Speed_2MHz,
},
.remap = 0,
.irq = {
.handler = TIM4_IRQHandler,
.init = {
.NVIC_IRQChannelPreemptionPriority = PIOS_IRQ_PRIO_MID,
.NVIC_IRQChannelSubPriority = 0,
.NVIC_IRQChannelCmd = ENABLE,
},
},
.timer = TIM4,
.port = GPIOB,
.ccr = TIM_IT_CC1,
};
void PIOS_TIM4_irq_handler()
{
PIOS_PPM_irq_handler();
}
#endif /* PIOS_INCLUDE_PPM */
/* /*
* PWM Inputs * PWM Inputs
*/ */
#if defined(PIOS_INCLUDE_PWM) #if defined(PIOS_INCLUDE_PWM)
#include <pios_pwm_priv.h> #include <pios_pwm_priv.h>
const struct pios_pwm_channel pios_pwm_channels[] = {
static const struct pios_pwm_channel pios_pwm_channels[] = {
{ {
.timer = TIM4, .timer = TIM4,
.port = GPIOB, .port = GPIOB,
@ -552,7 +761,7 @@ const struct pios_pwm_cfg pios_pwm_cfg = {
}, },
.remap = 0, .remap = 0,
.irq = { .irq = {
.handler = TIM2_IRQHandler, .handler = NULL,
.init = { .init = {
.NVIC_IRQChannelPreemptionPriority = PIOS_IRQ_PRIO_MID, .NVIC_IRQChannelPreemptionPriority = PIOS_IRQ_PRIO_MID,
.NVIC_IRQChannelSubPriority = 0, .NVIC_IRQChannelSubPriority = 0,
@ -589,7 +798,7 @@ void PIOS_I2C_main_adapter_er_irq_handler(void);
void I2C2_EV_IRQHandler() __attribute__ ((alias ("PIOS_I2C_main_adapter_ev_irq_handler"))); void I2C2_EV_IRQHandler() __attribute__ ((alias ("PIOS_I2C_main_adapter_ev_irq_handler")));
void I2C2_ER_IRQHandler() __attribute__ ((alias ("PIOS_I2C_main_adapter_er_irq_handler"))); void I2C2_ER_IRQHandler() __attribute__ ((alias ("PIOS_I2C_main_adapter_er_irq_handler")));
const struct pios_i2c_adapter_cfg pios_i2c_main_adapter_cfg = { static const struct pios_i2c_adapter_cfg pios_i2c_main_adapter_cfg = {
.regs = I2C2, .regs = I2C2,
.init = { .init = {
.I2C_Mode = I2C_Mode_I2C, .I2C_Mode = I2C_Mode_I2C,
@ -617,7 +826,7 @@ const struct pios_i2c_adapter_cfg pios_i2c_main_adapter_cfg = {
}, },
}, },
.event = { .event = {
.handler = PIOS_I2C_main_adapter_ev_irq_handler, .handler = NULL,
.flags = 0, /* FIXME: check this */ .flags = 0, /* FIXME: check this */
.init = { .init = {
.NVIC_IRQChannel = I2C2_EV_IRQn, .NVIC_IRQChannel = I2C2_EV_IRQn,
@ -627,7 +836,7 @@ const struct pios_i2c_adapter_cfg pios_i2c_main_adapter_cfg = {
}, },
}, },
.error = { .error = {
.handler = PIOS_I2C_main_adapter_er_irq_handler, .handler = NULL,
.flags = 0, /* FIXME: check this */ .flags = 0, /* FIXME: check this */
.init = { .init = {
.NVIC_IRQChannel = I2C2_ER_IRQn, .NVIC_IRQChannel = I2C2_ER_IRQn,
@ -653,12 +862,18 @@ 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;
uint32_t pios_com_telem_usb_id; uint32_t pios_com_telem_usb_id;
uint32_t pios_com_gps_id; uint32_t pios_com_gps_id;
uint32_t pios_com_spektrum_id;
/** /**
* PIOS_Board_Init() * PIOS_Board_Init()
@ -668,57 +883,220 @@ uint32_t pios_com_spektrum_id;
void PIOS_Board_Init(void) { void PIOS_Board_Init(void) {
/* Delay system */ /* Delay system */
PIOS_DELAY_Init(); PIOS_DELAY_Init();
/* Set up the SPI interface to the serial flash */ /* Set up the SPI interface to the serial flash */
if (PIOS_SPI_Init(&pios_spi_flash_accel_id, &pios_spi_flash_accel_cfg)) { if (PIOS_SPI_Init(&pios_spi_flash_accel_id, &pios_spi_flash_accel_cfg)) {
PIOS_DEBUG_Assert(0); PIOS_Assert(0);
} }
PIOS_Flash_W25X_Init(pios_spi_flash_accel_id); PIOS_Flash_W25X_Init(pios_spi_flash_accel_id);
PIOS_ADXL345_Attach(pios_spi_flash_accel_id); PIOS_ADXL345_Attach(pios_spi_flash_accel_id);
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();
UAVObjectsInitializeAll(); UAVObjectsInitializeAll();
#if defined(PIOS_INCLUDE_RTC)
/* Initialize the real-time clock and its associated tick */
PIOS_RTC_Init(&pios_rtc_main_cfg);
#endif
/* Initialize the alarms library */ /* Initialize the alarms library */
AlarmsInitialize(); AlarmsInitialize();
/* Initialize the task monitor library */ /* Initialize the task monitor library */
TaskMonitorInitialize(); TaskMonitorInitialize();
/* Initialize the PiOS library */ /* Configure the main IO port */
#if defined(PIOS_INCLUDE_COM) uint8_t hwsettings_cc_mainport;
if (PIOS_USART_Init(&pios_usart_telem_rf_id, &pios_usart_telem_cfg)) { HwSettingsCC_MainPortGet(&hwsettings_cc_mainport);
PIOS_DEBUG_Assert(0);
} switch (hwsettings_cc_mainport) {
if (PIOS_COM_Init(&pios_com_telem_rf_id, &pios_usart_com_driver, pios_usart_telem_rf_id)) { case HWSETTINGS_CC_MAINPORT_DISABLED:
PIOS_DEBUG_Assert(0); break;
} case HWSETTINGS_CC_MAINPORT_TELEMETRY:
#if defined(PIOS_INCLUDE_TELEMETRY_RF)
{
uint32_t pios_usart_telem_rf_id;
if (PIOS_USART_Init(&pios_usart_telem_rf_id, &pios_usart_telem_main_cfg)) {
PIOS_Assert(0);
}
if (PIOS_COM_Init(&pios_com_telem_rf_id, &pios_usart_com_driver, pios_usart_telem_rf_id)) {
PIOS_Assert(0);
}
}
#endif /* PIOS_INCLUDE_TELEMETRY_RF */
break;
case HWSETTINGS_CC_MAINPORT_SBUS:
#if defined(PIOS_INCLUDE_SBUS)
{
PIOS_SBUS_Init(&pios_sbus_cfg);
uint32_t pios_usart_sbus_id;
if (PIOS_USART_Init(&pios_usart_sbus_id, &pios_usart_sbus_main_cfg)) {
PIOS_Assert(0);
}
}
#endif /* PIOS_INCLUDE_SBUS */
break;
case HWSETTINGS_CC_MAINPORT_GPS:
#if defined(PIOS_INCLUDE_GPS) #if defined(PIOS_INCLUDE_GPS)
if (PIOS_USART_Init(&pios_usart_gps_id, &pios_usart_gps_cfg)) { {
PIOS_DEBUG_Assert(0); uint32_t pios_usart_gps_id;
} if (PIOS_USART_Init(&pios_usart_gps_id, &pios_usart_gps_main_cfg)) {
if (PIOS_COM_Init(&pios_com_gps_id, &pios_usart_com_driver, pios_usart_gps_id)) { PIOS_Assert(0);
PIOS_DEBUG_Assert(0); }
} if (PIOS_COM_Init(&pios_com_gps_id, &pios_usart_com_driver, pios_usart_gps_id)) {
PIOS_Assert(0);
}
}
#endif /* PIOS_INCLUDE_GPS */ #endif /* PIOS_INCLUDE_GPS */
#endif /* PIOS_INCLUDE_COM */ break;
case HWSETTINGS_CC_MAINPORT_SPEKTRUM:
#if defined(PIOS_INCLUDE_SPEKTRUM)
{
/* SPEKTRUM init must come before usart init since it may use Rx pin for bind */
PIOS_SPEKTRUM_Init(&pios_spektrum_main_cfg, false);
uint32_t pios_usart_spektrum_id;
if (PIOS_USART_Init(&pios_usart_spektrum_id, &pios_usart_spektrum_main_cfg)) {
PIOS_Assert(0);
}
}
#endif /* PIOS_INCLUDE_SPEKTRUM */
break;
case HWSETTINGS_CC_MAINPORT_COMAUX:
break;
}
/* Configure the flexi port */
uint8_t hwsettings_cc_flexiport;
HwSettingsCC_FlexiPortGet(&hwsettings_cc_flexiport);
switch (hwsettings_cc_flexiport) {
case HWSETTINGS_CC_FLEXIPORT_DISABLED:
break;
case HWSETTINGS_CC_FLEXIPORT_TELEMETRY:
#if defined(PIOS_INCLUDE_TELEMETRY_RF)
{
uint32_t pios_usart_telem_rf_id;
if (PIOS_USART_Init(&pios_usart_telem_rf_id, &pios_usart_telem_flexi_cfg)) {
PIOS_Assert(0);
}
if (PIOS_COM_Init(&pios_com_telem_rf_id, &pios_usart_com_driver, pios_usart_telem_rf_id)) {
PIOS_Assert(0);
}
}
#endif /* PIOS_INCLUDE_TELEMETRY_RF */
break;
case HWSETTINGS_CC_FLEXIPORT_GPS:
#if defined(PIOS_INCLUDE_GPS)
{
uint32_t pios_usart_gps_id;
if (PIOS_USART_Init(&pios_usart_gps_id, &pios_usart_gps_flexi_cfg)) {
PIOS_Assert(0);
}
if (PIOS_COM_Init(&pios_com_gps_id, &pios_usart_com_driver, pios_usart_gps_id)) {
PIOS_Assert(0);
}
}
#endif /* PIOS_INCLUDE_GPS */
break;
case HWSETTINGS_CC_FLEXIPORT_SPEKTRUM:
#if defined(PIOS_INCLUDE_SPEKTRUM)
{
/* SPEKTRUM init must come before usart init since it may use Rx pin for bind */
PIOS_SPEKTRUM_Init(&pios_spektrum_flexi_cfg, false);
uint32_t pios_usart_spektrum_id;
if (PIOS_USART_Init(&pios_usart_spektrum_id, &pios_usart_spektrum_flexi_cfg)) {
PIOS_Assert(0);
}
}
#endif /* PIOS_INCLUDE_SPEKTRUM */
break;
case HWSETTINGS_CC_FLEXIPORT_COMAUX:
break;
case HWSETTINGS_CC_FLEXIPORT_I2C:
#if defined(PIOS_INCLUDE_I2C)
{
if (PIOS_I2C_Init(&pios_i2c_main_adapter_id, &pios_i2c_main_adapter_cfg)) {
PIOS_Assert(0);
}
}
#endif /* PIOS_INCLUDE_I2C */
break;
}
/* Configure the selected receiver */
uint8_t manualcontrolsettings_inputmode;
ManualControlSettingsInputModeGet(&manualcontrolsettings_inputmode);
switch (manualcontrolsettings_inputmode) {
case MANUALCONTROLSETTINGS_INPUTMODE_PWM:
#if defined(PIOS_INCLUDE_PWM)
PIOS_PWM_Init();
for (uint8_t i = 0; i < PIOS_PWM_NUM_INPUTS && i < PIOS_RCVR_MAX_DEVS; 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_Assert(0);
}
}
#endif /* PIOS_INCLUDE_PWM */
break;
case MANUALCONTROLSETTINGS_INPUTMODE_PPM:
#if defined(PIOS_INCLUDE_PPM)
PIOS_PPM_Init();
for (uint8_t i = 0; i < PIOS_PPM_NUM_INPUTS && i < PIOS_RCVR_MAX_DEVS; 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_Assert(0);
}
}
#endif /* PIOS_INCLUDE_PPM */
break;
case MANUALCONTROLSETTINGS_INPUTMODE_SPEKTRUM:
#if defined(PIOS_INCLUDE_SPEKTRUM)
if (hwsettings_cc_mainport == HWSETTINGS_CC_MAINPORT_SPEKTRUM ||
hwsettings_cc_flexiport == HWSETTINGS_CC_FLEXIPORT_SPEKTRUM) {
for (uint8_t i = 0; i < PIOS_SPEKTRUM_NUM_INPUTS && i < PIOS_RCVR_MAX_DEVS; 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_Assert(0);
}
}
}
#endif /* PIOS_INCLUDE_SPEKTRUM */
break;
case MANUALCONTROLSETTINGS_INPUTMODE_SBUS:
#if defined(PIOS_INCLUDE_SBUS)
if (hwsettings_cc_mainport == HWSETTINGS_CC_MAINPORT_SBUS) {
for (uint8_t i = 0; i < SBUS_NUMBER_OF_CHANNELS && i < PIOS_RCVR_MAX_DEVS; 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_Assert(0);
}
}
}
#endif /* PIOS_INCLUDE_SBUS */
break;
}
/* Remap AFIO pin */ /* Remap AFIO pin */
GPIO_PinRemapConfig( GPIO_Remap_SWJ_NoJTRST, ENABLE); GPIO_PinRemapConfig( GPIO_Remap_SWJ_NoJTRST, ENABLE);
@ -727,26 +1105,15 @@ void PIOS_Board_Init(void) {
PIOS_ADC_Init(); PIOS_ADC_Init();
PIOS_GPIO_Init(); PIOS_GPIO_Init();
#if defined(PIOS_INCLUDE_PWM)
PIOS_PWM_Init();
#endif
#if defined(PIOS_INCLUDE_PPM)
PIOS_PPM_Init();
#endif
#if defined(PIOS_INCLUDE_USB_HID) #if defined(PIOS_INCLUDE_USB_HID)
PIOS_USB_HID_Init(0); PIOS_USB_HID_Init(0);
#if defined(PIOS_INCLUDE_COM) #if defined(PIOS_INCLUDE_COM)
if (PIOS_COM_Init(&pios_com_telem_usb_id, &pios_usb_com_driver, 0)) { if (PIOS_COM_Init(&pios_com_telem_usb_id, &pios_usb_com_driver, 0)) {
PIOS_DEBUG_Assert(0); PIOS_Assert(0);
} }
#endif /* PIOS_INCLUDE_COM */ #endif /* PIOS_INCLUDE_COM */
#endif #endif /* PIOS_INCLUDE_USB_HID */
#if defined(PIOS_INCLUDE_I2C)
if (PIOS_I2C_Init(&pios_i2c_main_adapter_id, &pios_i2c_main_adapter_cfg)) {
PIOS_DEBUG_Assert(0);
}
#endif /* PIOS_INCLUDE_I2C */
PIOS_IAP_Init(); PIOS_IAP_Init();
PIOS_WDG_Init(); PIOS_WDG_Init();
} }

View File

@ -61,7 +61,7 @@ static const struct pios_spi_cfg pios_spi_op_mag_cfg = {
.ahb_clk = RCC_AHBPeriph_DMA1, .ahb_clk = RCC_AHBPeriph_DMA1,
.irq = { .irq = {
.handler = PIOS_SPI_op_mag_irq_handler, .handler = NULL,
.flags = .flags =
(DMA1_FLAG_TC4 | DMA1_FLAG_TE4 | DMA1_FLAG_HT4 | (DMA1_FLAG_TC4 | DMA1_FLAG_TE4 | DMA1_FLAG_HT4 |
DMA1_FLAG_GL4), DMA1_FLAG_GL4),
@ -175,7 +175,7 @@ static const struct pios_spi_cfg pios_spi_accel_cfg = {
.ahb_clk = RCC_AHBPeriph_DMA1, .ahb_clk = RCC_AHBPeriph_DMA1,
.irq = { .irq = {
.handler = PIOS_SPI_accel_irq_handler, .handler = NULL,
.flags = (DMA1_FLAG_TC2 | DMA1_FLAG_TE2 | DMA1_FLAG_HT2 | DMA1_FLAG_GL2), .flags = (DMA1_FLAG_TC2 | DMA1_FLAG_TE2 | DMA1_FLAG_HT2 | DMA1_FLAG_GL2),
.init = { .init = {
.NVIC_IRQChannel = DMA1_Channel2_IRQn, .NVIC_IRQChannel = DMA1_Channel2_IRQn,
@ -265,17 +265,10 @@ void PIOS_SPI_accel_irq_handler(void)
/* /*
* GPS USART * GPS USART
*/ */
void PIOS_USART_gps_irq_handler(void); static const struct pios_usart_cfg pios_usart_gps_cfg = {
void USART1_IRQHandler()
__attribute__ ((alias("PIOS_USART_gps_irq_handler")));
const struct pios_usart_cfg pios_usart_gps_cfg = {
.regs = USART1, .regs = USART1,
.init = { .init = {
#if defined (PIOS_USART_BAUDRATE)
.USART_BaudRate = PIOS_USART_BAUDRATE,
#else
.USART_BaudRate = 57600, .USART_BaudRate = 57600,
#endif
.USART_WordLength = USART_WordLength_8b, .USART_WordLength = USART_WordLength_8b,
.USART_Parity = USART_Parity_No, .USART_Parity = USART_Parity_No,
.USART_StopBits = USART_StopBits_1, .USART_StopBits = USART_StopBits_1,
@ -284,7 +277,7 @@ const struct pios_usart_cfg pios_usart_gps_cfg = {
.USART_Mode = USART_Mode_Rx | USART_Mode_Tx, .USART_Mode = USART_Mode_Rx | USART_Mode_Tx,
}, },
.irq = { .irq = {
.handler = PIOS_USART_gps_irq_handler, .handler = NULL,
.init = { .init = {
.NVIC_IRQChannel = USART1_IRQn, .NVIC_IRQChannel = USART1_IRQn,
.NVIC_IRQChannelPreemptionPriority = PIOS_IRQ_PRIO_MID, .NVIC_IRQChannelPreemptionPriority = PIOS_IRQ_PRIO_MID,
@ -310,29 +303,16 @@ const struct pios_usart_cfg pios_usart_gps_cfg = {
}, },
}; };
static uint32_t pios_usart_gps_id;
void PIOS_USART_gps_irq_handler(void)
{
PIOS_USART_IRQ_Handler(pios_usart_gps_id);
}
#endif /* PIOS_INCLUDE_GPS */ #endif /* PIOS_INCLUDE_GPS */
#ifdef PIOS_COM_AUX #ifdef PIOS_COM_AUX
/* /*
* AUX USART * AUX USART
*/ */
void PIOS_USART_aux_irq_handler(void); static const struct pios_usart_cfg pios_usart_aux_cfg = {
void USART4_IRQHandler()
__attribute__ ((alias("PIOS_USART_aux_irq_handler")));
const struct pios_usart_cfg pios_usart_aux_cfg = {
.regs = USART4, .regs = USART4,
.init = { .init = {
#if defined (PIOS_USART_BAUDRATE)
.USART_BaudRate = PIOS_USART_BAUDRATE,
#else
.USART_BaudRate = 57600, .USART_BaudRate = 57600,
#endif
.USART_WordLength = USART_WordLength_8b, .USART_WordLength = USART_WordLength_8b,
.USART_Parity = USART_Parity_No, .USART_Parity = USART_Parity_No,
.USART_StopBits = USART_StopBits_1, .USART_StopBits = USART_StopBits_1,
@ -341,7 +321,7 @@ const struct pios_usart_cfg pios_usart_aux_cfg = {
.USART_Mode = USART_Mode_Rx | USART_Mode_Tx, .USART_Mode = USART_Mode_Rx | USART_Mode_Tx,
}, },
.irq = { .irq = {
.handler = PIOS_USART_aux_irq_handler, .handler = NULL,
.init = { .init = {
.NVIC_IRQChannel = USART4_IRQn, .NVIC_IRQChannel = USART4_IRQn,
.NVIC_IRQChannelPreemptionPriority = PIOS_IRQ_PRIO_HIGH, .NVIC_IRQChannelPreemptionPriority = PIOS_IRQ_PRIO_HIGH,
@ -367,12 +347,6 @@ const struct pios_usart_cfg pios_usart_aux_cfg = {
}, },
}; };
static uint32_t pios_usart_aux_id;
void PIOS_USART_aux_irq_handler(void)
{
PIOS_USART_IRQ_Handler(pios_usart_aux_id);
}
#endif /* PIOS_COM_AUX */ #endif /* PIOS_COM_AUX */
@ -391,7 +365,7 @@ void I2C1_EV_IRQHandler()
void I2C1_ER_IRQHandler() void I2C1_ER_IRQHandler()
__attribute__ ((alias("PIOS_I2C_pres_mag_adapter_er_irq_handler"))); __attribute__ ((alias("PIOS_I2C_pres_mag_adapter_er_irq_handler")));
const struct pios_i2c_adapter_cfg pios_i2c_pres_mag_adapter_cfg = { static const struct pios_i2c_adapter_cfg pios_i2c_pres_mag_adapter_cfg = {
.regs = I2C1, .regs = I2C1,
.init = { .init = {
.I2C_Mode = I2C_Mode_I2C, .I2C_Mode = I2C_Mode_I2C,
@ -419,7 +393,7 @@ const struct pios_i2c_adapter_cfg pios_i2c_pres_mag_adapter_cfg = {
}, },
}, },
.event = { .event = {
.handler = PIOS_I2C_pres_mag_adapter_ev_irq_handler, .handler = NULL,
.flags = 0, /* FIXME: check this */ .flags = 0, /* FIXME: check this */
.init = { .init = {
.NVIC_IRQChannel = I2C1_EV_IRQn, .NVIC_IRQChannel = I2C1_EV_IRQn,
@ -429,7 +403,7 @@ const struct pios_i2c_adapter_cfg pios_i2c_pres_mag_adapter_cfg = {
}, },
}, },
.error = { .error = {
.handler = PIOS_I2C_pres_mag_adapter_er_irq_handler, .handler = NULL,
.flags = 0, /* FIXME: check this */ .flags = 0, /* FIXME: check this */
.init = { .init = {
.NVIC_IRQChannel = I2C1_ER_IRQn, .NVIC_IRQChannel = I2C1_ER_IRQn,
@ -459,7 +433,7 @@ void PIOS_I2C_gyro_adapter_er_irq_handler(void);
void I2C2_EV_IRQHandler() __attribute__ ((alias ("PIOS_I2C_gyro_adapter_ev_irq_handler"))); void I2C2_EV_IRQHandler() __attribute__ ((alias ("PIOS_I2C_gyro_adapter_ev_irq_handler")));
void I2C2_ER_IRQHandler() __attribute__ ((alias ("PIOS_I2C_gyro_adapter_er_irq_handler"))); void I2C2_ER_IRQHandler() __attribute__ ((alias ("PIOS_I2C_gyro_adapter_er_irq_handler")));
const struct pios_i2c_adapter_cfg pios_i2c_gyro_adapter_cfg = { static const struct pios_i2c_adapter_cfg pios_i2c_gyro_adapter_cfg = {
.regs = I2C2, .regs = I2C2,
.init = { .init = {
.I2C_Mode = I2C_Mode_I2C, .I2C_Mode = I2C_Mode_I2C,
@ -487,7 +461,7 @@ const struct pios_i2c_adapter_cfg pios_i2c_gyro_adapter_cfg = {
}, },
}, },
.event = { .event = {
.handler = PIOS_I2C_gyro_adapter_ev_irq_handler, .handler = NULL,
.flags = 0, /* FIXME: check this */ .flags = 0, /* FIXME: check this */
.init = { .init = {
.NVIC_IRQChannel = I2C2_EV_IRQn, .NVIC_IRQChannel = I2C2_EV_IRQn,
@ -497,7 +471,7 @@ const struct pios_i2c_adapter_cfg pios_i2c_gyro_adapter_cfg = {
}, },
}, },
.error = { .error = {
.handler = PIOS_I2C_gyro_adapter_er_irq_handler, .handler = NULL,
.flags = 0, /* FIXME: check this */ .flags = 0, /* FIXME: check this */
.init = { .init = {
.NVIC_IRQChannel = I2C2_ER_IRQn, .NVIC_IRQChannel = I2C2_ER_IRQn,
@ -547,6 +521,7 @@ void PIOS_Board_Init(void) {
#if defined(PIOS_INCLUDE_COM) #if defined(PIOS_INCLUDE_COM)
#if defined(PIOS_INCLUDE_GPS) #if defined(PIOS_INCLUDE_GPS)
uint32_t pios_usart_gps_id;
if (PIOS_USART_Init(&pios_usart_gps_id, &pios_usart_gps_cfg)) { if (PIOS_USART_Init(&pios_usart_gps_id, &pios_usart_gps_cfg)) {
PIOS_DEBUG_Assert(0); PIOS_DEBUG_Assert(0);
} }

View File

@ -1,628 +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
#endif if (settings.Roll >= MANUALCONTROLSETTINGS_ROLL_NONE ||
scaledChannel[n] = scaleChannel(cmd.Channel[n], settings.ChannelMax[n], settings.ChannelMin[n], settings.ChannelNeutral[n]); settings.Pitch >= MANUALCONTROLSETTINGS_PITCH_NONE ||
} settings.Yaw >= MANUALCONTROLSETTINGS_YAW_NONE ||
settings.Throttle >= MANUALCONTROLSETTINGS_THROTTLE_NONE ||
// Check settings, if error raise alarm settings.FlightMode >= MANUALCONTROLSETTINGS_FLIGHTMODE_NONE) {
if (settings.Roll >= MANUALCONTROLSETTINGS_ROLL_NONE || AlarmsSet(SYSTEMALARMS_ALARM_MANUALCONTROL, SYSTEMALARMS_ALARM_CRITICAL);
settings.Pitch >= MANUALCONTROLSETTINGS_PITCH_NONE || cmd.Connected = MANUALCONTROLCOMMAND_CONNECTED_FALSE;
settings.Yaw >= MANUALCONTROLSETTINGS_YAW_NONE || ManualControlCommandSet(&cmd);
settings.Throttle >= MANUALCONTROLSETTINGS_THROTTLE_NONE || continue;
settings.FlightMode >= MANUALCONTROLSETTINGS_FLIGHTMODE_NONE) { }
AlarmsSet(SYSTEMALARMS_ALARM_MANUALCONTROL, SYSTEMALARMS_ALARM_CRITICAL);
cmd.Connected = MANUALCONTROLCOMMAND_CONNECTED_FALSE; // decide if we have valid manual input or not
ManualControlCommandSet(&cmd); bool valid_input_detected = validInputRange(settings.ChannelMin[settings.Throttle], settings.ChannelMax[settings.Throttle], cmd.Channel[settings.Throttle]) &&
continue; validInputRange(settings.ChannelMin[settings.Roll], settings.ChannelMax[settings.Roll], cmd.Channel[settings.Roll]) &&
} validInputRange(settings.ChannelMin[settings.Yaw], settings.ChannelMax[settings.Yaw], cmd.Channel[settings.Yaw]) &&
validInputRange(settings.ChannelMin[settings.Pitch], settings.ChannelMax[settings.Pitch], cmd.Channel[settings.Pitch]);
// decide if we have valid manual input or not
bool valid_input_detected = validInputRange(settings.ChannelMin[settings.Throttle], settings.ChannelMax[settings.Throttle], cmd.Channel[settings.Throttle]) && // Implement hysteresis loop on connection status
validInputRange(settings.ChannelMin[settings.Roll], settings.ChannelMax[settings.Roll], cmd.Channel[settings.Roll]) && if (valid_input_detected && (++connected_count > 10)) {
validInputRange(settings.ChannelMin[settings.Yaw], settings.ChannelMax[settings.Yaw], cmd.Channel[settings.Yaw]) && cmd.Connected = MANUALCONTROLCOMMAND_CONNECTED_TRUE;
validInputRange(settings.ChannelMin[settings.Pitch], settings.ChannelMax[settings.Pitch], cmd.Channel[settings.Pitch]); connected_count = 0;
disconnected_count = 0;
// Implement hysteresis loop on connection status } else if (!valid_input_detected && (++disconnected_count > 10)) {
if (valid_input_detected && (++connected_count > 10)) { cmd.Connected = MANUALCONTROLCOMMAND_CONNECTED_FALSE;
cmd.Connected = MANUALCONTROLCOMMAND_CONNECTED_TRUE; connected_count = 0;
connected_count = 0; disconnected_count = 0;
disconnected_count = 0; }
} else if (!valid_input_detected && (++disconnected_count > 10)) {
cmd.Connected = MANUALCONTROLCOMMAND_CONNECTED_FALSE; if (cmd.Connected == MANUALCONTROLCOMMAND_CONNECTED_FALSE) {
connected_count = 0; cmd.Throttle = -1; // Shut down engine with no control
disconnected_count = 0; cmd.Roll = 0;
} cmd.Yaw = 0;
cmd.Pitch = 0;
if (cmd.Connected == MANUALCONTROLCOMMAND_CONNECTED_FALSE) { //cmd.FlightMode = MANUALCONTROLCOMMAND_FLIGHTMODE_AUTO; // don't do until AUTO implemented and functioning
cmd.Throttle = -1; // Shut down engine with no control // Important: Throttle < 0 will reset Stabilization coefficients among other things. Either change this,
cmd.Roll = 0; // or leave throttle at IDLE speed or above when going into AUTO-failsafe.
cmd.Yaw = 0; AlarmsSet(SYSTEMALARMS_ALARM_MANUALCONTROL, SYSTEMALARMS_ALARM_WARNING);
cmd.Pitch = 0; ManualControlCommandSet(&cmd);
//cmd.FlightMode = MANUALCONTROLCOMMAND_FLIGHTMODE_AUTO; // don't do until AUTO implemented and functioning } else {
// Important: Throttle < 0 will reset Stabilization coefficients among other things. Either change this, AlarmsClear(SYSTEMALARMS_ALARM_MANUALCONTROL);
// or leave throttle at IDLE speed or above when going into AUTO-failsafe.
AlarmsSet(SYSTEMALARMS_ALARM_MANUALCONTROL, SYSTEMALARMS_ALARM_WARNING); // Scale channels to -1 -> +1 range
ManualControlCommandSet(&cmd); cmd.Roll = scaledChannel[settings.Roll];
} else { cmd.Pitch = scaledChannel[settings.Pitch];
AlarmsClear(SYSTEMALARMS_ALARM_MANUALCONTROL); cmd.Yaw = scaledChannel[settings.Yaw];
cmd.Throttle = scaledChannel[settings.Throttle];
// Scale channels to -1 -> +1 range flightMode = scaledChannel[settings.FlightMode];
cmd.Roll = scaledChannel[settings.Roll];
cmd.Pitch = scaledChannel[settings.Pitch]; AccessoryDesiredData accessory;
cmd.Yaw = scaledChannel[settings.Yaw]; // Set Accessory 0
cmd.Throttle = scaledChannel[settings.Throttle]; if(settings.Accessory0 != MANUALCONTROLSETTINGS_ACCESSORY0_NONE) {
flightMode = scaledChannel[settings.FlightMode]; accessory.AccessoryVal = scaledChannel[settings.Accessory0];
if(AccessoryDesiredInstSet(0, &accessory) != 0)
AccessoryDesiredData accessory; AlarmsSet(SYSTEMALARMS_ALARM_MANUALCONTROL, SYSTEMALARMS_ALARM_WARNING);
// Set Accessory 0 }
if(settings.Accessory0 != MANUALCONTROLSETTINGS_ACCESSORY0_NONE) { // Set Accessory 1
accessory.AccessoryVal = scaledChannel[settings.Accessory0]; if(settings.Accessory1 != MANUALCONTROLSETTINGS_ACCESSORY1_NONE) {
if(AccessoryDesiredInstSet(0, &accessory) != 0) accessory.AccessoryVal = scaledChannel[settings.Accessory1];
AlarmsSet(SYSTEMALARMS_ALARM_MANUALCONTROL, SYSTEMALARMS_ALARM_WARNING); if(AccessoryDesiredInstSet(1, &accessory) != 0)
} AlarmsSet(SYSTEMALARMS_ALARM_MANUALCONTROL, SYSTEMALARMS_ALARM_WARNING);
// Set Accessory 1 }
if(settings.Accessory1 != MANUALCONTROLSETTINGS_ACCESSORY1_NONE) { // Set Accsesory 2
accessory.AccessoryVal = scaledChannel[settings.Accessory1]; if(settings.Accessory2 != MANUALCONTROLSETTINGS_ACCESSORY2_NONE) {
if(AccessoryDesiredInstSet(1, &accessory) != 0) accessory.AccessoryVal = scaledChannel[settings.Accessory2];
AlarmsSet(SYSTEMALARMS_ALARM_MANUALCONTROL, SYSTEMALARMS_ALARM_WARNING); if(AccessoryDesiredInstSet(2, &accessory) != 0)
} AlarmsSet(SYSTEMALARMS_ALARM_MANUALCONTROL, SYSTEMALARMS_ALARM_WARNING);
// Set Accsesory 2 }
if(settings.Accessory2 != MANUALCONTROLSETTINGS_ACCESSORY2_NONE) {
accessory.AccessoryVal = scaledChannel[settings.Accessory2];
if(AccessoryDesiredInstSet(2, &accessory) != 0) processFlightMode(&settings, flightMode);
AlarmsSet(SYSTEMALARMS_ALARM_MANUALCONTROL, SYSTEMALARMS_ALARM_WARNING); processArm(&cmd, &settings);
}
// Update cmd object
ManualControlCommandSet(&cmd);
processFlightMode(&settings, flightMode);
processArm(&cmd, &settings); }
// Update cmd object } else {
ManualControlCommandSet(&cmd); ManualControlCommandGet(&cmd); /* Under GCS control */
}
}
} else { FlightStatusGet(&flightStatus);
ManualControlCommandGet(&cmd); /* Under GCS control */
} // Depending on the mode update the Stabilization or Actuator objects
switch(PARSE_FLIGHT_MODE(flightStatus.FlightMode)) {
case FLIGHTMODE_UNDEFINED:
FlightStatusGet(&flightStatus); // This reflects a bug in the code architecture!
AlarmsSet(SYSTEMALARMS_ALARM_MANUALCONTROL, SYSTEMALARMS_ALARM_CRITICAL);
// Depending on the mode update the Stabilization or Actuator objects break;
switch(PARSE_FLIGHT_MODE(flightStatus.FlightMode)) { case FLIGHTMODE_MANUAL:
case FLIGHTMODE_UNDEFINED: updateActuatorDesired(&cmd);
// This reflects a bug in the code architecture! break;
AlarmsSet(SYSTEMALARMS_ALARM_MANUALCONTROL, SYSTEMALARMS_ALARM_CRITICAL); case FLIGHTMODE_STABILIZED:
break; updateStabilizationDesired(&cmd, &settings);
case FLIGHTMODE_MANUAL: break;
updateActuatorDesired(&cmd); case FLIGHTMODE_GUIDANCE:
break; // TODO: Implement
case FLIGHTMODE_STABILIZED: break;
updateStabilizationDesired(&cmd, &settings); }
break; }
case FLIGHTMODE_GUIDANCE: }
// TODO: Implement
break; static void updateActuatorDesired(ManualControlCommandData * cmd)
} {
} ActuatorDesiredData actuator;
} ActuatorDesiredGet(&actuator);
actuator.Roll = cmd->Roll;
static void updateActuatorDesired(ManualControlCommandData * cmd) actuator.Pitch = cmd->Pitch;
{ actuator.Yaw = cmd->Yaw;
ActuatorDesiredData actuator; actuator.Throttle = (cmd->Throttle < 0) ? -1 : cmd->Throttle;
ActuatorDesiredGet(&actuator); ActuatorDesiredSet(&actuator);
actuator.Roll = cmd->Roll; }
actuator.Pitch = cmd->Pitch;
actuator.Yaw = cmd->Yaw; static void updateStabilizationDesired(ManualControlCommandData * cmd, ManualControlSettingsData * settings)
actuator.Throttle = (cmd->Throttle < 0) ? -1 : cmd->Throttle; {
ActuatorDesiredSet(&actuator); StabilizationDesiredData stabilization;
} StabilizationDesiredGet(&stabilization);
static void updateStabilizationDesired(ManualControlCommandData * cmd, ManualControlSettingsData * settings) StabilizationSettingsData stabSettings;
{ StabilizationSettingsGet(&stabSettings);
StabilizationDesiredData stabilization;
StabilizationDesiredGet(&stabilization); uint8_t * stab_settings;
FlightStatusData flightStatus;
StabilizationSettingsData stabSettings; FlightStatusGet(&flightStatus);
StabilizationSettingsGet(&stabSettings); switch(flightStatus.FlightMode) {
case FLIGHTSTATUS_FLIGHTMODE_STABILIZED1:
uint8_t * stab_settings; stab_settings = settings->Stabilization1Settings;
FlightStatusData flightStatus; break;
FlightStatusGet(&flightStatus); case FLIGHTSTATUS_FLIGHTMODE_STABILIZED2:
switch(flightStatus.FlightMode) { stab_settings = settings->Stabilization2Settings;
case FLIGHTSTATUS_FLIGHTMODE_STABILIZED1: break;
stab_settings = settings->Stabilization1Settings; case FLIGHTSTATUS_FLIGHTMODE_STABILIZED3:
break; stab_settings = settings->Stabilization3Settings;
case FLIGHTSTATUS_FLIGHTMODE_STABILIZED2: break;
stab_settings = settings->Stabilization2Settings; default:
break; // Major error, this should not occur because only enter this block when one of these is true
case FLIGHTSTATUS_FLIGHTMODE_STABILIZED3: AlarmsSet(SYSTEMALARMS_ALARM_MANUALCONTROL, SYSTEMALARMS_ALARM_CRITICAL);
stab_settings = settings->Stabilization3Settings; return;
break; }
default:
// Major error, this should not occur because only enter this block when one of these is true // TOOD: Add assumption about order of stabilization desired and manual control stabilization mode fields having same order
AlarmsSet(SYSTEMALARMS_ALARM_MANUALCONTROL, SYSTEMALARMS_ALARM_CRITICAL); stabilization.StabilizationMode[STABILIZATIONDESIRED_STABILIZATIONMODE_ROLL] = stab_settings[0];
return; stabilization.StabilizationMode[STABILIZATIONDESIRED_STABILIZATIONMODE_PITCH] = stab_settings[1];
} stabilization.StabilizationMode[STABILIZATIONDESIRED_STABILIZATIONMODE_YAW] = stab_settings[2];
// TOOD: Add assumption about order of stabilization desired and manual control stabilization mode fields having same order stabilization.Roll = (stab_settings[0] == STABILIZATIONDESIRED_STABILIZATIONMODE_NONE) ? cmd->Roll :
stabilization.StabilizationMode[STABILIZATIONDESIRED_STABILIZATIONMODE_ROLL] = stab_settings[0]; (stab_settings[0] == STABILIZATIONDESIRED_STABILIZATIONMODE_RATE) ? cmd->Roll * stabSettings.ManualRate[STABILIZATIONSETTINGS_MANUALRATE_ROLL] :
stabilization.StabilizationMode[STABILIZATIONDESIRED_STABILIZATIONMODE_PITCH] = stab_settings[1]; (stab_settings[0] == STABILIZATIONDESIRED_STABILIZATIONMODE_ATTITUDE) ? cmd->Roll * stabSettings.RollMax :
stabilization.StabilizationMode[STABILIZATIONDESIRED_STABILIZATIONMODE_YAW] = stab_settings[2]; 0; // this is an invalid mode
;
stabilization.Roll = (stab_settings[0] == STABILIZATIONDESIRED_STABILIZATIONMODE_NONE) ? cmd->Roll : stabilization.Pitch = (stab_settings[1] == STABILIZATIONDESIRED_STABILIZATIONMODE_NONE) ? cmd->Pitch :
(stab_settings[0] == STABILIZATIONDESIRED_STABILIZATIONMODE_RATE) ? cmd->Roll * stabSettings.ManualRate[STABILIZATIONSETTINGS_MANUALRATE_ROLL] : (stab_settings[1] == STABILIZATIONDESIRED_STABILIZATIONMODE_RATE) ? cmd->Pitch * stabSettings.ManualRate[STABILIZATIONSETTINGS_MANUALRATE_PITCH] :
(stab_settings[0] == STABILIZATIONDESIRED_STABILIZATIONMODE_ATTITUDE) ? cmd->Roll * stabSettings.RollMax : (stab_settings[1] == STABILIZATIONDESIRED_STABILIZATIONMODE_ATTITUDE) ? cmd->Pitch * stabSettings.PitchMax :
0; // this is an invalid mode 0; // this is an invalid mode
;
stabilization.Pitch = (stab_settings[1] == STABILIZATIONDESIRED_STABILIZATIONMODE_NONE) ? cmd->Pitch : stabilization.Yaw = (stab_settings[2] == STABILIZATIONDESIRED_STABILIZATIONMODE_NONE) ? cmd->Yaw :
(stab_settings[1] == STABILIZATIONDESIRED_STABILIZATIONMODE_RATE) ? cmd->Pitch * stabSettings.ManualRate[STABILIZATIONSETTINGS_MANUALRATE_PITCH] : (stab_settings[2] == STABILIZATIONDESIRED_STABILIZATIONMODE_RATE) ? cmd->Yaw * stabSettings.ManualRate[STABILIZATIONSETTINGS_MANUALRATE_YAW] :
(stab_settings[1] == STABILIZATIONDESIRED_STABILIZATIONMODE_ATTITUDE) ? cmd->Pitch * stabSettings.PitchMax : (stab_settings[2] == STABILIZATIONDESIRED_STABILIZATIONMODE_ATTITUDE) ? fmod(cmd->Yaw * 180.0, 360) :
0; // this is an invalid mode 0; // this is an invalid mode
stabilization.Yaw = (stab_settings[2] == STABILIZATIONDESIRED_STABILIZATIONMODE_NONE) ? cmd->Yaw : stabilization.Throttle = (cmd->Throttle < 0) ? -1 : cmd->Throttle;
(stab_settings[2] == STABILIZATIONDESIRED_STABILIZATIONMODE_RATE) ? cmd->Yaw * stabSettings.ManualRate[STABILIZATIONSETTINGS_MANUALRATE_YAW] : StabilizationDesiredSet(&stabilization);
(stab_settings[2] == STABILIZATIONDESIRED_STABILIZATIONMODE_ATTITUDE) ? fmod(cmd->Yaw * 180.0, 360) : }
0; // this is an invalid mode
/**
stabilization.Throttle = (cmd->Throttle < 0) ? -1 : cmd->Throttle; * Convert channel from servo pulse duration (microseconds) to scaled -1/+1 range.
StabilizationDesiredSet(&stabilization); */
} static float scaleChannel(int16_t value, int16_t max, int16_t min, int16_t neutral)
{
/** float valueScaled;
* Convert channel from servo pulse duration (microseconds) to scaled -1/+1 range.
*/ // Scale
static float scaleChannel(int16_t value, int16_t max, int16_t min, int16_t neutral) if ((max > min && value >= neutral) || (min > max && value <= neutral))
{ {
float valueScaled; if (max != neutral)
valueScaled = (float)(value - neutral) / (float)(max - neutral);
// Scale else
if ((max > min && value >= neutral) || (min > max && value <= neutral)) valueScaled = 0;
{ }
if (max != neutral) else
valueScaled = (float)(value - neutral) / (float)(max - neutral); {
else if (min != neutral)
valueScaled = 0; valueScaled = (float)(value - neutral) / (float)(neutral - min);
} else
else valueScaled = 0;
{ }
if (min != neutral)
valueScaled = (float)(value - neutral) / (float)(neutral - min); // Bound
else if (valueScaled > 1.0) valueScaled = 1.0;
valueScaled = 0; else
} if (valueScaled < -1.0) valueScaled = -1.0;
// Bound return valueScaled;
if (valueScaled > 1.0) valueScaled = 1.0; }
else
if (valueScaled < -1.0) valueScaled = -1.0; static uint32_t timeDifferenceMs(portTickType start_time, portTickType end_time) {
if(end_time > start_time)
return valueScaled; return (end_time - start_time) * portTICK_RATE_MS;
} return ((((portTICK_RATE_MS) -1) - start_time) + end_time) * portTICK_RATE_MS;
}
static uint32_t timeDifferenceMs(portTickType start_time, portTickType end_time) {
if(end_time > start_time) /**
return (end_time - start_time) * portTICK_RATE_MS; * @brief Determine if the aircraft is safe to arm
return ((((portTICK_RATE_MS) -1) - start_time) + end_time) * portTICK_RATE_MS; * @returns True if safe to arm, false otherwise
} */
static bool okToArm(void)
/** {
* @brief Determine if the aircraft is safe to arm // read alarms
* @returns True if safe to arm, false otherwise SystemAlarmsData alarms;
*/ SystemAlarmsGet(&alarms);
static bool okToArm(void)
{
// read alarms // Check each alarm
SystemAlarmsData alarms; for (int i = 0; i < SYSTEMALARMS_ALARM_NUMELEM; i++)
SystemAlarmsGet(&alarms); {
if (alarms.Alarm[i] >= SYSTEMALARMS_ALARM_ERROR)
{ // found an alarm thats set
// Check each alarm if (i == SYSTEMALARMS_ALARM_GPS || i == SYSTEMALARMS_ALARM_TELEMETRY)
for (int i = 0; i < SYSTEMALARMS_ALARM_NUMELEM; i++) continue;
{
if (alarms.Alarm[i] >= SYSTEMALARMS_ALARM_ERROR) return false;
{ // found an alarm thats set }
if (i == SYSTEMALARMS_ALARM_GPS || i == SYSTEMALARMS_ALARM_TELEMETRY) }
continue;
return true;
return false; }
}
} /**
* @brief Update the flightStatus object only if value changed. Reduces callbacks
return true; * @param[in] val The new value
} */
static void setArmedIfChanged(uint8_t val) {
/** FlightStatusData flightStatus;
* @brief Update the flightStatus object only if value changed. Reduces callbacks FlightStatusGet(&flightStatus);
* @param[in] val The new value
*/ if(flightStatus.Armed != val) {
static void setArmedIfChanged(uint8_t val) { flightStatus.Armed = val;
FlightStatusData flightStatus; FlightStatusSet(&flightStatus);
FlightStatusGet(&flightStatus); }
}
if(flightStatus.Armed != val) {
flightStatus.Armed = val; /**
FlightStatusSet(&flightStatus); * @brief Process the inputs and determine whether to arm or not
} * @param[out] cmd The structure to set the armed in
} * @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 {
* @param[out] cmd The structure to set the armed in
* @param[in] settings Settings indicating the necessary position bool lowThrottle = cmd->Throttle <= 0;
*/
static void processArm(ManualControlCommandData * cmd, ManualControlSettingsData * settings) if (settings->Arming == MANUALCONTROLSETTINGS_ARMING_ALWAYSDISARMED) {
{ // In this configuration we always disarm
setArmedIfChanged(FLIGHTSTATUS_ARMED_DISARMED);
bool lowThrottle = cmd->Throttle <= 0; } else {
// Not really needed since this function not called when disconnected
if (settings->Arming == MANUALCONTROLSETTINGS_ARMING_ALWAYSDISARMED) { if (cmd->Connected == MANUALCONTROLCOMMAND_CONNECTED_FALSE)
// In this configuration we always disarm return;
setArmedIfChanged(FLIGHTSTATUS_ARMED_DISARMED);
} else { // The throttle is not low, in case we where arming or disarming, abort
// Not really needed since this function not called when disconnected if (!lowThrottle) {
if (cmd->Connected == MANUALCONTROLCOMMAND_CONNECTED_FALSE) switch(armState) {
return; case ARM_STATE_DISARMING_MANUAL:
case ARM_STATE_DISARMING_TIMEOUT:
// The throttle is not low, in case we where arming or disarming, abort armState = ARM_STATE_ARMED;
if (!lowThrottle) { break;
switch(armState) { case ARM_STATE_ARMING_MANUAL:
case ARM_STATE_DISARMING_MANUAL: armState = ARM_STATE_DISARMED;
case ARM_STATE_DISARMING_TIMEOUT: break;
armState = ARM_STATE_ARMED; default:
break; // Nothing needs to be done in the other states
case ARM_STATE_ARMING_MANUAL: break;
armState = ARM_STATE_DISARMED; }
break; return;
default: }
// Nothing needs to be done in the other states
break; // The rest of these cases throttle is low
} if (settings->Arming == MANUALCONTROLSETTINGS_ARMING_ALWAYSARMED) {
return; // In this configuration, we go into armed state as soon as the throttle is low, never disarm
} setArmedIfChanged(FLIGHTSTATUS_ARMED_ARMED);
return;
// The rest of these cases throttle is low }
if (settings->Arming == MANUALCONTROLSETTINGS_ARMING_ALWAYSARMED) {
// In this configuration, we go into armed state as soon as the throttle is low, never disarm
setArmedIfChanged(FLIGHTSTATUS_ARMED_ARMED); // When the configuration is not "Always armed" and no "Always disarmed",
return; // the state will not be changed when the throttle is not low
} static portTickType armedDisarmStart;
float armingInputLevel = 0;
// When the configuration is not "Always armed" and no "Always disarmed", // Calc channel see assumptions7
// the state will not be changed when the throttle is not low int8_t sign = ((settings->Arming-MANUALCONTROLSETTINGS_ARMING_ROLLLEFT)%2) ? -1 : 1;
static portTickType armedDisarmStart; switch ( (settings->Arming-MANUALCONTROLSETTINGS_ARMING_ROLLLEFT)/2 ) {
float armingInputLevel = 0; case ARMING_CHANNEL_ROLL: armingInputLevel = sign * cmd->Roll; break;
case ARMING_CHANNEL_PITCH: armingInputLevel = sign * cmd->Pitch; break;
// Calc channel see assumptions7 case ARMING_CHANNEL_YAW: armingInputLevel = sign * cmd->Yaw; break;
int8_t sign = ((settings->Arming-MANUALCONTROLSETTINGS_ARMING_ROLLLEFT)%2) ? -1 : 1; }
switch ( (settings->Arming-MANUALCONTROLSETTINGS_ARMING_ROLLLEFT)/2 ) {
case ARMING_CHANNEL_ROLL: armingInputLevel = sign * cmd->Roll; break; bool manualArm = false;
case ARMING_CHANNEL_PITCH: armingInputLevel = sign * cmd->Pitch; break; bool manualDisarm = false;
case ARMING_CHANNEL_YAW: armingInputLevel = sign * cmd->Yaw; break;
} if (armingInputLevel <= -ARMED_THRESHOLD)
manualArm = true;
bool manualArm = false; else if (armingInputLevel >= +ARMED_THRESHOLD)
bool manualDisarm = false; manualDisarm = true;
if (armingInputLevel <= -ARMED_THRESHOLD) switch(armState) {
manualArm = true; case ARM_STATE_DISARMED:
else if (armingInputLevel >= +ARMED_THRESHOLD) setArmedIfChanged(FLIGHTSTATUS_ARMED_DISARMED);
manualDisarm = true;
// only allow arming if it's OK too
switch(armState) { if (manualArm && okToArm()) {
case ARM_STATE_DISARMED: armedDisarmStart = lastSysTime;
setArmedIfChanged(FLIGHTSTATUS_ARMED_DISARMED); armState = ARM_STATE_ARMING_MANUAL;
}
// only allow arming if it's OK too break;
if (manualArm && okToArm()) {
armedDisarmStart = lastSysTime; case ARM_STATE_ARMING_MANUAL:
armState = ARM_STATE_ARMING_MANUAL; setArmedIfChanged(FLIGHTSTATUS_ARMED_ARMING);
}
break; if (manualArm && (timeDifferenceMs(armedDisarmStart, lastSysTime) > ARMED_TIME_MS))
armState = ARM_STATE_ARMED;
case ARM_STATE_ARMING_MANUAL: else if (!manualArm)
setArmedIfChanged(FLIGHTSTATUS_ARMED_ARMING); armState = ARM_STATE_DISARMED;
break;
if (manualArm && (timeDifferenceMs(armedDisarmStart, lastSysTime) > ARMED_TIME_MS))
armState = ARM_STATE_ARMED; case ARM_STATE_ARMED:
else if (!manualArm) // When we get here, the throttle is low,
armState = ARM_STATE_DISARMED; // we go immediately to disarming due to timeout, also when the disarming mechanism is not enabled
break; armedDisarmStart = lastSysTime;
armState = ARM_STATE_DISARMING_TIMEOUT;
case ARM_STATE_ARMED: setArmedIfChanged(FLIGHTSTATUS_ARMED_ARMED);
// When we get here, the throttle is low, break;
// we go immediately to disarming due to timeout, also when the disarming mechanism is not enabled
armedDisarmStart = lastSysTime; case ARM_STATE_DISARMING_TIMEOUT:
armState = ARM_STATE_DISARMING_TIMEOUT; // We get here when armed while throttle low, even when the arming timeout is not enabled
setArmedIfChanged(FLIGHTSTATUS_ARMED_ARMED); if ((settings->ArmedTimeout != 0) && (timeDifferenceMs(armedDisarmStart, lastSysTime) > settings->ArmedTimeout))
break; armState = ARM_STATE_DISARMED;
case ARM_STATE_DISARMING_TIMEOUT: // Switch to disarming due to manual control when needed
// We get here when armed while throttle low, even when the arming timeout is not enabled if (manualDisarm) {
if ((settings->ArmedTimeout != 0) && (timeDifferenceMs(armedDisarmStart, lastSysTime) > settings->ArmedTimeout)) armedDisarmStart = lastSysTime;
armState = ARM_STATE_DISARMED; armState = ARM_STATE_DISARMING_MANUAL;
}
// Switch to disarming due to manual control when needed break;
if (manualDisarm) {
armedDisarmStart = lastSysTime; case ARM_STATE_DISARMING_MANUAL:
armState = ARM_STATE_DISARMING_MANUAL; if (manualDisarm &&(timeDifferenceMs(armedDisarmStart, lastSysTime) > ARMED_TIME_MS))
} armState = ARM_STATE_DISARMED;
break; else if (!manualDisarm)
armState = ARM_STATE_ARMED;
case ARM_STATE_DISARMING_MANUAL: break;
if (manualDisarm &&(timeDifferenceMs(armedDisarmStart, lastSysTime) > ARMED_TIME_MS)) } // End Switch
armState = ARM_STATE_DISARMED; }
else if (!manualDisarm) }
armState = ARM_STATE_ARMED;
break; /**
} // End Switch * @brief Determine which of three positions the flight mode switch is in and set flight mode accordingly
} * @param[out] cmd Pointer to the command structure to set the flight mode in
} * @param[in] settings The settings which indicate which position is which mode
* @param[in] flightMode the value of the switch position
/** */
* @brief Determine which of three positions the flight mode switch is in and set flight mode accordingly static void processFlightMode(ManualControlSettingsData * settings, float flightMode)
* @param[out] cmd Pointer to the command structure to set the flight mode in {
* @param[in] settings The settings which indicate which position is which mode FlightStatusData flightStatus;
* @param[in] flightMode the value of the switch position FlightStatusGet(&flightStatus);
*/
static void processFlightMode(ManualControlSettingsData * settings, float flightMode) uint8_t newMode;
{ // Note here the code is ass
FlightStatusData flightStatus; if (flightMode < -FLIGHT_MODE_LIMIT)
FlightStatusGet(&flightStatus); newMode = settings->FlightModePosition[0];
else if (flightMode > FLIGHT_MODE_LIMIT)
uint8_t newMode; newMode = settings->FlightModePosition[2];
// Note here the code is ass else
if (flightMode < -FLIGHT_MODE_LIMIT) newMode = settings->FlightModePosition[1];
newMode = settings->FlightModePosition[0];
else if (flightMode > FLIGHT_MODE_LIMIT) if(flightStatus.FlightMode != newMode) {
newMode = settings->FlightModePosition[2]; flightStatus.FlightMode = newMode;
else FlightStatusSet(&flightStatus);
newMode = settings->FlightModePosition[1]; }
if(flightStatus.FlightMode != newMode) { }
flightStatus.FlightMode = newMode;
FlightStatusSet(&flightStatus); /**
} * @brief Determine if the manual input value is within acceptable limits
* @returns return TRUE if so, otherwise return FALSE
} */
bool validInputRange(int16_t min, int16_t max, uint16_t value)
/** {
* @brief Determine if the manual input value is within acceptable limits if (min > max)
* @returns return TRUE if so, otherwise return FALSE {
*/ int16_t tmp = min;
bool validInputRange(int16_t min, int16_t max, uint16_t value) min = max;
{ max = tmp;
if (min > max) }
{ return (value >= min - CONNECTION_OFFSET && value <= max + CONNECTION_OFFSET);
int16_t tmp = min; }
min = max;
max = tmp; /**
} * @}
return (value >= min - CONNECTION_OFFSET && value <= max + CONNECTION_OFFSET); * @}
} */
/**
* @}
* @}
*/

View File

@ -43,9 +43,6 @@ ENABLE_DEBUG_PINS ?= NO
# Set to Yes to enable the AUX UART which is mapped on the S1 (Tx) and S2 (Rx) servo outputs # Set to Yes to enable the AUX UART which is mapped on the S1 (Tx) and S2 (Rx) servo outputs
ENABLE_AUX_UART ?= NO ENABLE_AUX_UART ?= NO
USE_SPEKTRUM ?= NO
# Set to YES when using Code Sourcery toolchain # Set to YES when using Code Sourcery toolchain
CODE_SOURCERY ?= YES CODE_SOURCERY ?= YES
@ -170,6 +167,7 @@ SRC += $(PIOSSTM32F10X)/pios_spi.c
SRC += $(PIOSSTM32F10X)/pios_ppm.c SRC += $(PIOSSTM32F10X)/pios_ppm.c
SRC += $(PIOSSTM32F10X)/pios_pwm.c SRC += $(PIOSSTM32F10X)/pios_pwm.c
SRC += $(PIOSSTM32F10X)/pios_spektrum.c SRC += $(PIOSSTM32F10X)/pios_spektrum.c
SRC += $(PIOSSTM32F10X)/pios_sbus.c
SRC += $(PIOSSTM32F10X)/pios_debug.c SRC += $(PIOSSTM32F10X)/pios_debug.c
SRC += $(PIOSSTM32F10X)/pios_gpio.c SRC += $(PIOSSTM32F10X)/pios_gpio.c
SRC += $(PIOSSTM32F10X)/pios_exti.c SRC += $(PIOSSTM32F10X)/pios_exti.c
@ -194,6 +192,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
@ -363,11 +362,6 @@ ifeq ($(ENABLE_AUX_UART), YES)
CDEFS += -DPIOS_ENABLE_AUX_UART CDEFS += -DPIOS_ENABLE_AUX_UART
endif endif
ifeq ($(USE_SPEKTRUM), YES)
CDEFS += -DUSE_SPEKTRUM
endif
# Place project-specific -D and/or -U options for # Place project-specific -D and/or -U options for
# Assembler with preprocessor here. # Assembler with preprocessor here.
#ADEFS = -DUSE_IRQ_ASM_WRAPPER #ADEFS = -DUSE_IRQ_ASM_WRAPPER

View File

@ -42,12 +42,12 @@
#define PIOS_INCLUDE_IRQ #define PIOS_INCLUDE_IRQ
#define PIOS_INCLUDE_LED #define PIOS_INCLUDE_LED
#if defined(USE_SPEKTRUM) #define PIOS_INCLUDE_RCVR
#define PIOS_INCLUDE_SPEKTRUM #define PIOS_INCLUDE_SPEKTRUM
#else //#define PIOS_INCLUDE_SBUS
//#define PIOS_INCLUDE_PPM
#define PIOS_INCLUDE_PWM #define PIOS_INCLUDE_PWM
#endif //#define PIOS_INCLUDE_PPM
#define PIOS_INCLUDE_SERVO #define PIOS_INCLUDE_SERVO
#define PIOS_INCLUDE_SPI #define PIOS_INCLUDE_SPI

View File

@ -153,6 +153,9 @@ static void TaskTesting(void *pvParameters)
#if defined(PIOS_INCLUDE_SPEKTRUM) #if defined(PIOS_INCLUDE_SPEKTRUM)
PIOS_COM_SendFormattedStringNonBlocking(COM_DEBUG_USART, "%u,%u,%u,%u,%u,%u,%u,%u\r", PIOS_SPEKTRUM_Get(0), PIOS_SPEKTRUM_Get(1), PIOS_SPEKTRUM_Get(2), PIOS_SPEKTRUM_Get(3), PIOS_SPEKTRUM_Get(4), PIOS_SPEKTRUM_Get(5), PIOS_SPEKTRUM_Get(6), PIOS_SPEKTRUM_Get(7)); PIOS_COM_SendFormattedStringNonBlocking(COM_DEBUG_USART, "%u,%u,%u,%u,%u,%u,%u,%u\r", PIOS_SPEKTRUM_Get(0), PIOS_SPEKTRUM_Get(1), PIOS_SPEKTRUM_Get(2), PIOS_SPEKTRUM_Get(3), PIOS_SPEKTRUM_Get(4), PIOS_SPEKTRUM_Get(5), PIOS_SPEKTRUM_Get(6), PIOS_SPEKTRUM_Get(7));
#endif #endif
#if defined(PIOS_INCLUDE_SBUS)
PIOS_COM_SendFormattedStringNonBlocking(COM_DEBUG_USART, "%u,%u,%u,%u,%u,%u,%u,%u\r", PIOS_SBUS_Get(0), PIOS_SBUS_Get(1), PIOS_SBUS_Get(2), PIOS_SBUS_Get(3), PIOS_SBUS_Get(4), PIOS_SBUS_Get(5), PIOS_SBUS_Get(6), PIOS_SBUS_Get(7));
#endif
#if defined(PIOS_INCLUDE_PWM) #if defined(PIOS_INCLUDE_PWM)
PIOS_COM_SendFormattedStringNonBlocking(COM_DEBUG_USART, "%u,%u,%u,%u,%u,%u,%u,%u uS\r", PIOS_PWM_Get(0), PIOS_PWM_Get(1), PIOS_PWM_Get(2), PIOS_PWM_Get(3), PIOS_PWM_Get(4), PIOS_PWM_Get(5), PIOS_PWM_Get(6), PIOS_PWM_Get(7)); PIOS_COM_SendFormattedStringNonBlocking(COM_DEBUG_USART, "%u,%u,%u,%u,%u,%u,%u,%u uS\r", PIOS_PWM_Get(0), PIOS_PWM_Get(1), PIOS_PWM_Get(2), PIOS_PWM_Get(3), PIOS_PWM_Get(4), PIOS_PWM_Get(5), PIOS_PWM_Get(6), PIOS_PWM_Get(7));
#endif #endif

View File

@ -46,7 +46,7 @@
void PIOS_SPI_sdcard_irq_handler(void); void PIOS_SPI_sdcard_irq_handler(void);
void DMA1_Channel2_IRQHandler() __attribute__ ((alias ("PIOS_SPI_sdcard_irq_handler"))); void DMA1_Channel2_IRQHandler() __attribute__ ((alias ("PIOS_SPI_sdcard_irq_handler")));
void DMA1_Channel3_IRQHandler() __attribute__ ((alias ("PIOS_SPI_sdcard_irq_handler"))); void DMA1_Channel3_IRQHandler() __attribute__ ((alias ("PIOS_SPI_sdcard_irq_handler")));
const struct pios_spi_cfg pios_spi_sdcard_cfg = { static const struct pios_spi_cfg pios_spi_sdcard_cfg = {
.regs = SPI1, .regs = SPI1,
.init = { .init = {
.SPI_Mode = SPI_Mode_Master, .SPI_Mode = SPI_Mode_Master,
@ -63,7 +63,7 @@ const struct pios_spi_cfg pios_spi_sdcard_cfg = {
.ahb_clk = RCC_AHBPeriph_DMA1, .ahb_clk = RCC_AHBPeriph_DMA1,
.irq = { .irq = {
.handler = PIOS_SPI_sdcard_irq_handler, .handler = NULL,
.flags = (DMA1_FLAG_TC2 | DMA1_FLAG_TE2 | DMA1_FLAG_HT2 | DMA1_FLAG_GL2), .flags = (DMA1_FLAG_TC2 | DMA1_FLAG_TE2 | DMA1_FLAG_HT2 | DMA1_FLAG_GL2),
.init = { .init = {
.NVIC_IRQChannel = DMA1_Channel2_IRQn, .NVIC_IRQChannel = DMA1_Channel2_IRQn,
@ -144,7 +144,7 @@ const struct pios_spi_cfg pios_spi_sdcard_cfg = {
void PIOS_SPI_ahrs_irq_handler(void); void PIOS_SPI_ahrs_irq_handler(void);
void DMA1_Channel4_IRQHandler() __attribute__ ((alias ("PIOS_SPI_ahrs_irq_handler"))); void DMA1_Channel4_IRQHandler() __attribute__ ((alias ("PIOS_SPI_ahrs_irq_handler")));
void DMA1_Channel5_IRQHandler() __attribute__ ((alias ("PIOS_SPI_ahrs_irq_handler"))); void DMA1_Channel5_IRQHandler() __attribute__ ((alias ("PIOS_SPI_ahrs_irq_handler")));
const struct pios_spi_cfg pios_spi_ahrs_cfg = { static const struct pios_spi_cfg pios_spi_ahrs_cfg = {
.regs = SPI2, .regs = SPI2,
.init = { .init = {
.SPI_Mode = SPI_Mode_Master, .SPI_Mode = SPI_Mode_Master,
@ -162,7 +162,7 @@ const struct pios_spi_cfg pios_spi_ahrs_cfg = {
.ahb_clk = RCC_AHBPeriph_DMA1, .ahb_clk = RCC_AHBPeriph_DMA1,
.irq = { .irq = {
.handler = PIOS_SPI_ahrs_irq_handler, .handler = NULL,
.flags = (DMA1_FLAG_TC4 | DMA1_FLAG_TE4 | DMA1_FLAG_HT4 | DMA1_FLAG_GL4), .flags = (DMA1_FLAG_TC4 | DMA1_FLAG_TE4 | DMA1_FLAG_HT4 | DMA1_FLAG_GL4),
.init = { .init = {
.NVIC_IRQChannel = DMA1_Channel4_IRQn, .NVIC_IRQChannel = DMA1_Channel4_IRQn,
@ -258,11 +258,11 @@ void PIOS_SPI_ahrs_irq_handler(void)
extern void PIOS_ADC_handler(void); extern void PIOS_ADC_handler(void);
void DMA1_Channel1_IRQHandler() __attribute__ ((alias("PIOS_ADC_handler"))); void DMA1_Channel1_IRQHandler() __attribute__ ((alias("PIOS_ADC_handler")));
// Remap the ADC DMA handler to this one // Remap the ADC DMA handler to this one
const struct pios_adc_cfg pios_adc_cfg = { static const struct pios_adc_cfg pios_adc_cfg = {
.dma = { .dma = {
.ahb_clk = RCC_AHBPeriph_DMA1, .ahb_clk = RCC_AHBPeriph_DMA1,
.irq = { .irq = {
.handler = PIOS_ADC_DMA_Handler, .handler = NULL,
.flags = (DMA1_FLAG_TC1 | DMA1_FLAG_TE1 | DMA1_FLAG_HT1 | DMA1_FLAG_GL1), .flags = (DMA1_FLAG_TC1 | DMA1_FLAG_TE1 | DMA1_FLAG_HT1 | DMA1_FLAG_GL1),
.init = { .init = {
.NVIC_IRQChannel = DMA1_Channel1_IRQn, .NVIC_IRQChannel = DMA1_Channel1_IRQn,
@ -310,16 +310,10 @@ void PIOS_ADC_handler() {
/* /*
* Telemetry USART * Telemetry USART
*/ */
void PIOS_USART_telem_irq_handler(void); static const struct pios_usart_cfg pios_usart_telem_cfg = {
void USART2_IRQHandler() __attribute__ ((alias ("PIOS_USART_telem_irq_handler")));
const struct pios_usart_cfg pios_usart_telem_cfg = {
.regs = USART2, .regs = USART2,
.init = { .init = {
#if defined (PIOS_COM_TELEM_BAUDRATE) .USART_BaudRate = 57600,
.USART_BaudRate = PIOS_COM_TELEM_BAUDRATE,
#else
.USART_BaudRate = 57600,
#endif
.USART_WordLength = USART_WordLength_8b, .USART_WordLength = USART_WordLength_8b,
.USART_Parity = USART_Parity_No, .USART_Parity = USART_Parity_No,
.USART_StopBits = USART_StopBits_1, .USART_StopBits = USART_StopBits_1,
@ -327,7 +321,7 @@ const struct pios_usart_cfg pios_usart_telem_cfg = {
.USART_Mode = USART_Mode_Rx | USART_Mode_Tx, .USART_Mode = USART_Mode_Rx | USART_Mode_Tx,
}, },
.irq = { .irq = {
.handler = PIOS_USART_telem_irq_handler, .handler = NULL,
.init = { .init = {
.NVIC_IRQChannel = USART2_IRQn, .NVIC_IRQChannel = USART2_IRQn,
.NVIC_IRQChannelPreemptionPriority = PIOS_IRQ_PRIO_MID, .NVIC_IRQChannelPreemptionPriority = PIOS_IRQ_PRIO_MID,
@ -356,17 +350,11 @@ const struct pios_usart_cfg pios_usart_telem_cfg = {
/* /*
* GPS USART * GPS USART
*/ */
void PIOS_USART_gps_irq_handler(void); static const struct pios_usart_cfg pios_usart_gps_cfg = {
void USART3_IRQHandler() __attribute__ ((alias ("PIOS_USART_gps_irq_handler")));
const struct pios_usart_cfg pios_usart_gps_cfg = {
.regs = USART3, .regs = USART3,
.remap = GPIO_PartialRemap_USART3, .remap = GPIO_PartialRemap_USART3,
.init = { .init = {
#if defined (PIOS_COM_GPS_BAUDRATE) .USART_BaudRate = 57600,
.USART_BaudRate = PIOS_COM_GPS_BAUDRATE,
#else
.USART_BaudRate = 57600,
#endif
.USART_WordLength = USART_WordLength_8b, .USART_WordLength = USART_WordLength_8b,
.USART_Parity = USART_Parity_No, .USART_Parity = USART_Parity_No,
.USART_StopBits = USART_StopBits_1, .USART_StopBits = USART_StopBits_1,
@ -374,7 +362,7 @@ const struct pios_usart_cfg pios_usart_gps_cfg = {
.USART_Mode = USART_Mode_Rx | USART_Mode_Tx, .USART_Mode = USART_Mode_Rx | USART_Mode_Tx,
}, },
.irq = { .irq = {
.handler = PIOS_USART_gps_irq_handler, .handler = NULL,
.init = { .init = {
.NVIC_IRQChannel = USART3_IRQn, .NVIC_IRQChannel = USART3_IRQn,
.NVIC_IRQChannelPreemptionPriority = PIOS_IRQ_PRIO_MID, .NVIC_IRQChannelPreemptionPriority = PIOS_IRQ_PRIO_MID,
@ -404,16 +392,9 @@ const struct pios_usart_cfg pios_usart_gps_cfg = {
/* /*
* AUX USART * AUX USART
*/ */
void PIOS_USART_aux_irq_handler(void); static const struct pios_usart_cfg pios_usart_aux_cfg = {
void USART1_IRQHandler() __attribute__ ((alias ("PIOS_USART_aux_irq_handler")));
const struct pios_usart_cfg pios_usart_aux_cfg = {
.regs = USART1, .regs = USART1,
.init = { .init = {
#if defined (PIOS_COM_AUX_BAUDRATE)
.USART_BaudRate = PIOS_COM_AUX_BAUDRATE,
#else
.USART_BaudRate = 57600,
#endif
.USART_BaudRate = 57600, .USART_BaudRate = 57600,
.USART_WordLength = USART_WordLength_8b, .USART_WordLength = USART_WordLength_8b,
.USART_Parity = USART_Parity_No, .USART_Parity = USART_Parity_No,
@ -422,7 +403,7 @@ const struct pios_usart_cfg pios_usart_aux_cfg = {
.USART_Mode = USART_Mode_Rx | USART_Mode_Tx, .USART_Mode = USART_Mode_Rx | USART_Mode_Tx,
}, },
.irq = { .irq = {
.handler = PIOS_USART_aux_irq_handler, .handler = NULL,
.init = { .init = {
.NVIC_IRQChannel = USART1_IRQn, .NVIC_IRQChannel = USART1_IRQn,
.NVIC_IRQChannelPreemptionPriority = PIOS_IRQ_PRIO_MID, .NVIC_IRQChannelPreemptionPriority = PIOS_IRQ_PRIO_MID,
@ -450,20 +431,45 @@ const struct pios_usart_cfg pios_usart_aux_cfg = {
}; };
#endif #endif
#if defined(PIOS_INCLUDE_RTC)
/*
* Realtime Clock (RTC)
*/
#include <pios_rtc_priv.h>
void PIOS_RTC_IRQ_Handler (void);
void RTC_IRQHandler() __attribute__ ((alias ("PIOS_RTC_IRQ_Handler")));
static const struct pios_rtc_cfg pios_rtc_main_cfg = {
.clksrc = RCC_RTCCLKSource_HSE_Div128,
.prescaler = 100,
.irq = {
.handler = NULL,
.init = {
.NVIC_IRQChannel = RTC_IRQn,
.NVIC_IRQChannelPreemptionPriority = PIOS_IRQ_PRIO_MID,
.NVIC_IRQChannelSubPriority = 0,
.NVIC_IRQChannelCmd = ENABLE,
},
},
};
void PIOS_RTC_IRQ_Handler (void)
{
PIOS_RTC_irq_handler ();
}
#endif
#ifdef PIOS_COM_SPEKTRUM #ifdef PIOS_COM_SPEKTRUM
/* /*
* SPEKTRUM USART * SPEKTRUM USART
*/ */
void PIOS_USART_spektrum_irq_handler(void); #include <pios_spektrum_priv.h>
void USART1_IRQHandler() __attribute__ ((alias ("PIOS_USART_spektrum_irq_handler")));
const struct pios_usart_cfg pios_usart_spektrum_cfg = { static const struct pios_usart_cfg pios_usart_spektrum_cfg = {
.regs = USART1, .regs = USART1,
.init = { .init = {
#if defined (PIOS_COM_SPEKTRUM_BAUDRATE) .USART_BaudRate = 115200,
.USART_BaudRate = PIOS_COM_SPEKTRUM_BAUDRATE,
#else
.USART_BaudRate = 115200,
#endif
.USART_WordLength = USART_WordLength_8b, .USART_WordLength = USART_WordLength_8b,
.USART_Parity = USART_Parity_No, .USART_Parity = USART_Parity_No,
.USART_StopBits = USART_StopBits_1, .USART_StopBits = USART_StopBits_1,
@ -471,7 +477,7 @@ const struct pios_usart_cfg pios_usart_spektrum_cfg = {
.USART_Mode = USART_Mode_Rx, .USART_Mode = USART_Mode_Rx,
}, },
.irq = { .irq = {
.handler = PIOS_USART_spektrum_irq_handler, .handler = PIOS_SPEKTRUM_irq_handler,
.init = { .init = {
.NVIC_IRQChannel = USART1_IRQn, .NVIC_IRQChannel = USART1_IRQn,
.NVIC_IRQChannelPreemptionPriority = PIOS_IRQ_PRIO_HIGH, .NVIC_IRQChannelPreemptionPriority = PIOS_IRQ_PRIO_HIGH,
@ -497,74 +503,30 @@ 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> static const struct pios_spektrum_cfg pios_spektrum_cfg = {
void RTC_IRQHandler(); .bind = {
void RTC_IRQHandler() __attribute__ ((alias ("PIOS_SUPV_irq_handler"))); .gpio = GPIOA,
const struct pios_spektrum_cfg pios_spektrum_cfg = { .init = {
.pios_usart_spektrum_cfg = &pios_usart_spektrum_cfg, .GPIO_Pin = GPIO_Pin_10,
.gpio_init = { //used for bind feature .GPIO_Speed = GPIO_Speed_2MHz,
.GPIO_Mode = GPIO_Mode_Out_PP, .GPIO_Mode = GPIO_Mode_Out_PP,
.GPIO_Speed = GPIO_Speed_2MHz,
},
.remap = 0,
.irq = {
.handler = RTC_IRQHandler,
.init = {
.NVIC_IRQChannelPreemptionPriority = PIOS_IRQ_PRIO_MID,
.NVIC_IRQChannelSubPriority = 0,
.NVIC_IRQChannelCmd = ENABLE,
}, },
}, },
.port = GPIOA, .remap = 0,
.pin = GPIO_Pin_10,
}; };
void PIOS_SUPV_irq_handler() {
if (RTC_GetITStatus(RTC_IT_SEC))
{
/* Call the right handler */
PIOS_SPEKTRUM_irq_handler(pios_usart_spektrum_id);
/* Wait until last write operation on RTC registers has finished */
RTC_WaitForLastTask();
/* Clear the RTC Second interrupt */
RTC_ClearITPendingBit(RTC_IT_SEC);
}
}
#endif /* PIOS_COM_SPEKTRUM */ #endif /* PIOS_COM_SPEKTRUM */
static uint32_t pios_usart_telem_rf_id; #if defined(PIOS_INCLUDE_SBUS)
void PIOS_USART_telem_irq_handler(void) #error PIOS_INCLUDE_SBUS not implemented
{ #endif /* PIOS_INCLUDE_SBUS */
PIOS_USART_IRQ_Handler(pios_usart_telem_rf_id);
}
static uint32_t pios_usart_gps_id;
void PIOS_USART_gps_irq_handler(void)
{
#ifdef USART_GPS_DEBUG_PIN
PIOS_DEBUG_PinHigh(USART_GPS_DEBUG_PIN);
#endif
PIOS_USART_IRQ_Handler(pios_usart_gps_id);
#ifdef USART_GPS_DEBUG_PIN
PIOS_DEBUG_PinLow(USART_GPS_DEBUG_PIN);
#endif
}
#ifdef PIOS_COM_AUX
static uint32_t pios_usart_aux_id;
void PIOS_USART_aux_irq_handler(void)
{
PIOS_USART_IRQ_Handler(pios_usart_aux_id);
}
#endif
#endif /* PIOS_INCLUDE_USART */ #endif /* PIOS_INCLUDE_USART */
@ -578,7 +540,7 @@ void PIOS_USART_aux_irq_handler(void)
* Pios servo configuration structures * Pios servo configuration structures
*/ */
#include <pios_servo_priv.h> #include <pios_servo_priv.h>
const struct pios_servo_channel pios_servo_channels[] = { static const struct pios_servo_channel pios_servo_channels[] = {
{ {
.timer = TIM4, .timer = TIM4,
.port = GPIOB, .port = GPIOB,
@ -662,7 +624,7 @@ const struct pios_servo_cfg pios_servo_cfg = {
*/ */
#if defined(PIOS_INCLUDE_PWM) #if defined(PIOS_INCLUDE_PWM)
#include <pios_pwm_priv.h> #include <pios_pwm_priv.h>
const struct pios_pwm_channel pios_pwm_channels[] = { static const struct pios_pwm_channel pios_pwm_channels[] = {
{ {
.timer = TIM1, .timer = TIM1,
.port = GPIOA, .port = GPIOA,
@ -747,7 +709,7 @@ const struct pios_pwm_cfg pios_pwm_cfg = {
}, },
.remap = GPIO_PartialRemap_TIM3, .remap = GPIO_PartialRemap_TIM3,
.irq = { .irq = {
.handler = TIM1_CC_IRQHandler, .handler = NULL,
.init = { .init = {
.NVIC_IRQChannelPreemptionPriority = PIOS_IRQ_PRIO_MID, .NVIC_IRQChannelPreemptionPriority = PIOS_IRQ_PRIO_MID,
.NVIC_IRQChannelSubPriority = 0, .NVIC_IRQChannelSubPriority = 0,
@ -778,7 +740,7 @@ void PIOS_TIM5_irq_handler()
#include <pios_ppm_priv.h> #include <pios_ppm_priv.h>
void TIM6_IRQHandler(); void TIM6_IRQHandler();
void TIM6_IRQHandler() __attribute__ ((alias ("PIOS_TIM6_irq_handler"))); void TIM6_IRQHandler() __attribute__ ((alias ("PIOS_TIM6_irq_handler")));
const struct pios_ppmsv_cfg pios_ppmsv_cfg = { static const struct pios_ppmsv_cfg pios_ppmsv_cfg = {
.tim_base_init = { .tim_base_init = {
.TIM_Prescaler = (PIOS_MASTER_CLOCK / 1000000) - 1, /* For 1 uS accuracy */ .TIM_Prescaler = (PIOS_MASTER_CLOCK / 1000000) - 1, /* For 1 uS accuracy */
.TIM_ClockDivision = TIM_CKD_DIV1, .TIM_ClockDivision = TIM_CKD_DIV1,
@ -787,7 +749,7 @@ const struct pios_ppmsv_cfg pios_ppmsv_cfg = {
.TIM_RepetitionCounter = 0x0000, .TIM_RepetitionCounter = 0x0000,
}, },
.irq = { .irq = {
.handler = TIM6_IRQHandler, .handler = NULL,
.init = { .init = {
.NVIC_IRQChannelPreemptionPriority = PIOS_IRQ_PRIO_MID, .NVIC_IRQChannelPreemptionPriority = PIOS_IRQ_PRIO_MID,
.NVIC_IRQChannelSubPriority = 0, .NVIC_IRQChannelSubPriority = 0,
@ -798,14 +760,14 @@ 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();
} }
void TIM1_CC_IRQHandler(); void TIM1_CC_IRQHandler();
void TIM1_CC_IRQHandler() __attribute__ ((alias ("PIOS_TIM1_CC_irq_handler"))); void TIM1_CC_IRQHandler() __attribute__ ((alias ("PIOS_TIM1_CC_irq_handler")));
const struct pios_ppm_cfg pios_ppm_cfg = { static const struct pios_ppm_cfg pios_ppm_cfg = {
.tim_base_init = { .tim_base_init = {
.TIM_Prescaler = (PIOS_MASTER_CLOCK / 1000000) - 1, /* For 1 uS accuracy */ .TIM_Prescaler = (PIOS_MASTER_CLOCK / 1000000) - 1, /* For 1 uS accuracy */
.TIM_ClockDivision = TIM_CKD_DIV1, .TIM_ClockDivision = TIM_CKD_DIV1,
@ -827,7 +789,7 @@ const struct pios_ppm_cfg pios_ppm_cfg = {
}, },
.remap = 0, .remap = 0,
.irq = { .irq = {
.handler = TIM1_CC_IRQHandler, .handler = NULL,
.init = { .init = {
.NVIC_IRQChannelPreemptionPriority = PIOS_IRQ_PRIO_MID, .NVIC_IRQChannelPreemptionPriority = PIOS_IRQ_PRIO_MID,
.NVIC_IRQChannelSubPriority = 0, .NVIC_IRQChannelSubPriority = 0,
@ -840,7 +802,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();
} }
@ -860,7 +822,7 @@ void PIOS_I2C_main_adapter_er_irq_handler(void);
void I2C2_EV_IRQHandler() __attribute__ ((alias ("PIOS_I2C_main_adapter_ev_irq_handler"))); void I2C2_EV_IRQHandler() __attribute__ ((alias ("PIOS_I2C_main_adapter_ev_irq_handler")));
void I2C2_ER_IRQHandler() __attribute__ ((alias ("PIOS_I2C_main_adapter_er_irq_handler"))); void I2C2_ER_IRQHandler() __attribute__ ((alias ("PIOS_I2C_main_adapter_er_irq_handler")));
const struct pios_i2c_adapter_cfg pios_i2c_main_adapter_cfg = { static const struct pios_i2c_adapter_cfg pios_i2c_main_adapter_cfg = {
.regs = I2C2, .regs = I2C2,
.init = { .init = {
.I2C_Mode = I2C_Mode_I2C, .I2C_Mode = I2C_Mode_I2C,
@ -888,7 +850,7 @@ const struct pios_i2c_adapter_cfg pios_i2c_main_adapter_cfg = {
}, },
}, },
.event = { .event = {
.handler = PIOS_I2C_main_adapter_ev_irq_handler, .handler = NULL,
.flags = 0, /* FIXME: check this */ .flags = 0, /* FIXME: check this */
.init = { .init = {
.NVIC_IRQChannel = I2C2_EV_IRQn, .NVIC_IRQChannel = I2C2_EV_IRQn,
@ -898,7 +860,7 @@ const struct pios_i2c_adapter_cfg pios_i2c_main_adapter_cfg = {
}, },
}, },
.error = { .error = {
.handler = PIOS_I2C_main_adapter_er_irq_handler, .handler = NULL,
.flags = 0, /* FIXME: check this */ .flags = 0, /* FIXME: check this */
.init = { .init = {
.NVIC_IRQChannel = I2C2_ER_IRQn, .NVIC_IRQChannel = I2C2_ER_IRQn,
@ -1009,6 +971,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;
@ -1038,7 +1007,7 @@ void PIOS_Board_Init(void) {
#if defined(PIOS_INCLUDE_SPI) #if defined(PIOS_INCLUDE_SPI)
/* Set up the SPI interface to the SD card */ /* Set up the SPI interface to the SD card */
if (PIOS_SPI_Init(&pios_spi_sdcard_id, &pios_spi_sdcard_cfg)) { if (PIOS_SPI_Init(&pios_spi_sdcard_id, &pios_spi_sdcard_cfg)) {
PIOS_DEBUG_Assert(0); PIOS_Assert(0);
} }
/* Enable and mount the SDCard */ /* Enable and mount the SDCard */
@ -1046,23 +1015,16 @@ 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();
UAVObjectsInitializeAll(); UAVObjectsInitializeAll();
#if defined(PIOS_INCLUDE_RTC)
/* Initialize the real-time clock and its associated tick */
PIOS_RTC_Init(&pios_rtc_main_cfg);
#endif
/* Initialize the alarms library */ /* Initialize the alarms library */
AlarmsInitialize(); AlarmsInitialize();
@ -1074,7 +1036,7 @@ void PIOS_Board_Init(void) {
/* Set up the SPI interface to the AHRS */ /* Set up the SPI interface to the AHRS */
if (PIOS_SPI_Init(&pios_spi_ahrs_id, &pios_spi_ahrs_cfg)) { if (PIOS_SPI_Init(&pios_spi_ahrs_id, &pios_spi_ahrs_cfg)) {
PIOS_DEBUG_Assert(0); PIOS_Assert(0);
} }
/* Bind the AHRS comms layer to the AHRS SPI link */ /* Bind the AHRS comms layer to the AHRS SPI link */
@ -1082,43 +1044,95 @@ void PIOS_Board_Init(void) {
/* Initialize the PiOS library */ /* Initialize the PiOS library */
#if defined(PIOS_INCLUDE_COM) #if defined(PIOS_INCLUDE_COM)
#if defined(PIOS_INCLUDE_TELEMETRY_RF)
uint32_t pios_usart_telem_rf_id;
if (PIOS_USART_Init(&pios_usart_telem_rf_id, &pios_usart_telem_cfg)) { if (PIOS_USART_Init(&pios_usart_telem_rf_id, &pios_usart_telem_cfg)) {
PIOS_DEBUG_Assert(0); PIOS_Assert(0);
} }
if (PIOS_COM_Init(&pios_com_telem_rf_id, &pios_usart_com_driver, pios_usart_telem_rf_id)) { if (PIOS_COM_Init(&pios_com_telem_rf_id, &pios_usart_com_driver, pios_usart_telem_rf_id)) {
PIOS_DEBUG_Assert(0); PIOS_Assert(0);
} }
#endif /* PIOS_INCLUDE_TELEMETRY_RF */
#if defined(PIOS_INCLUDE_GPS)
uint32_t pios_usart_gps_id;
if (PIOS_USART_Init(&pios_usart_gps_id, &pios_usart_gps_cfg)) { if (PIOS_USART_Init(&pios_usart_gps_id, &pios_usart_gps_cfg)) {
PIOS_DEBUG_Assert(0); PIOS_Assert(0);
} }
if (PIOS_COM_Init(&pios_com_gps_id, &pios_usart_com_driver, pios_usart_gps_id)) { if (PIOS_COM_Init(&pios_com_gps_id, &pios_usart_com_driver, pios_usart_gps_id)) {
PIOS_DEBUG_Assert(0); PIOS_Assert(0);
} }
#endif /* PIOS_INCLUDE_GPS */
#endif #endif
PIOS_Servo_Init(); PIOS_Servo_Init();
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(&pios_spektrum_cfg, false);
uint32_t pios_usart_spektrum_id;
if (PIOS_USART_Init(&pios_usart_spektrum_id, &pios_usart_spektrum_cfg)) {
PIOS_Assert(0);
}
for (uint8_t i = 0; i < PIOS_SPEKTRUM_NUM_INPUTS && i < PIOS_RCVR_MAX_DEVS; 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_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 < PIOS_RCVR_MAX_DEVS; 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_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 < PIOS_RCVR_MAX_DEVS; 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_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);
#if defined(PIOS_INCLUDE_COM) #if defined(PIOS_INCLUDE_COM)
if (PIOS_COM_Init(&pios_com_telem_usb_id, &pios_usb_com_driver, 0)) { if (PIOS_COM_Init(&pios_com_telem_usb_id, &pios_usb_com_driver, 0)) {
PIOS_DEBUG_Assert(0); PIOS_Assert(0);
} }
#endif /* PIOS_INCLUDE_COM */ #endif /* PIOS_INCLUDE_COM */
#endif /* PIOS_INCLUDE_USB_HID */ #endif /* PIOS_INCLUDE_USB_HID */
#if defined(PIOS_INCLUDE_I2C) #if defined(PIOS_INCLUDE_I2C)
if (PIOS_I2C_Init(&pios_i2c_main_adapter_id, &pios_i2c_main_adapter_cfg)) { if (PIOS_I2C_Init(&pios_i2c_main_adapter_id, &pios_i2c_main_adapter_cfg)) {
PIOS_DEBUG_Assert(0); PIOS_Assert(0);
} }
#endif /* PIOS_INCLUDE_I2C */ #endif /* PIOS_INCLUDE_I2C */
PIOS_IAP_Init(); PIOS_IAP_Init();

View File

@ -120,7 +120,6 @@ extern uint32_t pios_i2c_main_adapter_id;
#define PIOS_USART_MAX_DEVS 2 #define PIOS_USART_MAX_DEVS 2
#define PIOS_USART_RX_BUFFER_SIZE 256 #define PIOS_USART_RX_BUFFER_SIZE 256
#define PIOS_USART_TX_BUFFER_SIZE 256 #define PIOS_USART_TX_BUFFER_SIZE 256
#define PIOS_USART_BAUDRATE 230400
//------------------------- //-------------------------
// PIOS_COM // PIOS_COM

View File

@ -141,13 +141,11 @@ extern uint32_t pios_i2c_main_adapter_id;
//------------------------- //-------------------------
#define PIOS_COM_MAX_DEVS 4 #define PIOS_COM_MAX_DEVS 4
#define PIOS_COM_TELEM_BAUDRATE 57600
extern uint32_t pios_com_telem_rf_id; extern uint32_t pios_com_telem_rf_id;
#define PIOS_COM_TELEM_RF (pios_com_telem_rf_id) #define PIOS_COM_TELEM_RF (pios_com_telem_rf_id)
#define PIOS_COM_DEBUG PIOS_COM_TELEM_RF #define PIOS_COM_DEBUG PIOS_COM_TELEM_RF
#if defined(PIOS_INCLUDE_GPS) #if defined(PIOS_INCLUDE_GPS)
#define PIOS_COM_GPS_BAUDRATE 57600
extern uint32_t pios_com_gps_id; extern uint32_t pios_com_gps_id;
#define PIOS_COM_GPS (pios_com_gps_id) #define PIOS_COM_GPS (pios_com_gps_id)
#endif /* PIOS_INCLUDE_GPS */ #endif /* PIOS_INCLUDE_GPS */
@ -156,11 +154,15 @@ extern uint32_t pios_com_telem_usb_id;
#define PIOS_COM_TELEM_USB (pios_com_telem_usb_id) #define PIOS_COM_TELEM_USB (pios_com_telem_usb_id)
#ifdef PIOS_INCLUDE_SPEKTRUM #ifdef PIOS_INCLUDE_SPEKTRUM
#define PIOS_COM_SPEKTRUM_BAUDRATE 115200
extern uint32_t pios_com_spektrum_id; extern uint32_t pios_com_spektrum_id;
#define PIOS_COM_SPEKTRUM (pios_com_spektrum_id) #define PIOS_COM_SPEKTRUM (pios_com_spektrum_id)
#endif #endif
#ifdef PIOS_INCLUDE_SBUS
extern uint32_t pios_com_sbus_id;
#define PIOS_COM_SBUS (pios_com_sbus_id)
#endif
//------------------------- //-------------------------
// ADC // ADC
// PIOS_ADC_PinGet(0) = Gyro Z // PIOS_ADC_PinGet(0) = Gyro Z
@ -219,10 +221,26 @@ extern uint32_t pios_com_spektrum_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
//-------------------------
// Receiver PWM input
//-------------------------
#define PIOS_PWM_NUM_INPUTS 6
//-------------------------
// Receiver SPEKTRUM input
//-------------------------
#define PIOS_SPEKTRUM_NUM_INPUTS 12
//------------------------- //-------------------------
// Servo outputs // Servo outputs

View File

@ -135,12 +135,10 @@ extern uint32_t pios_i2c_gyro_adapter_id;
//------------------------- //-------------------------
#define PIOS_COM_MAX_DEVS 2 #define PIOS_COM_MAX_DEVS 2
#define PIOS_COM_GPS_BAUDRATE 57600
extern uint32_t pios_com_gps_id; extern uint32_t pios_com_gps_id;
#define PIOS_COM_GPS (pios_com_gps_id) #define PIOS_COM_GPS (pios_com_gps_id)
#ifdef PIOS_ENABLE_AUX_UART #ifdef PIOS_ENABLE_AUX_UART
#define PIOS_COM_AUX_BAUDRATE 57600
extern uint32_t pios_com_aux_id; extern uint32_t pios_com_aux_id;
#define PIOS_COM_AUX (pios_com_aux_id) #define PIOS_COM_AUX (pios_com_aux_id)
#define PIOS_COM_DEBUG PIOS_COM_AUX #define PIOS_COM_DEBUG PIOS_COM_AUX

View File

@ -149,11 +149,9 @@ extern uint32_t pios_i2c_main_adapter_id;
//------------------------- //-------------------------
#define PIOS_COM_MAX_DEVS 4 #define PIOS_COM_MAX_DEVS 4
#define PIOS_COM_TELEM_BAUDRATE 57600
extern uint32_t pios_com_telem_rf_id; extern uint32_t pios_com_telem_rf_id;
#define PIOS_COM_TELEM_RF (pios_com_telem_rf_id) #define PIOS_COM_TELEM_RF (pios_com_telem_rf_id)
#define PIOS_COM_GPS_BAUDRATE 57600
extern uint32_t pios_com_gps_id; extern uint32_t pios_com_gps_id;
#define PIOS_COM_GPS (pios_com_gps_id) #define PIOS_COM_GPS (pios_com_gps_id)
@ -161,18 +159,21 @@ extern uint32_t pios_com_telem_usb_id;
#define PIOS_COM_TELEM_USB (pios_com_telem_usb_id) #define PIOS_COM_TELEM_USB (pios_com_telem_usb_id)
#ifdef PIOS_ENABLE_AUX_UART #ifdef PIOS_ENABLE_AUX_UART
#define PIOS_COM_AUX_BAUDRATE 57600
extern uint32_t pios_com_aux_id; extern uint32_t pios_com_aux_id;
#define PIOS_COM_AUX (pios_com_aux_id) #define PIOS_COM_AUX (pios_com_aux_id)
#define PIOS_COM_DEBUG PIOS_COM_AUX #define PIOS_COM_DEBUG PIOS_COM_AUX
#endif #endif
#ifdef PIOS_INCLUDE_SPEKTRUM #ifdef PIOS_INCLUDE_SPEKTRUM
#define PIOS_COM_SPEKTRUM_BAUDRATE 115200
extern uint32_t pios_com_spektrum_id; extern uint32_t pios_com_spektrum_id;
#define PIOS_COM_SPEKTRUM (pios_com_spektrum_id) #define PIOS_COM_SPEKTRUM (pios_com_spektrum_id)
#endif #endif
#ifdef PIOS_INCLUDE_SBUS
extern uint32_t pios_com_sbus_id;
#define PIOS_COM_SBUS (pios_com_sbus_id)
#endif
//------------------------- //-------------------------
// Delay Timer // Delay Timer
//------------------------- //-------------------------
@ -193,37 +194,33 @@ extern uint32_t pios_com_spektrum_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

View File

@ -38,7 +38,7 @@
static bool PIOS_COM_validate(struct pios_com_dev * com_dev) static bool PIOS_COM_validate(struct pios_com_dev * com_dev)
{ {
return (com_dev->magic == PIOS_COM_DEV_MAGIC); return (com_dev && (com_dev->magic == PIOS_COM_DEV_MAGIC));
} }
#if defined(PIOS_INCLUDE_FREERTOS) && 0 #if defined(PIOS_INCLUDE_FREERTOS) && 0
@ -298,7 +298,9 @@ int32_t PIOS_COM_ReceiveBufferUsed(uint32_t com_id)
if (!PIOS_COM_validate(com_dev)) { if (!PIOS_COM_validate(com_dev)) {
/* Undefined COM port for this board (see pios_board.c) */ /* Undefined COM port for this board (see pios_board.c) */
PIOS_DEBUG_Assert(0); /* This is commented out so com_id=NULL can be used to disable telemetry */
//PIOS_DEBUG_Assert(0);
return 0;
} }
if (!com_dev->driver->rx_avail) { if (!com_dev->driver->rx_avail) {

View File

@ -32,8 +32,8 @@
#include "pios.h" #include "pios.h"
#if defined(PIOS_INCLUDE_HCSR04) #if defined(PIOS_INCLUDE_HCSR04)
#if !defined(PIOS_INCLUDE_SPEKTRUM) #if !(defined(PIOS_INCLUDE_SPEKTRUM) || defined(PIOS_INCLUDE_SBUS))
#error Only supported with spektrum interface! #error Only supported with Spektrum or S.Bus interface!
#endif #endif
/* Local Variables */ /* Local Variables */

View File

@ -0,0 +1,88 @@
/* Project Includes */
#include "pios.h"
#if defined(PIOS_INCLUDE_RCVR)
#include <pios_rcvr_priv.h>
static bool PIOS_RCVR_validate(struct pios_rcvr_dev * rcvr_dev)
{
return (rcvr_dev->magic == PIOS_RCVR_DEV_MAGIC);
}
#if defined(PIOS_INCLUDE_FREERTOS) && 0
static struct pios_rcvr_dev * PIOS_RCVR_alloc(void)
{
struct pios_rcvr_dev * rcvr_dev;
rcvr_dev = (struct pios_rcvr_dev *)malloc(sizeof(*rcvr_dev));
if (!rcvr_dev) return (NULL);
rcvr_dev->magic = PIOS_RCVR_DEV_MAGIC;
return(rcvr_dev);
}
#else
static struct pios_rcvr_dev pios_rcvr_devs[PIOS_RCVR_MAX_DEVS];
static uint8_t pios_rcvr_num_devs;
static struct pios_rcvr_dev * PIOS_RCVR_alloc(void)
{
struct pios_rcvr_dev * rcvr_dev;
if (pios_rcvr_num_devs >= PIOS_RCVR_MAX_DEVS) {
return (NULL);
}
rcvr_dev = &pios_rcvr_devs[pios_rcvr_num_devs++];
rcvr_dev->magic = PIOS_RCVR_DEV_MAGIC;
return (rcvr_dev);
}
#endif
/**
* Initialises RCVR layer
* \param[out] handle
* \param[in] driver
* \param[in] id
* \return < 0 if initialisation failed
*/
int32_t PIOS_RCVR_Init(uint32_t * rcvr_id, const struct pios_rcvr_driver * driver, const uint32_t lower_id)
{
PIOS_DEBUG_Assert(rcvr_id);
PIOS_DEBUG_Assert(driver);
struct pios_rcvr_dev * rcvr_dev;
rcvr_dev = (struct pios_rcvr_dev *) PIOS_RCVR_alloc();
if (!rcvr_dev) goto out_fail;
rcvr_dev->driver = driver;
rcvr_dev->id = lower_id;
*rcvr_id = (uint32_t)rcvr_dev;
return(0);
out_fail:
return(-1);
}
int32_t PIOS_RCVR_Read(uint32_t rcvr_id)
{
struct pios_rcvr_dev * rcvr_dev = (struct pios_rcvr_dev *)rcvr_id;
if (!PIOS_RCVR_validate(rcvr_dev)) {
/* Undefined RCVR port for this board (see pios_board.c) */
PIOS_DEBUG_Assert(0);
}
PIOS_DEBUG_Assert(rcvr_dev->driver->read);
return rcvr_dev->driver->read(rcvr_dev->id);
}
#endif
/**
* @}
* @}
*/

View File

@ -34,22 +34,29 @@
#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;
static uint32_t CurrentValue; static uint32_t CurrentValue;
static uint32_t CapturedValue; static uint32_t CapturedValue;
static uint32_t CaptureValue[PIOS_PPM_NUM_INPUTS]; static uint32_t CaptureValue[PIOS_PPM_NUM_INPUTS];
static uint8_t SupervisorState = 0;
static uint32_t CapCounter[PIOS_PPM_NUM_INPUTS]; static uint32_t CapCounter[PIOS_PPM_NUM_INPUTS];
static uint16_t TimerCounter;
static uint8_t supv_timer = 0;
static uint8_t SupervisorState = 0;
static uint32_t CapCounterPrev[PIOS_PPM_NUM_INPUTS]; static uint32_t CapCounterPrev[PIOS_PPM_NUM_INPUTS];
/** static void PIOS_PPM_Supervisor(uint32_t ppm_id);
* Initialises all the LED's
*/
void PIOS_PPM_Init(void) void PIOS_PPM_Init(void)
{ {
/* Flush counter variables */ /* Flush counter variables */
@ -59,6 +66,7 @@ void PIOS_PPM_Init(void)
PreviousValue = 0; PreviousValue = 0;
CurrentValue = 0; CurrentValue = 0;
CapturedValue = 0; CapturedValue = 0;
TimerCounter = 0;
for (i = 0; i < PIOS_PPM_NUM_INPUTS; i++) { for (i = 0; i < PIOS_PPM_NUM_INPUTS; i++) {
CaptureValue[i] = 0; CaptureValue[i] = 0;
@ -121,13 +129,12 @@ void PIOS_PPM_Init(void)
TIM_TimeBaseInit(pios_ppm_cfg.timer, &TIM_TimeBaseStructure); TIM_TimeBaseInit(pios_ppm_cfg.timer, &TIM_TimeBaseStructure);
/* Enable the Capture Compare Interrupt Request */ /* Enable the Capture Compare Interrupt Request */
TIM_ITConfig(pios_ppm_cfg.timer, pios_ppm_cfg.ccr, ENABLE); TIM_ITConfig(pios_ppm_cfg.timer, pios_ppm_cfg.ccr | TIM_IT_Update, ENABLE);
/* Enable timers */ /* Enable timers */
TIM_Cmd(pios_ppm_cfg.timer, ENABLE); TIM_Cmd(pios_ppm_cfg.timer, ENABLE);
/* Supervisor Setup */ /* Supervisor Setup */
#if (PIOS_PPM_SUPV_ENABLED)
/* Flush counter variables */ /* Flush counter variables */
for (i = 0; i < PIOS_PPM_NUM_INPUTS; i++) { for (i = 0; i < PIOS_PPM_NUM_INPUTS; i++) {
CapCounter[i] = 0; CapCounter[i] = 0;
@ -136,70 +143,15 @@ void PIOS_PPM_Init(void)
CapCounterPrev[i] = 0; CapCounterPrev[i] = 0;
} }
NVIC_InitStructure = pios_ppmsv_cfg.irq.init;
/* Enable appropriate clock to timer module */
switch((int32_t) pios_ppmsv_cfg.timer) {
case (int32_t)TIM1:
NVIC_InitStructure.NVIC_IRQChannel = TIM1_CC_IRQn;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE);
break;
case (int32_t)TIM2:
NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
break;
case (int32_t)TIM3:
NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
break;
case (int32_t)TIM4:
NVIC_InitStructure.NVIC_IRQChannel = TIM4_IRQn;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE);
break;
#ifdef STM32F10X_HD
case (int32_t)TIM5:
NVIC_InitStructure.NVIC_IRQChannel = TIM5_IRQn;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM5, ENABLE);
break;
case (int32_t)TIM6:
NVIC_InitStructure.NVIC_IRQChannel = TIM6_IRQn;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM6, ENABLE);
break;
case (int32_t)TIM7:
NVIC_InitStructure.NVIC_IRQChannel = TIM7_IRQn;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM7, ENABLE);
break;
case (int32_t)TIM8:
NVIC_InitStructure.NVIC_IRQChannel = TIM8_CC_IRQn;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM8, ENABLE);
break;
#endif
}
/* Configure interrupts */
NVIC_Init(&NVIC_InitStructure);
/* Time base configuration */
TIM_TimeBaseStructInit(&TIM_TimeBaseStructure);
TIM_TimeBaseStructure = pios_ppmsv_cfg.tim_base_init;
TIM_TimeBaseInit(pios_ppmsv_cfg.timer, &TIM_TimeBaseStructure);
/* Enable the CCx Interrupt Request */
TIM_ITConfig(pios_ppmsv_cfg.timer, pios_ppmsv_cfg.ccr, ENABLE);
/* Clear update pending flag */
TIM_ClearFlag(pios_ppmsv_cfg.timer, TIM_FLAG_Update);
/* Enable counter */
TIM_Cmd(pios_ppmsv_cfg.timer, ENABLE);
#endif
/* Setup local variable which stays in this scope */ /* Setup local variable which stays in this scope */
/* Doing this here and using a local variable saves doing it in the ISR */ /* Doing this here and using a local variable saves doing it in the ISR */
TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI; TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI;
TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1; TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;
TIM_ICInitStructure.TIM_ICFilter = 0x0; TIM_ICInitStructure.TIM_ICFilter = 0x0;
if (!PIOS_RTC_RegisterTickCallback(PIOS_PPM_Supervisor, 0)) {
PIOS_DEBUG_Assert(0);
}
} }
/** /**
@ -208,13 +160,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];
} }
/** /**
@ -224,6 +176,15 @@ int32_t PIOS_PPM_Get(int8_t Channel)
*/ */
void PIOS_PPM_irq_handler(void) void PIOS_PPM_irq_handler(void)
{ {
if (TIM_GetITStatus(pios_ppm_cfg.timer, TIM_IT_Update) == SET) {
TimerCounter+=pios_ppm_cfg.timer->ARR;
TIM_ClearITPendingBit(pios_ppm_cfg.timer, TIM_IT_Update);
if (TIM_GetITStatus(pios_ppm_cfg.timer, pios_ppm_cfg.ccr) != SET) {
return;
}
}
/* Do this as it's more efficient */ /* Do this as it's more efficient */
if (TIM_GetITStatus(pios_ppm_cfg.timer, pios_ppm_cfg.ccr) == SET) { if (TIM_GetITStatus(pios_ppm_cfg.timer, pios_ppm_cfg.ccr) == SET) {
PreviousValue = CurrentValue; PreviousValue = CurrentValue;
@ -241,37 +202,44 @@ void PIOS_PPM_irq_handler(void)
CurrentValue = TIM_GetCapture4(pios_ppm_cfg.timer); CurrentValue = TIM_GetCapture4(pios_ppm_cfg.timer);
break; break;
} }
} CurrentValue+=TimerCounter;
if(CurrentValue > 0xFFFF) {
CurrentValue-=0xFFFF;
}
/* Clear TIMx Capture compare interrupt pending bit */ /* Clear TIMx Capture compare interrupt pending bit */
TIM_ClearITPendingBit(pios_ppm_cfg.timer, pios_ppm_cfg.ccr); TIM_ClearITPendingBit(pios_ppm_cfg.timer, pios_ppm_cfg.ccr);
/* Capture computation */ /* Capture computation */
if (CurrentValue > PreviousValue) { if (CurrentValue > PreviousValue) {
CapturedValue = (CurrentValue - PreviousValue); CapturedValue = (CurrentValue - PreviousValue);
} else { } else {
CapturedValue = ((0xFFFF - PreviousValue) + CurrentValue); CapturedValue = ((0xFFFF - PreviousValue) + CurrentValue);
} }
/* sync pulse */ /* sync pulse */
if (CapturedValue > 8000) { if (CapturedValue > 8000) {
PulseIndex = 0; PulseIndex = 0;
/* trying to detect bad pulses, not sure this is working correctly yet. I need a scope :P */ /* trying to detect bad pulses, not sure this is working correctly yet. I need a scope :P */
} else if (CapturedValue > 750 && CapturedValue < 2500) { } else if (CapturedValue > 750 && CapturedValue < 2500) {
if (PulseIndex < PIOS_PPM_NUM_INPUTS) { if (PulseIndex < PIOS_PPM_NUM_INPUTS) {
CaptureValue[PulseIndex] = CapturedValue; CaptureValue[PulseIndex] = CapturedValue;
CapCounter[PulseIndex]++; CapCounter[PulseIndex]++;
PulseIndex++; PulseIndex++;
}
} }
} }
} }
/** static void PIOS_PPM_Supervisor(uint32_t ppm_id) {
* This function handles TIM3 global interrupt request. /*
*/ * RTC runs at 625Hz so divide down the base rate so
void PIOS_PPMSV_irq_handler(void) { * that this loop runs at 25Hz.
/* Clear timer interrupt pending bit */ */
TIM_ClearITPendingBit(pios_ppmsv_cfg.timer, pios_ppmsv_cfg.ccr); if(++supv_timer < 25) {
return;
}
supv_timer = 0;
/* Simple state machine */ /* Simple state machine */
if (SupervisorState == 0) { if (SupervisorState == 0) {

View File

@ -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
/** /**

View File

@ -32,30 +32,39 @@
#include "pios.h" #include "pios.h"
#if defined(PIOS_INCLUDE_RTC) #if defined(PIOS_INCLUDE_RTC)
#include <pios_rtc_priv.h>
#ifndef PIOS_RTC_PRESCALAR #ifndef PIOS_RTC_PRESCALER
#define PIOS_RTC_PRESCALAR 100 #define PIOS_RTC_PRESCALER 100
#endif #endif
void PIOS_RTC_Init() struct rtc_callback_entry {
void (*fn)(uint32_t);
uint32_t data;
};
#define PIOS_RTC_MAX_CALLBACKS 3
struct rtc_callback_entry rtc_callback_list[PIOS_RTC_MAX_CALLBACKS];
static uint8_t rtc_callback_next = 0;
void PIOS_RTC_Init(const struct pios_rtc_cfg * cfg)
{ {
RCC_APB1PeriphClockCmd(RCC_APB1Periph_BKP | RCC_APB1Periph_PWR, RCC_APB1PeriphClockCmd(RCC_APB1Periph_BKP | RCC_APB1Periph_PWR,
ENABLE); ENABLE);
PWR_BackupAccessCmd(ENABLE); PWR_BackupAccessCmd(ENABLE);
RCC_RTCCLKConfig(RCC_RTCCLKSource_HSE_Div128); RCC_RTCCLKConfig(cfg->clksrc);
RCC_RTCCLKCmd(ENABLE); RCC_RTCCLKCmd(ENABLE);
RTC_WaitForLastTask(); RTC_WaitForLastTask();
RTC_WaitForSynchro(); RTC_WaitForSynchro();
RTC_WaitForLastTask(); RTC_WaitForLastTask();
#if defined(PIOS_INCLUDE_SPEKTRUM) /* Configure and enable the RTC Second interrupt */
/* Enable the RTC Second interrupt */ NVIC_Init(&cfg->irq.init);
RTC_ITConfig( RTC_IT_SEC, ENABLE ); RTC_ITConfig( RTC_IT_SEC, ENABLE );
/* Wait until last write operation on RTC registers has finished */
RTC_WaitForLastTask(); RTC_WaitForLastTask();
#endif
RTC_SetPrescaler(PIOS_RTC_PRESCALAR); // counting at 8e6 / 128 RTC_SetPrescaler(cfg->prescaler);
RTC_WaitForLastTask(); RTC_WaitForLastTask();
RTC_SetCounter(0); RTC_SetCounter(0);
RTC_WaitForLastTask(); RTC_WaitForLastTask();
@ -66,9 +75,12 @@ uint32_t PIOS_RTC_Counter()
return RTC_GetCounter(); return RTC_GetCounter();
} }
/* FIXME: This shouldn't use hard-coded clock rates, dividers or prescalers.
* Should get these from the cfg struct passed to init.
*/
float PIOS_RTC_Rate() float PIOS_RTC_Rate()
{ {
return (float) (8e6 / 128) / (1 + PIOS_RTC_PRESCALAR); return (float) (8e6 / 128) / (1 + PIOS_RTC_PRESCALER);
} }
float PIOS_RTC_MsPerTick() float PIOS_RTC_MsPerTick()
@ -76,6 +88,39 @@ float PIOS_RTC_MsPerTick()
return 1000.0f / PIOS_RTC_Rate(); return 1000.0f / PIOS_RTC_Rate();
} }
/* TODO: This needs a mutex around rtc_callbacks[] */
bool PIOS_RTC_RegisterTickCallback(void (*fn)(uint32_t id), uint32_t data)
{
struct rtc_callback_entry * cb;
if (rtc_callback_next >= PIOS_RTC_MAX_CALLBACKS) {
return false;
}
cb = &rtc_callback_list[rtc_callback_next++];
cb->fn = fn;
cb->data = data;
return true;
}
void PIOS_RTC_irq_handler (void)
{
if (RTC_GetITStatus(RTC_IT_SEC))
{
/* Call all registered callbacks */
for (uint8_t i = 0; i < rtc_callback_next; i++) {
struct rtc_callback_entry * cb = &rtc_callback_list[i];
if (cb->fn) {
(cb->fn)(cb->data);
}
}
/* Wait until last write operation on RTC registers has finished */
RTC_WaitForLastTask();
/* Clear the RTC Second interrupt */
RTC_ClearITPendingBit(RTC_IT_SEC);
}
}
#endif #endif
/** /**

View File

@ -0,0 +1,227 @@
/**
******************************************************************************
* @addtogroup PIOS PIOS Core hardware abstraction layer
* @{
* @addtogroup PIOS_SBUS Futaba S.Bus receiver functions
* @brief Code to read Futaba S.Bus input
* @{
*
* @file pios_sbus.c
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2011.
* @brief USART commands. Inits USARTs, controls USARTs & Interrupt handlers. (STM32 dependent)
* @see The GNU Public License (GPL) Version 3
*
*****************************************************************************/
/*
* 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
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/* Project Includes */
#include "pios.h"
#include "pios_sbus_priv.h"
#if defined(PIOS_INCLUDE_SBUS)
/* 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 */
static uint16_t channel_data[SBUS_NUMBER_OF_CHANNELS];
static uint8_t received_data[SBUS_FRAME_LENGTH - 2];
static uint8_t receive_timer;
static uint8_t failsafe_timer;
static uint8_t frame_found;
static void PIOS_SBUS_Supervisor(uint32_t sbus_id);
/**
* reset_channels() function clears all channel data in case of
* lost signal or explicit failsafe flag from the S.Bus data stream
*/
static void reset_channels(void)
{
for (int i = 0; i < SBUS_NUMBER_OF_CHANNELS; i++) {
channel_data[i] = 0;
}
}
/**
* unroll_channels() function computes channel_data[] from received_data[]
* For efficiency it unrolls first 8 channels without loops. If other
* 8 channels are needed they can be unrolled using the same code
* starting from s[11] instead of s[0]. Two extra digital channels are
* accessible using (s[22] & SBUS_FLAG_DGx) logical expressions.
*/
static void unroll_channels(void)
{
uint8_t *s = received_data;
uint16_t *d = channel_data;
#if (SBUS_NUMBER_OF_CHANNELS != 8)
#error Current S.Bus code unrolls only first 8 channels
#endif
#define F(v,s) ((v) >> s) & 0x7ff
*d++ = F(s[0] | s[1] << 8, 0);
*d++ = F(s[1] | s[2] << 8, 3);
*d++ = F(s[2] | s[3] << 8 | s[4] << 16, 6);
*d++ = F(s[4] | s[5] << 8, 1);
*d++ = F(s[5] | s[6] << 8, 4);
*d++ = F(s[6] | s[7] << 8 | s[8] << 16, 7);
*d++ = F(s[8] | s[9] << 8, 2);
*d++ = F(s[9] | s[10] << 8, 5);
}
/**
* process_byte() function processes incoming byte from S.Bus stream
*/
static void process_byte(uint8_t b)
{
static uint8_t byte_count;
if (frame_found == 0) {
/* no frame found yet, waiting for start byte */
if (b == SBUS_SOF_BYTE) {
byte_count = 0;
frame_found = 1;
}
} else {
/* do not store start and end of frame bytes */
if (byte_count < SBUS_FRAME_LENGTH - 2) {
/* store next byte */
received_data[byte_count++] = b;
} else {
if (b == SBUS_EOF_BYTE) {
/* full frame received */
uint8_t flags = received_data[SBUS_FRAME_LENGTH - 3];
if (flags & SBUS_FLAG_FL) {
/* frame lost, do not update */
} else if (flags & SBUS_FLAG_FS) {
/* failsafe flag active */
reset_channels();
} else {
/* data looking good */
unroll_channels();
failsafe_timer = 0;
}
} else {
/* discard whole frame */
}
/* prepare for the next frame */
frame_found = 0;
}
}
}
/**
* Initialise S.Bus receiver interface
*/
void PIOS_SBUS_Init(const struct pios_sbus_cfg *cfg)
{
/* Enable inverter clock and enable the inverter */
(*cfg->gpio_clk_func)(cfg->gpio_clk_periph, ENABLE);
GPIO_Init(cfg->inv.gpio, &cfg->inv.init);
GPIO_WriteBit(cfg->inv.gpio,
cfg->inv.init.GPIO_Pin,
cfg->gpio_inv_enable);
if (!PIOS_RTC_RegisterTickCallback(PIOS_SBUS_Supervisor, 0)) {
PIOS_Assert(0);
}
}
/**
* Get the value of an input channel
* \param[in] channel Number of the channel desired (zero based)
* \output -1 channel not available
* \output >0 channel value
*/
static int32_t PIOS_SBUS_Get(uint32_t chan_id)
{
/* return error if channel is not available */
if (chan_id >= SBUS_NUMBER_OF_CHANNELS) {
return -1;
}
return channel_data[chan_id];
}
/**
* Interrupt handler for USART
*/
void PIOS_SBUS_irq_handler(uint32_t usart_id)
{
/* Grab the config for this device from the underlying USART device */
const struct pios_usart_cfg * cfg;
cfg = PIOS_USART_GetConfig(usart_id);
PIOS_Assert(cfg);
/* by always reading DR after SR make sure to clear any error interrupts */
volatile uint16_t sr = cfg->regs->SR;
volatile uint8_t b = cfg->regs->DR;
/* process received byte if one has arrived */
if (sr & USART_SR_RXNE) {
/* process byte and clear receive timer */
process_byte(b);
receive_timer = 0;
}
/* ignore TXE interrupts */
if (sr & USART_SR_TXE) {
/* disable TXE interrupt (TXEIE=0) */
USART_ITConfig(cfg->regs, USART_IT_TXE, DISABLE);
}
}
/**
* Input data supervisor is called periodically and provides
* two functions: frame syncing and failsafe triggering.
*
* S.Bus frames come at 7ms (HS) or 14ms (FS) rate at 100000bps. RTC
* timer is running at 625Hz (1.6ms). So with divider 2 it gives
* 3.2ms pause between frames which is good for both S.Bus data rates.
*
* Data receive function must clear the receive_timer to confirm new
* data reception. If no new data received in 100ms, we must call the
* failsafe function which clears all channels.
*/
static void PIOS_SBUS_Supervisor(uint32_t sbus_id)
{
/* waiting for new frame if no bytes were received in 3.2ms */
if (++receive_timer > 2) {
receive_timer = 0;
frame_found = 0;
}
/* activate failsafe if no frames have arrived in 102.4ms */
if (++failsafe_timer > 64) {
reset_channels();
failsafe_timer = 0;
}
}
#endif
/**
* @}
* @}
*/

View File

@ -34,12 +34,6 @@
#include "pios_spektrum_priv.h" #include "pios_spektrum_priv.h"
#if defined(PIOS_INCLUDE_SPEKTRUM) #if defined(PIOS_INCLUDE_SPEKTRUM)
#if defined(PIOS_INCLUDE_PWM)
#error "Both PWM and SPEKTRUM input defined, choose only one"
#endif
#if defined(PIOS_COM_AUX)
#error "AUX com cannot be used with SPEKTRUM"
#endif
/** /**
* @Note Framesyncing: * @Note Framesyncing:
@ -51,31 +45,35 @@
/* 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;
static void PIOS_SPEKTRUM_Supervisor(uint32_t spektrum_id);
static bool PIOS_SPEKTRUM_Bind(const struct pios_spektrum_cfg * cfg);
/** /**
* Bind and Initialise Spektrum satellite receiver * Bind and Initialise Spektrum satellite receiver
*/ */
void PIOS_SPEKTRUM_Init(void) void PIOS_SPEKTRUM_Init(const struct pios_spektrum_cfg * cfg, bool bind)
{ {
// TODO: need setting flag for bind on next powerup // TODO: need setting flag for bind on next powerup
if (0) { if (bind) {
PIOS_SPEKTRUM_Bind(); PIOS_SPEKTRUM_Bind(cfg);
} }
/* Init RTC supervisor timer interrupt */ if (!PIOS_RTC_RegisterTickCallback(PIOS_SPEKTRUM_Supervisor, 0)) {
NVIC_InitTypeDef NVIC_InitStructure; PIOS_DEBUG_Assert(0);
NVIC_InitStructure.NVIC_IRQChannel = RTC_IRQn; }
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = PIOS_IRQ_PRIO_MID;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
/* Init RTC clock */
PIOS_RTC_Init();
} }
/** /**
@ -84,59 +82,56 @@ 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];
} }
/** /**
* Spektrum bind function * Spektrum bind function
* \output 1 Successful bind * \output true Successful bind
* \output 0 Bind failed * \output false Bind failed
* \note Applications shouldn't call these functions directly
*/ */
uint8_t PIOS_SPEKTRUM_Bind(void) static bool PIOS_SPEKTRUM_Bind(const struct pios_spektrum_cfg * cfg)
{ {
GPIO_InitTypeDef GPIO_InitStructure = pios_spektrum_cfg.gpio_init; GPIO_Init(cfg->bind.gpio, &cfg->bind.init);
GPIO_InitStructure.GPIO_Pin = pios_spektrum_cfg.pin;
GPIO_Init(pios_spektrum_cfg.port, &GPIO_InitStructure);
pios_spektrum_cfg.port->BRR = pios_spektrum_cfg.pin; GPIO_ResetBits(cfg->bind.gpio, cfg->bind.init.GPIO_Pin);
//PIOS_DELAY_WaitmS(75); //PIOS_DELAY_WaitmS(75);
/* RX line, drive high for 10us */ /* RX line, drive high for 10us */
pios_spektrum_cfg.port->BSRR = pios_spektrum_cfg.pin; GPIO_SetBits(cfg->bind.gpio, cfg->bind.init.GPIO_Pin);
PIOS_DELAY_WaituS(10); PIOS_DELAY_WaituS(10);
/* RX line, drive low for 120us */ /* RX line, drive low for 120us */
pios_spektrum_cfg.port->BRR = pios_spektrum_cfg.pin; GPIO_ResetBits(cfg->bind.gpio, cfg->bind.init.GPIO_Pin);
PIOS_DELAY_WaituS(120); PIOS_DELAY_WaituS(120);
/* RX line, drive high for 120us */ /* RX line, drive high for 120us */
pios_spektrum_cfg.port->BSRR = pios_spektrum_cfg.pin; GPIO_SetBits(cfg->bind.gpio, cfg->bind.init.GPIO_Pin);
PIOS_DELAY_WaituS(120); PIOS_DELAY_WaituS(120);
/* RX line, drive low for 120us */ /* RX line, drive low for 120us */
pios_spektrum_cfg.port->BRR = pios_spektrum_cfg.pin; GPIO_ResetBits(cfg->bind.gpio, cfg->bind.init.GPIO_Pin);
PIOS_DELAY_WaituS(120); PIOS_DELAY_WaituS(120);
/* RX line, drive high for 120us */ /* RX line, drive high for 120us */
pios_spektrum_cfg.port->BSRR = pios_spektrum_cfg.pin; GPIO_SetBits(cfg->bind.gpio, cfg->bind.init.GPIO_Pin);
PIOS_DELAY_WaituS(120); PIOS_DELAY_WaituS(120);
/* RX line, drive low for 120us */ /* RX line, drive low for 120us */
pios_spektrum_cfg.port->BRR = pios_spektrum_cfg.pin; GPIO_ResetBits(cfg->bind.gpio, cfg->bind.init.GPIO_Pin);
PIOS_DELAY_WaituS(120); PIOS_DELAY_WaituS(120);
/* RX line, drive high for 120us */ /* RX line, drive high for 120us */
pios_spektrum_cfg.port->BSRR = pios_spektrum_cfg.pin; GPIO_SetBits(cfg->bind.gpio, cfg->bind.init.GPIO_Pin);
PIOS_DELAY_WaituS(120); PIOS_DELAY_WaituS(120);
/* RX line, drive low for 120us */ /* RX line, drive low for 120us */
pios_spektrum_cfg.port->BRR = pios_spektrum_cfg.pin; GPIO_ResetBits(cfg->bind.gpio, cfg->bind.init.GPIO_Pin);
PIOS_DELAY_WaituS(120); PIOS_DELAY_WaituS(120);
/* RX line, drive high for 120us */ /* RX line, drive high for 120us */
pios_spektrum_cfg.port->BSRR = pios_spektrum_cfg.pin; GPIO_SetBits(cfg->bind.gpio, cfg->bind.init.GPIO_Pin);
PIOS_DELAY_WaituS(120); PIOS_DELAY_WaituS(120);
/* RX line, set input and wait for data, PIOS_SPEKTRUM_Init */ /* RX line, set input and wait for data, PIOS_SPEKTRUM_Init */
return 1; return true;
} }
/** /**
@ -147,7 +142,7 @@ uint8_t PIOS_SPEKTRUM_Bind(void)
* \return -2 if buffer full (retry) * \return -2 if buffer full (retry)
* \note Applications shouldn't call these functions directly * \note Applications shouldn't call these functions directly
*/ */
int32_t PIOS_SPEKTRUM_Decode(uint8_t b) static int32_t PIOS_SPEKTRUM_Decode(uint8_t b)
{ {
static uint16_t channel = 0; /*, sync_word = 0;*/ static uint16_t channel = 0; /*, sync_word = 0;*/
uint8_t channeln = 0, frame = 0; uint8_t channeln = 0, frame = 0;
@ -201,7 +196,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 +207,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];
} }
@ -223,11 +218,16 @@ int32_t PIOS_SPEKTRUM_Decode(uint8_t b)
return 0; return 0;
} }
/* Interrupt handler for USART */ /* Custom interrupt handler for USART */
void SPEKTRUM_IRQHandler(uint32_t usart_id) { void PIOS_SPEKTRUM_irq_handler(uint32_t usart_id) {
/* Grab the config for this device from the underlying USART device */
const struct pios_usart_cfg * cfg;
cfg = PIOS_USART_GetConfig(usart_id);
PIOS_Assert(cfg);
/* 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 = cfg->regs->SR;
volatile uint8_t b = pios_spektrum_cfg.pios_usart_spektrum_cfg->regs->DR; volatile uint8_t b = cfg->regs->DR;
/* check if RXNE flag is set */ /* check if RXNE flag is set */
if (sr & USART_SR_RXNE) { if (sr & USART_SR_RXNE) {
@ -238,7 +238,7 @@ void SPEKTRUM_IRQHandler(uint32_t usart_id) {
if (sr & USART_SR_TXE) { // check if TXE flag is set if (sr & USART_SR_TXE) { // check if TXE flag is set
/* Disable TXE interrupt (TXEIE=0) */ /* Disable TXE interrupt (TXEIE=0) */
USART_ITConfig(pios_spektrum_cfg.pios_usart_spektrum_cfg->regs, USART_IT_TXE, DISABLE); USART_ITConfig(cfg->regs, USART_IT_TXE, DISABLE);
} }
/* byte arrived so clear "watchdog" timer */ /* byte arrived so clear "watchdog" timer */
supv_timer=0; supv_timer=0;
@ -248,7 +248,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() { static void PIOS_SPEKTRUM_Supervisor(uint32_t spektrum_id) {
/* 125hz */ /* 125hz */
supv_timer++; supv_timer++;
if(supv_timer > 5) { if(supv_timer > 5) {
@ -262,7 +262,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;
} }

View File

@ -51,6 +51,23 @@ const struct pios_com_driver pios_usart_com_driver = {
.rx_avail = PIOS_USART_RxBufferUsed, .rx_avail = PIOS_USART_RxBufferUsed,
}; };
enum pios_usart_dev_magic {
PIOS_USART_DEV_MAGIC = 0x11223344,
};
struct pios_usart_dev {
enum pios_usart_dev_magic magic;
const struct pios_usart_cfg * cfg;
// align to 32-bit to try and provide speed improvement;
uint8_t rx_buffer[PIOS_USART_RX_BUFFER_SIZE] __attribute__ ((aligned(4)));
t_fifo_buffer rx;
// align to 32-bit to try and provide speed improvement;
uint8_t tx_buffer[PIOS_USART_TX_BUFFER_SIZE] __attribute__ ((aligned(4)));
t_fifo_buffer tx;
};
static bool PIOS_USART_validate(struct pios_usart_dev * usart_dev) static bool PIOS_USART_validate(struct pios_usart_dev * usart_dev)
{ {
return (usart_dev->magic == PIOS_USART_DEV_MAGIC); return (usart_dev->magic == PIOS_USART_DEV_MAGIC);
@ -85,6 +102,34 @@ static struct pios_usart_dev * PIOS_USART_alloc(void)
} }
#endif #endif
/* Bind Interrupt Handlers
*
* Map all valid USART IRQs to the common interrupt handler
* and provide storage for a 32-bit device id IRQ to map
* each physical IRQ to a specific registered device instance.
*/
static void PIOS_USART_generic_irq_handler(uint32_t usart_id);
static uint32_t PIOS_USART_1_id;
void USART1_IRQHandler(void) __attribute__ ((alias ("PIOS_USART_1_irq_handler")));
static void PIOS_USART_1_irq_handler (void)
{
PIOS_USART_generic_irq_handler (PIOS_USART_1_id);
}
static uint32_t PIOS_USART_2_id;
void USART2_IRQHandler(void) __attribute__ ((alias ("PIOS_USART_2_irq_handler")));
static void PIOS_USART_2_irq_handler (void)
{
PIOS_USART_generic_irq_handler (PIOS_USART_2_id);
}
static uint32_t PIOS_USART_3_id;
void USART3_IRQHandler(void) __attribute__ ((alias ("PIOS_USART_3_irq_handler")));
static void PIOS_USART_3_irq_handler (void)
{
PIOS_USART_generic_irq_handler (PIOS_USART_3_id);
}
/** /**
* Initialise a single USART device * Initialise a single USART device
@ -134,6 +179,11 @@ int32_t PIOS_USART_Init(uint32_t * usart_id, const struct pios_usart_cfg * cfg)
*usart_id = (uint32_t)usart_dev; *usart_id = (uint32_t)usart_dev;
/* Configure USART Interrupts */ /* Configure USART Interrupts */
switch ((uint32_t)usart_dev->cfg->regs) {
case (uint32_t)USART1: PIOS_USART_1_id = (uint32_t)usart_dev;
case (uint32_t)USART2: PIOS_USART_2_id = (uint32_t)usart_dev;
case (uint32_t)USART3: PIOS_USART_3_id = (uint32_t)usart_dev;
}
NVIC_Init(&usart_dev->cfg->irq.init); NVIC_Init(&usart_dev->cfg->irq.init);
USART_ITConfig(usart_dev->cfg->regs, USART_IT_RXNE, ENABLE); USART_ITConfig(usart_dev->cfg->regs, USART_IT_RXNE, ENABLE);
USART_ITConfig(usart_dev->cfg->regs, USART_IT_TXE, ENABLE); USART_ITConfig(usart_dev->cfg->regs, USART_IT_TXE, ENABLE);
@ -147,6 +197,19 @@ out_fail:
return(-1); return(-1);
} }
const struct pios_usart_cfg * PIOS_USART_GetConfig(uint32_t usart_id)
{
struct pios_usart_dev * usart_dev = (struct pios_usart_dev *)usart_id;
bool valid = PIOS_USART_validate(usart_dev);
if (!valid) {
return (NULL);
}
return usart_dev->cfg;
}
/** /**
* Changes the baud rate of the USART peripheral without re-initialising. * Changes the baud rate of the USART peripheral without re-initialising.
* \param[in] usart_id USART name (GPS, TELEM, AUX) * \param[in] usart_id USART name (GPS, TELEM, AUX)
@ -157,7 +220,7 @@ static void PIOS_USART_ChangeBaud(uint32_t usart_id, uint32_t baud)
struct pios_usart_dev * usart_dev = (struct pios_usart_dev *)usart_id; struct pios_usart_dev * usart_dev = (struct pios_usart_dev *)usart_id;
bool valid = PIOS_USART_validate(usart_dev); bool valid = PIOS_USART_validate(usart_dev);
PIOS_Assert(valid) PIOS_Assert(valid);
USART_InitTypeDef USART_InitStructure; USART_InitTypeDef USART_InitStructure;
@ -337,12 +400,20 @@ static int32_t PIOS_USART_TxBufferPutMore(uint32_t usart_id, const uint8_t *buff
return rc; return rc;
} }
void PIOS_USART_IRQ_Handler(uint32_t usart_id) static void PIOS_USART_generic_irq_handler(uint32_t usart_id)
{ {
struct pios_usart_dev * usart_dev = (struct pios_usart_dev *)usart_id; struct pios_usart_dev * usart_dev = (struct pios_usart_dev *)usart_id;
bool valid = PIOS_USART_validate(usart_dev); bool valid = PIOS_USART_validate(usart_dev);
PIOS_Assert(valid) PIOS_Assert(valid);
/* Call any user provided callback function instead of processing
* the interrupt ourselves.
*/
if (usart_dev->cfg->irq.handler) {
(usart_dev->cfg->irq.handler)(usart_id);
return;
}
/* Force read of dr after sr to make sure to clear error flags */ /* Force read of dr after sr to make sure to clear error flags */
volatile uint16_t sr = usart_dev->cfg->regs->SR; volatile uint16_t sr = usart_dev->cfg->regs->SR;

View File

@ -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 */

View File

@ -34,13 +34,6 @@
#include <pios.h> #include <pios.h>
#include <pios_stm32.h> #include <pios_stm32.h>
struct pios_ppmsv_cfg {
TIM_TimeBaseInitTypeDef tim_base_init;
struct stm32_irq irq;
TIM_TypeDef * timer;
uint16_t ccr;
};
struct pios_ppm_cfg { struct pios_ppm_cfg {
TIM_TimeBaseInitTypeDef tim_base_init; TIM_TimeBaseInitTypeDef tim_base_init;
TIM_ICInitTypeDef tim_ic_init; TIM_ICInitTypeDef tim_ic_init;
@ -53,11 +46,13 @@ struct pios_ppm_cfg {
}; };
extern void PIOS_PPM_irq_handler(); extern void PIOS_PPM_irq_handler();
extern void PIOS_PPMSV_irq_handler();
extern uint8_t pios_ppm_num_channels; 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_rcvr_driver pios_ppm_rcvr_driver;
extern void PIOS_PPM_Init(void);
#endif /* PIOS_PPM_PRIV_H */ #endif /* PIOS_PPM_PRIV_H */

View File

@ -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 */

View File

@ -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 */
/** /**

View File

@ -0,0 +1,49 @@
/**
******************************************************************************
* @addtogroup PIOS PIOS Core hardware abstraction layer
* @{
* @addtogroup PIOS_RCVR RCVR layer functions
* @brief Hardware communication layer
* @{
*
* @file pios_rcvr.h
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
* @brief RCVR layer functions header
* @see The GNU Public License (GPL) Version 3
*
*****************************************************************************/
/*
* 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
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef PIOS_RCVR_H
#define PIOS_RCVR_H
extern uint32_t pios_rcvr_channel_to_id_map[];
struct pios_rcvr_driver {
void (*init)(uint32_t id);
int32_t (*read)(uint32_t id);
};
/* Public Functions */
extern int32_t PIOS_RCVR_Read(uint32_t rcvr_id);
#endif /* PIOS_RCVR_H */
/**
* @}
* @}
*/

View File

@ -0,0 +1,58 @@
/**
******************************************************************************
* @addtogroup PIOS PIOS Core hardware abstraction layer
* @{
* @addtogroup PIOS_RCVR RCVR Functions
* @brief PIOS interface for RCVR drivers
* @{
*
* @file pios_rcvr_priv.h
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
* Parts by Thorsten Klose (tk@midibox.org)
* @brief USART private definitions.
* @see The GNU Public License (GPL) Version 3
*
*****************************************************************************/
/*
* 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
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef PIOS_RCVR_PRIV_H
#define PIOS_RCVR_PRIV_H
#include <pios.h>
extern uint32_t pios_rcvr_max_channel;
enum pios_rcvr_dev_magic {
PIOS_RCVR_DEV_MAGIC = 0x99aabbcc,
};
struct pios_rcvr_dev {
enum pios_rcvr_dev_magic magic;
uint32_t id;
const struct pios_rcvr_driver * driver;
};
extern int32_t PIOS_RCVR_Init(uint32_t * rcvr_id, const struct pios_rcvr_driver * driver, const uint32_t lower_id);
extern void PIOS_RCVR_IRQ_Handler(uint32_t rcvr_id);
#endif /* PIOS_RCVR_PRIV_H */
/**
* @}
* @}
*/

View File

@ -30,13 +30,15 @@
#ifndef PIOS_RTC_H #ifndef PIOS_RTC_H
#define PIOS_RTC_H #define PIOS_RTC_H
#include <stdbool.h>
/* Public Functions */ /* Public Functions */
extern void PIOS_RTC_Init();
extern uint32_t PIOS_RTC_Counter(); extern uint32_t PIOS_RTC_Counter();
extern float PIOS_RTC_Rate(); extern float PIOS_RTC_Rate();
extern float PIOS_RTC_MsPerTick(); extern float PIOS_RTC_MsPerTick();
extern bool PIOS_RTC_RegisterTickCallback(void (*fn)(uint32_t id), uint32_t data);
#endif /* PIOS_SERVO_H */ #endif /* PIOS_RTC_H */
/** /**
* @} * @}

View File

@ -0,0 +1,52 @@
/**
******************************************************************************
* @addtogroup PIOS PIOS Core hardware abstraction layer
* @{
* @addtogroup PIOS_RTC RTC Functions
* @brief PIOS interface for RTC tick
* @{
*
* @file pios_rtc_priv.h
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
* @brief ADC private definitions.
* @see The GNU Public License (GPL) Version 3
*
*****************************************************************************/
/*
* 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
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef PIOS_RTC_PRIV_H
#define PIOS_RTC_PRIV_H
#include <pios.h>
#include <pios_stm32.h>
struct pios_rtc_cfg {
uint32_t clksrc;
uint32_t prescaler;
struct stm32_irq irq;
};
extern void PIOS_RTC_Init(const struct pios_rtc_cfg * cfg);
extern void PIOS_RTC_irq_handler(void);
#endif /* PIOS_RTC_PRIV_H */
/**
* @}
* @}
*/

View File

@ -0,0 +1,42 @@
/**
******************************************************************************
* @addtogroup PIOS PIOS Core hardware abstraction layer
* @{
* @addtogroup PIOS_SBUS Futaba S.Bus receiver functions
* @{
*
* @file pios_sbus.h
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2011.
* @brief Futaba S.Bus functions header.
* @see The GNU Public License (GPL) Version 3
*
*****************************************************************************/
/*
* 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
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef PIOS_SBUS_H
#define PIOS_SBUS_H
/* Global Types */
/* Public Functions */
#endif /* PIOS_SBUS_H */
/**
* @}
* @}
*/

View File

@ -0,0 +1,89 @@
/**
******************************************************************************
* @addtogroup PIOS PIOS Core hardware abstraction layer
* @{
* @addtogroup PIOS_SBUS S.Bus Functions
* @brief PIOS interface to read and write from Futaba S.Bus port
* @{
*
* @file pios_sbus_priv.h
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2011.
* @brief Futaba S.Bus Private structures.
* @see The GNU Public License (GPL) Version 3
*
*****************************************************************************/
/*
* 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
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef PIOS_SBUS_PRIV_H
#define PIOS_SBUS_PRIV_H
#include <pios.h>
#include <pios_stm32.h>
#include <pios_usart_priv.h>
/*
* S.Bus serial port settings:
* 100000bps inverted serial stream, 8 bits, even parity, 2 stop bits
* frame period is 7ms (HS) or 14ms (FS)
*
* Frame structure:
* 1 byte - 0x0f (start of frame byte)
* 22 bytes - channel data (11 bit/channel, 16 channels, LSB first)
* 1 byte - bit flags:
* 0x01 - digital channel 1,
* 0x02 - digital channel 2,
* 0x04 - lost frame flag,
* 0x08 - failsafe flag,
* 0xf0 - reserved
* 1 byte - 0x00 (end of frame byte)
*/
#define SBUS_FRAME_LENGTH (1+22+1+1)
#define SBUS_SOF_BYTE 0x0f
#define SBUS_EOF_BYTE 0x00
#define SBUS_FLAG_DG1 0x01
#define SBUS_FLAG_DG2 0x02
#define SBUS_FLAG_FL 0x04
#define SBUS_FLAG_FS 0x08
/*
* S.Bus protocol provides up to 16 analog and 2 digital channels.
* Only 8 channels are currently supported by the OpenPilot.
*/
#define SBUS_NUMBER_OF_CHANNELS 8
/*
* S.Bus configuration programmable invertor
*/
struct pios_sbus_cfg {
struct stm32_gpio inv;
void (*gpio_clk_func)(uint32_t periph, FunctionalState state);
uint32_t gpio_clk_periph;
BitAction gpio_inv_enable;
};
extern void PIOS_SBUS_irq_handler();
extern const struct pios_rcvr_driver pios_sbus_rcvr_driver;
extern void PIOS_SBUS_Init(const struct pios_sbus_cfg * cfg);
#endif /* PIOS_SBUS_PRIV_H */
/**
* @}
* @}
*/

View File

@ -34,11 +34,6 @@
/* Global Types */ /* Global Types */
/* Public Functions */ /* Public Functions */
extern void PIOS_SPEKTRUM_Init(void);
extern uint8_t PIOS_SPEKTRUM_Bind(void);
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 */

View File

@ -36,18 +36,15 @@
#include <pios_usart_priv.h> #include <pios_usart_priv.h>
struct pios_spektrum_cfg { struct pios_spektrum_cfg {
const struct pios_usart_cfg * pios_usart_spektrum_cfg; struct stm32_gpio bind;
GPIO_InitTypeDef gpio_init;
uint32_t remap; /* GPIO_Remap_* */ uint32_t remap; /* GPIO_Remap_* */
struct stm32_irq irq;
GPIO_TypeDef * port;
uint16_t pin;
}; };
extern void PIOS_SPEKTRUM_irq_handler(); extern void PIOS_SPEKTRUM_irq_handler();
extern uint8_t pios_spektrum_num_channels; extern const struct pios_rcvr_driver pios_spektrum_rcvr_driver;
extern const struct pios_spektrum_cfg pios_spektrum_cfg;
extern void PIOS_SPEKTRUM_Init(const struct pios_spektrum_cfg * cfg, bool bind);
#endif /* PIOS_PWM_PRIV_H */ #endif /* PIOS_PWM_PRIV_H */

View File

@ -32,7 +32,7 @@
#define PIOS_STM32_H #define PIOS_STM32_H
struct stm32_irq { struct stm32_irq {
void (*handler) (void); void (*handler) (uint32_t);
uint32_t flags; uint32_t flags;
NVIC_InitTypeDef init; NVIC_InitTypeDef init;
}; };

View File

@ -48,26 +48,8 @@ struct pios_usart_cfg {
struct stm32_irq irq; struct stm32_irq irq;
}; };
enum pios_usart_dev_magic {
PIOS_USART_DEV_MAGIC = 0x11223344,
};
struct pios_usart_dev {
enum pios_usart_dev_magic magic;
const struct pios_usart_cfg * cfg;
// align to 32-bit to try and provide speed improvement;
uint8_t rx_buffer[PIOS_USART_RX_BUFFER_SIZE] __attribute__ ((aligned(4)));
t_fifo_buffer rx;
// align to 32-bit to try and provide speed improvement;
uint8_t tx_buffer[PIOS_USART_TX_BUFFER_SIZE] __attribute__ ((aligned(4)));
t_fifo_buffer tx;
};
extern int32_t PIOS_USART_Init(uint32_t * usart_id, const struct pios_usart_cfg * cfg); extern int32_t PIOS_USART_Init(uint32_t * usart_id, const struct pios_usart_cfg * cfg);
extern const struct pios_usart_cfg * PIOS_USART_GetConfig(uint32_t usart_id);
extern void PIOS_USART_IRQ_Handler(uint32_t usart_id);
#endif /* PIOS_USART_PRIV_H */ #endif /* PIOS_USART_PRIV_H */

View File

@ -78,7 +78,9 @@
#include <pios_spi.h> #include <pios_spi.h>
#include <pios_ppm.h> #include <pios_ppm.h>
#include <pios_pwm.h> #include <pios_pwm.h>
#include <pios_rcvr.h>
#include <pios_spektrum.h> #include <pios_spektrum.h>
#include <pios_sbus.h>
#include <pios_usb_hid.h> #include <pios_usb_hid.h>
#include <pios_debug.h> #include <pios_debug.h>
#include <pios_gpio.h> #include <pios_gpio.h>

View File

@ -90,7 +90,7 @@ static const struct pios_spi_cfg pios_spi_port_cfg =
.ahb_clk = RCC_AHBPeriph_DMA1, .ahb_clk = RCC_AHBPeriph_DMA1,
.irq = .irq =
{ {
.handler = PIOS_SPI_port_irq_handler, .handler = NULL,
.flags = (DMA1_FLAG_TC2 | DMA1_FLAG_TE2 | DMA1_FLAG_HT2 | DMA1_FLAG_GL2), .flags = (DMA1_FLAG_TC2 | DMA1_FLAG_TE2 | DMA1_FLAG_HT2 | DMA1_FLAG_GL2),
.init = { .init = {
.NVIC_IRQChannel = DMA1_Channel2_IRQn, .NVIC_IRQChannel = DMA1_Channel2_IRQn,
@ -189,11 +189,11 @@ void PIOS_SPI_port_irq_handler(void)
extern void PIOS_ADC_handler(void); extern void PIOS_ADC_handler(void);
void DMA1_Channel1_IRQHandler() __attribute__ ((alias("PIOS_ADC_handler"))); void DMA1_Channel1_IRQHandler() __attribute__ ((alias("PIOS_ADC_handler")));
// Remap the ADC DMA handler to this one // Remap the ADC DMA handler to this one
const struct pios_adc_cfg pios_adc_cfg = { static const struct pios_adc_cfg pios_adc_cfg = {
.dma = { .dma = {
.ahb_clk = RCC_AHBPeriph_DMA1, .ahb_clk = RCC_AHBPeriph_DMA1,
.irq = { .irq = {
.handler = PIOS_ADC_DMA_Handler, .handler = NULL,
.flags = (DMA1_FLAG_TC1 | DMA1_FLAG_TE1 | DMA1_FLAG_HT1 | DMA1_FLAG_GL1), .flags = (DMA1_FLAG_TC1 | DMA1_FLAG_TE1 | DMA1_FLAG_HT1 | DMA1_FLAG_GL1),
.init = { .init = {
.NVIC_IRQChannel = DMA1_Channel1_IRQn, .NVIC_IRQChannel = DMA1_Channel1_IRQn,
@ -245,10 +245,7 @@ void PIOS_ADC_handler() {
/* /*
* SERIAL USART * SERIAL USART
*/ */
void PIOS_USART_serial_irq_handler(void); static const struct pios_usart_cfg pios_usart_serial_cfg =
void USART1_IRQHandler() __attribute__ ((alias ("PIOS_USART_serial_irq_handler")));
const struct pios_usart_cfg pios_usart_serial_cfg =
{ {
.regs = USART1, .regs = USART1,
.init = .init =
@ -262,7 +259,7 @@ const struct pios_usart_cfg pios_usart_serial_cfg =
}, },
.irq = .irq =
{ {
.handler = PIOS_USART_serial_irq_handler, .handler = NULL,
.init = .init =
{ {
.NVIC_IRQChannel = USART1_IRQn, .NVIC_IRQChannel = USART1_IRQn,
@ -293,12 +290,6 @@ const struct pios_usart_cfg pios_usart_serial_cfg =
}, },
}; };
static uint32_t pios_usart_serial_id;
void PIOS_USART_serial_irq_handler(void)
{
PIOS_USART_IRQ_Handler(pios_usart_serial_id);
}
#endif /* PIOS_INCLUDE_USART */ #endif /* PIOS_INCLUDE_USART */
// *********************************************************************************** // ***********************************************************************************
@ -334,6 +325,7 @@ void PIOS_Board_Init(void) {
// Delay system // Delay system
PIOS_DELAY_Init(); PIOS_DELAY_Init();
uint32_t pios_usart_serial_id;
if (PIOS_USART_Init(&pios_usart_serial_id, &pios_usart_serial_cfg)) { if (PIOS_USART_Init(&pios_usart_serial_id, &pios_usart_serial_cfg)) {
PIOS_DEBUG_Assert(0); PIOS_DEBUG_Assert(0);
} }

View File

@ -28,7 +28,7 @@
// Private constants // Private constants
#define MAX_QUEUE_SIZE 20 #define MAX_QUEUE_SIZE 20
#define STACK_SIZE configMINIMAL_STACK_SIZE #define STACK_SIZE 96
#define TASK_PRIORITY (tskIDLE_PRIORITY + 3) #define TASK_PRIORITY (tskIDLE_PRIORITY + 3)
#define MAX_UPDATE_PERIOD_MS 1000 #define MAX_UPDATE_PERIOD_MS 1000

View File

@ -1,3140 +1,3960 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0"> <ui version="4.0">
<class>ccpmWidget</class> <class>ccpmWidget</class>
<widget class="QWidget" name="ccpmWidget"> <widget class="QWidget" name="ccpmWidget">
<property name="geometry"> <property name="geometry">
<rect> <rect>
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>660</width> <width>660</width>
<height>572</height> <height>572</height>
</rect> </rect>
</property> </property>
<property name="sizePolicy"> <property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding"> <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>0</horstretch> <horstretch>0</horstretch>
<verstretch>0</verstretch> <verstretch>0</verstretch>
</sizepolicy> </sizepolicy>
</property> </property>
<property name="minimumSize"> <property name="minimumSize">
<size> <size>
<width>300</width> <width>300</width>
<height>300</height> <height>300</height>
</size> </size>
</property> </property>
<property name="windowTitle"> <property name="windowTitle">
<string>Form</string> <string>Form</string>
</property> </property>
<property name="autoFillBackground"> <property name="autoFillBackground">
<bool>false</bool> <bool>false</bool>
</property> </property>
<layout class="QGridLayout" name="gridLayout_17"> <layout class="QGridLayout" name="gridLayout_17">
<item row="0" column="0"> <item row="0" column="0">
<layout class="QGridLayout" name="gridLayout_13"> <layout class="QGridLayout" name="gridLayout_13">
<item row="0" column="0"> <item row="0" column="0">
<layout class="QFormLayout" name="formLayout_6"> <layout class="QFormLayout" name="formLayout_6">
<property name="fieldGrowthPolicy"> <property name="fieldGrowthPolicy">
<enum>QFormLayout::AllNonFixedFieldsGrow</enum> <enum>QFormLayout::AllNonFixedFieldsGrow</enum>
</property> </property>
<property name="topMargin"> <property name="topMargin">
<number>0</number> <number>0</number>
</property> </property>
<item row="0" column="0"> <item row="0" column="0">
<widget class="QLabel" name="label"> <widget class="QLabel" name="label">
<property name="text"> <property name="text">
<string>Swashplate config:</string> <string>Swashplate config:</string>
</property> </property>
</widget> </widget>
</item> </item>
<item row="0" column="1"> <item row="0" column="1">
<widget class="QComboBox" name="ccpmType"> <widget class="QComboBox" name="ccpmType">
<property name="font"> <property name="font">
<font> <font>
<pointsize>10</pointsize> <pointsize>10</pointsize>
</font> </font>
</property> </property>
<property name="toolTip"> <property name="toolTip">
<string>Select aircraft type here</string> <string>Select aircraft type here</string>
</property> </property>
</widget> </widget>
</item> </item>
</layout> </layout>
</item> </item>
<item row="1" column="0"> <item row="1" column="0">
<widget class="QTabWidget" name="TabObject"> <widget class="QTabWidget" name="TabObject">
<property name="sizePolicy"> <property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding"> <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>0</horstretch> <horstretch>0</horstretch>
<verstretch>0</verstretch> <verstretch>0</verstretch>
</sizepolicy> </sizepolicy>
</property> </property>
<property name="minimumSize"> <property name="minimumSize">
<size> <size>
<width>400</width> <width>300</width>
<height>300</height> <height>300</height>
</size> </size>
</property> </property>
<property name="currentIndex"> <property name="currentIndex">
<number>0</number> <number>0</number>
</property> </property>
<widget class="QWidget" name="BasicTab"> <widget class="QWidget" name="BasicTab">
<attribute name="title"> <attribute name="title">
<string>Basic settings</string> <string>Basic settings</string>
</attribute> </attribute>
<layout class="QGridLayout" name="gridLayout_6"> <layout class="QGridLayout" name="gridLayout_6">
<property name="margin"> <property name="leftMargin">
<number>3</number> <number>3</number>
</property> </property>
<property name="spacing"> <property name="topMargin">
<number>3</number> <number>0</number>
</property> </property>
<item row="0" column="0"> <property name="rightMargin">
<layout class="QVBoxLayout" name="verticalLayout_6" stretch="1,1,1,0"> <number>3</number>
<item> </property>
<widget class="QGroupBox" name="SwashplateBox_2"> <property name="bottomMargin">
<property name="sizePolicy"> <number>3</number>
<sizepolicy hsizetype="Fixed" vsizetype="Maximum"> </property>
<horstretch>0</horstretch> <property name="spacing">
<verstretch>0</verstretch> <number>3</number>
</sizepolicy> </property>
</property> <item row="0" column="0">
<property name="title"> <layout class="QVBoxLayout" name="ccpmSettingsBox" stretch="0,1,1,0,0">
<string>Outputs</string> <item>
</property> <widget class="QGroupBox" name="SwashplateBox_2">
<layout class="QGridLayout" name="gridLayout_18"> <property name="sizePolicy">
<property name="horizontalSpacing"> <sizepolicy hsizetype="Fixed" vsizetype="Maximum">
<number>3</number> <horstretch>0</horstretch>
</property> <verstretch>0</verstretch>
<property name="verticalSpacing"> </sizepolicy>
<number>2</number> </property>
</property> <property name="maximumSize">
<property name="margin"> <size>
<number>3</number> <width>190</width>
</property> <height>16777215</height>
<item row="2" column="1"> </size>
<widget class="QComboBox" name="ccpmTailChannel"> </property>
<property name="sizePolicy"> <property name="font">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed"> <font>
<horstretch>0</horstretch> <pointsize>11</pointsize>
<verstretch>0</verstretch> </font>
</sizepolicy> </property>
</property> <property name="title">
<property name="minimumSize"> <string>Outputs</string>
<size> </property>
<width>85</width> <layout class="QGridLayout" name="gridLayout_18">
<height>0</height> <property name="horizontalSpacing">
</size> <number>3</number>
</property> </property>
<property name="maximumSize"> <property name="verticalSpacing">
<size> <number>2</number>
<width>85</width> </property>
<height>16777215</height> <property name="margin">
</size> <number>3</number>
</property> </property>
</widget> <item row="2" column="1">
</item> <widget class="QComboBox" name="ccpmTailChannel">
<item row="1" column="1"> <property name="sizePolicy">
<widget class="QComboBox" name="ccpmEngineChannel"> <sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
<property name="sizePolicy"> <horstretch>0</horstretch>
<sizepolicy hsizetype="Fixed" vsizetype="Fixed"> <verstretch>0</verstretch>
<horstretch>0</horstretch> </sizepolicy>
<verstretch>0</verstretch> </property>
</sizepolicy> <property name="minimumSize">
</property> <size>
<property name="minimumSize"> <width>85</width>
<size> <height>0</height>
<width>85</width> </size>
<height>0</height> </property>
</size> <property name="maximumSize">
</property> <size>
<property name="maximumSize"> <width>100</width>
<size> <height>16777215</height>
<width>85</width> </size>
<height>16777215</height> </property>
</size> <property name="font">
</property> <font>
</widget> <pointsize>11</pointsize>
</item> </font>
<item row="2" column="0"> </property>
<widget class="QLabel" name="ccpmTailLabel"> </widget>
<property name="sizePolicy"> </item>
<sizepolicy hsizetype="Fixed" vsizetype="Preferred"> <item row="1" column="1">
<horstretch>0</horstretch> <widget class="QComboBox" name="ccpmEngineChannel">
<verstretch>0</verstretch> <property name="sizePolicy">
</sizepolicy> <sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
</property> <horstretch>0</horstretch>
<property name="minimumSize"> <verstretch>0</verstretch>
<size> </sizepolicy>
<width>80</width> </property>
<height>0</height> <property name="minimumSize">
</size> <size>
</property> <width>85</width>
<property name="maximumSize"> <height>0</height>
<size> </size>
<width>80</width> </property>
<height>16777215</height> <property name="maximumSize">
</size> <size>
</property> <width>100</width>
<property name="text"> <height>16777215</height>
<string>Tail Rotor</string> </size>
</property> </property>
</widget> <property name="font">
</item> <font>
<item row="1" column="0"> <pointsize>11</pointsize>
<widget class="QLabel" name="ccpmEngineLabel"> </font>
<property name="sizePolicy"> </property>
<sizepolicy hsizetype="Fixed" vsizetype="Preferred"> </widget>
<horstretch>0</horstretch> </item>
<verstretch>0</verstretch> <item row="2" column="0">
</sizepolicy> <widget class="QLabel" name="ccpmTailLabel">
</property> <property name="sizePolicy">
<property name="minimumSize"> <sizepolicy hsizetype="Fixed" vsizetype="Preferred">
<size> <horstretch>0</horstretch>
<width>80</width> <verstretch>0</verstretch>
<height>0</height> </sizepolicy>
</size> </property>
</property> <property name="minimumSize">
<property name="maximumSize"> <size>
<size> <width>80</width>
<width>80</width> <height>0</height>
<height>16777215</height> </size>
</size> </property>
</property> <property name="maximumSize">
<property name="text"> <size>
<string>Engine</string> <width>80</width>
</property> <height>16777215</height>
</widget> </size>
</item> </property>
</layout> <property name="text">
</widget> <string>Tail Rotor</string>
</item> </property>
<item> </widget>
<widget class="QGroupBox" name="SwashplateBox"> </item>
<property name="sizePolicy"> <item row="1" column="0">
<sizepolicy hsizetype="Fixed" vsizetype="Maximum"> <widget class="QLabel" name="ccpmEngineLabel">
<horstretch>0</horstretch> <property name="sizePolicy">
<verstretch>0</verstretch> <sizepolicy hsizetype="Fixed" vsizetype="Preferred">
</sizepolicy> <horstretch>0</horstretch>
</property> <verstretch>0</verstretch>
<property name="title"> </sizepolicy>
<string>Swashplate Outputs</string> </property>
</property> <property name="minimumSize">
<layout class="QGridLayout" name="gridLayout_19"> <size>
<property name="horizontalSpacing"> <width>80</width>
<number>3</number> <height>0</height>
</property> </size>
<property name="verticalSpacing"> </property>
<number>2</number> <property name="maximumSize">
</property> <size>
<property name="margin"> <width>80</width>
<number>3</number> <height>16777215</height>
</property> </size>
<item row="0" column="0"> </property>
<widget class="QLabel" name="ccpmServoWLabel"> <property name="text">
<property name="enabled"> <string>Engine</string>
<bool>true</bool> </property>
</property> </widget>
<property name="sizePolicy"> </item>
<sizepolicy hsizetype="Fixed" vsizetype="Preferred"> </layout>
<horstretch>1</horstretch> </widget>
<verstretch>1</verstretch> </item>
</sizepolicy> <item>
</property> <widget class="QGroupBox" name="SwashplateBox">
<property name="minimumSize"> <property name="sizePolicy">
<size> <sizepolicy hsizetype="Maximum" vsizetype="Maximum">
<width>80</width> <horstretch>0</horstretch>
<height>0</height> <verstretch>0</verstretch>
</size> </sizepolicy>
</property> </property>
<property name="maximumSize"> <property name="maximumSize">
<size> <size>
<width>80</width> <width>190</width>
<height>16777215</height> <height>16777215</height>
</size> </size>
</property> </property>
<property name="text"> <property name="font">
<string>Servo W</string> <font>
</property> <pointsize>11</pointsize>
</widget> </font>
</item> </property>
<item row="0" column="1"> <property name="title">
<widget class="QComboBox" name="ccpmServoWChannel"> <string>Swashplate Outputs</string>
<property name="enabled"> </property>
<bool>true</bool> <layout class="QGridLayout" name="gridLayout_19">
</property> <property name="horizontalSpacing">
<property name="sizePolicy"> <number>3</number>
<sizepolicy hsizetype="Fixed" vsizetype="Fixed"> </property>
<horstretch>0</horstretch> <property name="verticalSpacing">
<verstretch>0</verstretch> <number>2</number>
</sizepolicy> </property>
</property> <property name="margin">
<property name="minimumSize"> <number>3</number>
<size> </property>
<width>85</width> <item row="0" column="0">
<height>0</height> <widget class="QLabel" name="ccpmServoWLabel">
</size> <property name="enabled">
</property> <bool>true</bool>
<property name="maximumSize"> </property>
<size> <property name="sizePolicy">
<width>85</width> <sizepolicy hsizetype="Fixed" vsizetype="Preferred">
<height>16777215</height> <horstretch>1</horstretch>
</size> <verstretch>1</verstretch>
</property> </sizepolicy>
</widget> </property>
</item> <property name="minimumSize">
<item row="1" column="1"> <size>
<widget class="QComboBox" name="ccpmServoXChannel"> <width>80</width>
<property name="sizePolicy"> <height>0</height>
<sizepolicy hsizetype="Fixed" vsizetype="Fixed"> </size>
<horstretch>0</horstretch> </property>
<verstretch>0</verstretch> <property name="maximumSize">
</sizepolicy> <size>
</property> <width>80</width>
<property name="minimumSize"> <height>16777215</height>
<size> </size>
<width>85</width> </property>
<height>0</height> <property name="text">
</size> <string>Servo W</string>
</property> </property>
<property name="maximumSize"> </widget>
<size> </item>
<width>85</width> <item row="0" column="1">
<height>16777215</height> <widget class="QComboBox" name="ccpmServoWChannel">
</size> <property name="enabled">
</property> <bool>true</bool>
</widget> </property>
</item> <property name="sizePolicy">
<item row="3" column="1"> <sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
<widget class="QComboBox" name="ccpmServoYChannel"> <horstretch>0</horstretch>
<property name="enabled"> <verstretch>0</verstretch>
<bool>true</bool> </sizepolicy>
</property> </property>
<property name="sizePolicy"> <property name="minimumSize">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed"> <size>
<horstretch>0</horstretch> <width>85</width>
<verstretch>0</verstretch> <height>0</height>
</sizepolicy> </size>
</property> </property>
<property name="minimumSize"> <property name="maximumSize">
<size> <size>
<width>85</width> <width>100</width>
<height>0</height> <height>16777215</height>
</size> </size>
</property> </property>
<property name="maximumSize"> </widget>
<size> </item>
<width>85</width> <item row="1" column="1">
<height>16777215</height> <widget class="QComboBox" name="ccpmServoXChannel">
</size> <property name="sizePolicy">
</property> <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
</widget> <horstretch>0</horstretch>
</item> <verstretch>0</verstretch>
<item row="1" column="0"> </sizepolicy>
<widget class="QLabel" name="ccpmServoXLabel"> </property>
<property name="sizePolicy"> <property name="minimumSize">
<sizepolicy hsizetype="Fixed" vsizetype="Preferred"> <size>
<horstretch>1</horstretch> <width>85</width>
<verstretch>1</verstretch> <height>0</height>
</sizepolicy> </size>
</property> </property>
<property name="minimumSize"> <property name="maximumSize">
<size> <size>
<width>80</width> <width>100</width>
<height>0</height> <height>16777215</height>
</size> </size>
</property> </property>
<property name="maximumSize"> </widget>
<size> </item>
<width>80</width> <item row="3" column="1">
<height>16777215</height> <widget class="QComboBox" name="ccpmServoYChannel">
</size> <property name="enabled">
</property> <bool>true</bool>
<property name="text"> </property>
<string>Servo X</string> <property name="sizePolicy">
</property> <sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
</widget> <horstretch>0</horstretch>
</item> <verstretch>0</verstretch>
<item row="5" column="1"> </sizepolicy>
<widget class="QComboBox" name="ccpmSingleServo"> </property>
<property name="sizePolicy"> <property name="minimumSize">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed"> <size>
<horstretch>0</horstretch> <width>85</width>
<verstretch>0</verstretch> <height>0</height>
</sizepolicy> </size>
</property> </property>
<property name="minimumSize"> <property name="maximumSize">
<size> <size>
<width>85</width> <width>100</width>
<height>0</height> <height>16777215</height>
</size> </size>
</property> </property>
<property name="maximumSize"> </widget>
<size> </item>
<width>85</width> <item row="1" column="0">
<height>16777215</height> <widget class="QLabel" name="ccpmServoXLabel">
</size> <property name="sizePolicy">
</property> <sizepolicy hsizetype="Fixed" vsizetype="Preferred">
<item> <horstretch>1</horstretch>
<property name="text"> <verstretch>1</verstretch>
<string>Front</string> </sizepolicy>
</property> </property>
</item> <property name="minimumSize">
<item> <size>
<property name="text"> <width>80</width>
<string>Right</string> <height>0</height>
</property> </size>
</item> </property>
<item> <property name="maximumSize">
<property name="text"> <size>
<string>Rear</string> <width>80</width>
</property> <height>16777215</height>
</item> </size>
<item> </property>
<property name="text"> <property name="text">
<string>Left</string> <string>Servo X</string>
</property> </property>
</item> </widget>
</widget> </item>
</item> <item row="5" column="1">
<item row="5" column="0"> <widget class="QComboBox" name="ccpmSingleServo">
<widget class="QLabel" name="ccpmServoZLabel_3"> <property name="sizePolicy">
<property name="sizePolicy"> <sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
<sizepolicy hsizetype="Fixed" vsizetype="Preferred"> <horstretch>0</horstretch>
<horstretch>1</horstretch> <verstretch>0</verstretch>
<verstretch>1</verstretch> </sizepolicy>
</sizepolicy> </property>
</property> <property name="minimumSize">
<property name="minimumSize"> <size>
<size> <width>85</width>
<width>80</width> <height>0</height>
<height>0</height> </size>
</size> </property>
</property> <property name="maximumSize">
<property name="maximumSize"> <size>
<size> <width>100</width>
<width>80</width> <height>16777215</height>
<height>16777215</height> </size>
</size> </property>
</property> <item>
<property name="text"> <property name="text">
<string>Single Servo</string> <string>Front</string>
</property> </property>
</widget> </item>
</item> <item>
<item row="4" column="1"> <property name="text">
<widget class="QComboBox" name="ccpmServoZChannel"> <string>Right</string>
<property name="sizePolicy"> </property>
<sizepolicy hsizetype="Fixed" vsizetype="Fixed"> </item>
<horstretch>0</horstretch> <item>
<verstretch>0</verstretch> <property name="text">
</sizepolicy> <string>Rear</string>
</property> </property>
<property name="minimumSize"> </item>
<size> <item>
<width>85</width> <property name="text">
<height>0</height> <string>Left</string>
</size> </property>
</property> </item>
<property name="maximumSize"> </widget>
<size> </item>
<width>85</width> <item row="5" column="0">
<height>16777215</height> <widget class="QLabel" name="ccpmServoZLabel_3">
</size> <property name="sizePolicy">
</property> <sizepolicy hsizetype="Fixed" vsizetype="Preferred">
</widget> <horstretch>1</horstretch>
</item> <verstretch>1</verstretch>
<item row="4" column="0"> </sizepolicy>
<widget class="QLabel" name="ccpmServoZLabel"> </property>
<property name="sizePolicy"> <property name="minimumSize">
<sizepolicy hsizetype="Fixed" vsizetype="Preferred"> <size>
<horstretch>1</horstretch> <width>80</width>
<verstretch>1</verstretch> <height>0</height>
</sizepolicy> </size>
</property> </property>
<property name="minimumSize"> <property name="maximumSize">
<size> <size>
<width>80</width> <width>80</width>
<height>0</height> <height>16777215</height>
</size> </size>
</property> </property>
<property name="maximumSize"> <property name="text">
<size> <string>1st Servo</string>
<width>80</width> </property>
<height>16777215</height> </widget>
</size> </item>
</property> <item row="4" column="1">
<property name="text"> <widget class="QComboBox" name="ccpmServoZChannel">
<string>Servo Z</string> <property name="sizePolicy">
</property> <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
</widget> <horstretch>0</horstretch>
</item> <verstretch>0</verstretch>
<item row="3" column="0"> </sizepolicy>
<widget class="QLabel" name="ccpmServoYLabel"> </property>
<property name="enabled"> <property name="minimumSize">
<bool>true</bool> <size>
</property> <width>85</width>
<property name="sizePolicy"> <height>0</height>
<sizepolicy hsizetype="Fixed" vsizetype="Preferred"> </size>
<horstretch>1</horstretch> </property>
<verstretch>1</verstretch> <property name="maximumSize">
</sizepolicy> <size>
</property> <width>100</width>
<property name="minimumSize"> <height>16777215</height>
<size> </size>
<width>80</width> </property>
<height>0</height> </widget>
</size> </item>
</property> <item row="4" column="0">
<property name="maximumSize"> <widget class="QLabel" name="ccpmServoZLabel">
<size> <property name="sizePolicy">
<width>80</width> <sizepolicy hsizetype="Fixed" vsizetype="Preferred">
<height>16777215</height> <horstretch>1</horstretch>
</size> <verstretch>1</verstretch>
</property> </sizepolicy>
<property name="text"> </property>
<string>Servo Y</string> <property name="minimumSize">
</property> <size>
</widget> <width>80</width>
</item> <height>0</height>
</layout> </size>
</widget> </property>
</item> <property name="maximumSize">
<item> <size>
<widget class="QGroupBox" name="SwashplateBox_3"> <width>80</width>
<property name="sizePolicy"> <height>16777215</height>
<sizepolicy hsizetype="Fixed" vsizetype="Maximum"> </size>
<horstretch>0</horstretch> </property>
<verstretch>0</verstretch> <property name="text">
</sizepolicy> <string>Servo Z</string>
</property> </property>
<property name="minimumSize"> </widget>
<size> </item>
<width>70</width> <item row="3" column="0">
<height>0</height> <widget class="QLabel" name="ccpmServoYLabel">
</size> <property name="enabled">
</property> <bool>true</bool>
<property name="title"> </property>
<string>Swashplate Servo Angles</string> <property name="sizePolicy">
</property> <sizepolicy hsizetype="Fixed" vsizetype="Preferred">
<layout class="QGridLayout" name="gridLayout_20"> <horstretch>1</horstretch>
<property name="horizontalSpacing"> <verstretch>1</verstretch>
<number>3</number> </sizepolicy>
</property> </property>
<property name="verticalSpacing"> <property name="minimumSize">
<number>2</number> <size>
</property> <width>80</width>
<property name="margin"> <height>0</height>
<number>3</number> </size>
</property> </property>
<item row="0" column="1"> <property name="maximumSize">
<widget class="QDoubleSpinBox" name="ccpmAngleW"> <size>
<property name="sizePolicy"> <width>80</width>
<sizepolicy hsizetype="Fixed" vsizetype="Fixed"> <height>16777215</height>
<horstretch>0</horstretch> </size>
<verstretch>0</verstretch> </property>
</sizepolicy> <property name="text">
</property> <string>Servo Y</string>
<property name="minimumSize"> </property>
<size> </widget>
<width>85</width> </item>
<height>0</height> </layout>
</size> </widget>
</property> </item>
<property name="maximumSize"> <item>
<size> <widget class="QGroupBox" name="SwashplateBox_3">
<width>85</width> <property name="sizePolicy">
<height>16777215</height> <sizepolicy hsizetype="Fixed" vsizetype="Maximum">
</size> <horstretch>0</horstretch>
</property> <verstretch>0</verstretch>
<property name="decimals"> </sizepolicy>
<number>0</number> </property>
</property> <property name="minimumSize">
<property name="maximum"> <size>
<double>360.000000000000000</double> <width>70</width>
</property> <height>0</height>
<property name="singleStep"> </size>
<double>15.000000000000000</double> </property>
</property> <property name="maximumSize">
</widget> <size>
</item> <width>190</width>
<item row="0" column="0"> <height>16777215</height>
<widget class="QLabel" name="ccpmServoWLabel_2"> </size>
<property name="enabled"> </property>
<bool>true</bool> <property name="font">
</property> <font>
<property name="sizePolicy"> <pointsize>11</pointsize>
<sizepolicy hsizetype="Fixed" vsizetype="Preferred"> </font>
<horstretch>0</horstretch> </property>
<verstretch>0</verstretch> <property name="title">
</sizepolicy> <string>Swashplate Servo Angles</string>
</property> </property>
<property name="minimumSize"> <layout class="QGridLayout" name="gridLayout_20">
<size> <property name="horizontalSpacing">
<width>80</width> <number>3</number>
<height>0</height> </property>
</size> <property name="verticalSpacing">
</property> <number>2</number>
<property name="maximumSize"> </property>
<size> <property name="margin">
<width>80</width> <number>3</number>
<height>16777215</height> </property>
</size> <item row="0" column="1">
</property> <widget class="QDoubleSpinBox" name="ccpmAngleW">
<property name="text"> <property name="sizePolicy">
<string>Angle W</string> <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
</property> <horstretch>0</horstretch>
</widget> <verstretch>0</verstretch>
</item> </sizepolicy>
<item row="1" column="0"> </property>
<widget class="QLabel" name="ccpmServoXLabel_2"> <property name="minimumSize">
<property name="sizePolicy"> <size>
<sizepolicy hsizetype="Fixed" vsizetype="Preferred"> <width>85</width>
<horstretch>0</horstretch> <height>0</height>
<verstretch>0</verstretch> </size>
</sizepolicy> </property>
</property> <property name="maximumSize">
<property name="minimumSize"> <size>
<size> <width>85</width>
<width>80</width> <height>16777215</height>
<height>0</height> </size>
</size> </property>
</property> <property name="decimals">
<property name="maximumSize"> <number>0</number>
<size> </property>
<width>80</width> <property name="maximum">
<height>16777215</height> <double>360.000000000000000</double>
</size> </property>
</property> <property name="singleStep">
<property name="text"> <double>15.000000000000000</double>
<string>Angle X</string> </property>
</property> </widget>
</widget> </item>
</item> <item row="0" column="0">
<item row="2" column="0"> <widget class="QLabel" name="ccpmServoWLabel_2">
<widget class="QLabel" name="ccpmServoYLabel_2"> <property name="enabled">
<property name="enabled"> <bool>true</bool>
<bool>true</bool> </property>
</property> <property name="sizePolicy">
<property name="sizePolicy"> <sizepolicy hsizetype="Fixed" vsizetype="Preferred">
<sizepolicy hsizetype="Fixed" vsizetype="Preferred"> <horstretch>0</horstretch>
<horstretch>0</horstretch> <verstretch>0</verstretch>
<verstretch>0</verstretch> </sizepolicy>
</sizepolicy> </property>
</property> <property name="minimumSize">
<property name="minimumSize"> <size>
<size> <width>80</width>
<width>80</width> <height>0</height>
<height>0</height> </size>
</size> </property>
</property> <property name="maximumSize">
<property name="maximumSize"> <size>
<size> <width>80</width>
<width>80</width> <height>16777215</height>
<height>16777215</height> </size>
</size> </property>
</property> <property name="text">
<property name="text"> <string>Angle W</string>
<string>Angle Y</string> </property>
</property> </widget>
</widget> </item>
</item> <item row="1" column="0">
<item row="4" column="0"> <widget class="QLabel" name="ccpmServoXLabel_2">
<widget class="QLabel" name="ccpmServoZLabel_2"> <property name="sizePolicy">
<property name="sizePolicy"> <sizepolicy hsizetype="Fixed" vsizetype="Preferred">
<sizepolicy hsizetype="Fixed" vsizetype="Preferred"> <horstretch>0</horstretch>
<horstretch>0</horstretch> <verstretch>0</verstretch>
<verstretch>0</verstretch> </sizepolicy>
</sizepolicy> </property>
</property> <property name="minimumSize">
<property name="minimumSize"> <size>
<size> <width>80</width>
<width>80</width> <height>0</height>
<height>0</height> </size>
</size> </property>
</property> <property name="maximumSize">
<property name="maximumSize"> <size>
<size> <width>80</width>
<width>80</width> <height>16777215</height>
<height>16777215</height> </size>
</size> </property>
</property> <property name="text">
<property name="text"> <string>Angle X</string>
<string>Angle Z</string> </property>
</property> </widget>
</widget> </item>
</item> <item row="2" column="0">
<item row="5" column="0"> <widget class="QLabel" name="ccpmServoYLabel_2">
<widget class="QLabel" name="label_10"> <property name="enabled">
<property name="enabled"> <bool>true</bool>
<bool>true</bool> </property>
</property> <property name="sizePolicy">
<property name="sizePolicy"> <sizepolicy hsizetype="Fixed" vsizetype="Preferred">
<sizepolicy hsizetype="Fixed" vsizetype="Preferred"> <horstretch>0</horstretch>
<horstretch>0</horstretch> <verstretch>0</verstretch>
<verstretch>0</verstretch> </sizepolicy>
</sizepolicy> </property>
</property> <property name="minimumSize">
<property name="minimumSize"> <size>
<size> <width>80</width>
<width>80</width> <height>0</height>
<height>0</height> </size>
</size> </property>
</property> <property name="maximumSize">
<property name="maximumSize"> <size>
<size> <width>80</width>
<width>80</width> <height>16777215</height>
<height>16777215</height> </size>
</size> </property>
</property> <property name="text">
<property name="text"> <string>Angle Y</string>
<string>CorrectionAngle</string> </property>
</property> </widget>
</widget> </item>
</item> <item row="4" column="0">
<item row="1" column="1"> <widget class="QLabel" name="ccpmServoZLabel_2">
<widget class="QDoubleSpinBox" name="ccpmAngleX"> <property name="sizePolicy">
<property name="sizePolicy"> <sizepolicy hsizetype="Fixed" vsizetype="Preferred">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed"> <horstretch>0</horstretch>
<horstretch>0</horstretch> <verstretch>0</verstretch>
<verstretch>0</verstretch> </sizepolicy>
</sizepolicy> </property>
</property> <property name="minimumSize">
<property name="minimumSize"> <size>
<size> <width>80</width>
<width>85</width> <height>0</height>
<height>0</height> </size>
</size> </property>
</property> <property name="maximumSize">
<property name="maximumSize"> <size>
<size> <width>80</width>
<width>85</width> <height>16777215</height>
<height>16777215</height> </size>
</size> </property>
</property> <property name="text">
<property name="decimals"> <string>Angle Z</string>
<number>0</number> </property>
</property> </widget>
<property name="maximum"> </item>
<double>360.000000000000000</double> <item row="5" column="0">
</property> <widget class="QLabel" name="label_10">
<property name="singleStep"> <property name="enabled">
<double>15.000000000000000</double> <bool>true</bool>
</property> </property>
</widget> <property name="sizePolicy">
</item> <sizepolicy hsizetype="Fixed" vsizetype="Preferred">
<item row="5" column="1"> <horstretch>0</horstretch>
<widget class="QDoubleSpinBox" name="ccpmCorrectionAngle"> <verstretch>0</verstretch>
<property name="enabled"> </sizepolicy>
<bool>true</bool> </property>
</property> <property name="minimumSize">
<property name="sizePolicy"> <size>
<sizepolicy hsizetype="Fixed" vsizetype="Fixed"> <width>80</width>
<horstretch>0</horstretch> <height>0</height>
<verstretch>0</verstretch> </size>
</sizepolicy> </property>
</property> <property name="maximumSize">
<property name="minimumSize"> <size>
<size> <width>80</width>
<width>85</width> <height>16777215</height>
<height>0</height> </size>
</size> </property>
</property> <property name="text">
<property name="maximumSize"> <string>Correction Angle</string>
<size> </property>
<width>85</width> <property name="wordWrap">
<height>16777215</height> <bool>true</bool>
</size> </property>
</property> </widget>
<property name="decimals"> </item>
<number>0</number> <item row="1" column="1">
</property> <widget class="QDoubleSpinBox" name="ccpmAngleX">
<property name="maximum"> <property name="sizePolicy">
<double>360.000000000000000</double> <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
</property> <horstretch>0</horstretch>
<property name="singleStep"> <verstretch>0</verstretch>
<double>15.000000000000000</double> </sizepolicy>
</property> </property>
</widget> <property name="minimumSize">
</item> <size>
<item row="4" column="1"> <width>85</width>
<widget class="QDoubleSpinBox" name="ccpmAngleZ"> <height>0</height>
<property name="sizePolicy"> </size>
<sizepolicy hsizetype="Fixed" vsizetype="Fixed"> </property>
<horstretch>0</horstretch> <property name="maximumSize">
<verstretch>0</verstretch> <size>
</sizepolicy> <width>85</width>
</property> <height>16777215</height>
<property name="minimumSize"> </size>
<size> </property>
<width>85</width> <property name="decimals">
<height>0</height> <number>0</number>
</size> </property>
</property> <property name="maximum">
<property name="maximumSize"> <double>360.000000000000000</double>
<size> </property>
<width>85</width> <property name="singleStep">
<height>16777215</height> <double>15.000000000000000</double>
</size> </property>
</property> </widget>
<property name="decimals"> </item>
<number>0</number> <item row="5" column="1">
</property> <widget class="QDoubleSpinBox" name="ccpmCorrectionAngle">
<property name="maximum"> <property name="enabled">
<double>360.000000000000000</double> <bool>true</bool>
</property> </property>
<property name="singleStep"> <property name="sizePolicy">
<double>15.000000000000000</double> <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
</property> <horstretch>0</horstretch>
</widget> <verstretch>0</verstretch>
</item> </sizepolicy>
<item row="2" column="1"> </property>
<widget class="QDoubleSpinBox" name="ccpmAngleY"> <property name="minimumSize">
<property name="sizePolicy"> <size>
<sizepolicy hsizetype="Fixed" vsizetype="Fixed"> <width>85</width>
<horstretch>0</horstretch> <height>0</height>
<verstretch>0</verstretch> </size>
</sizepolicy> </property>
</property> <property name="maximumSize">
<property name="minimumSize"> <size>
<size> <width>85</width>
<width>85</width> <height>16777215</height>
<height>0</height> </size>
</size> </property>
</property> <property name="decimals">
<property name="maximumSize"> <number>0</number>
<size> </property>
<width>85</width> <property name="maximum">
<height>16777215</height> <double>360.000000000000000</double>
</size> </property>
</property> <property name="singleStep">
<property name="decimals"> <double>15.000000000000000</double>
<number>0</number> </property>
</property> </widget>
<property name="maximum"> </item>
<double>360.000000000000000</double> <item row="4" column="1">
</property> <widget class="QDoubleSpinBox" name="ccpmAngleZ">
<property name="singleStep"> <property name="sizePolicy">
<double>15.000000000000000</double> <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
</property> <horstretch>0</horstretch>
</widget> <verstretch>0</verstretch>
</item> </sizepolicy>
</layout> </property>
</widget> <property name="minimumSize">
</item> <size>
<item> <width>85</width>
<spacer name="verticalSpacer_5"> <height>0</height>
<property name="orientation"> </size>
<enum>Qt::Vertical</enum> </property>
</property> <property name="maximumSize">
<property name="sizeType"> <size>
<enum>QSizePolicy::MinimumExpanding</enum> <width>85</width>
</property> <height>16777215</height>
<property name="sizeHint" stdset="0"> </size>
<size> </property>
<width>20</width> <property name="decimals">
<height>0</height> <number>0</number>
</size> </property>
</property> <property name="maximum">
</spacer> <double>360.000000000000000</double>
</item> </property>
</layout> <property name="singleStep">
</item> <double>15.000000000000000</double>
<item row="0" column="1"> </property>
<widget class="QGroupBox" name="ccpmRevoMixingBox"> </widget>
<property name="enabled"> </item>
<bool>false</bool> <item row="2" column="1">
</property> <widget class="QDoubleSpinBox" name="ccpmAngleY">
<property name="sizePolicy"> <property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Expanding"> <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch> <horstretch>0</horstretch>
<verstretch>0</verstretch> <verstretch>0</verstretch>
</sizepolicy> </sizepolicy>
</property> </property>
<property name="minimumSize"> <property name="minimumSize">
<size> <size>
<width>50</width> <width>85</width>
<height>100</height> <height>0</height>
</size> </size>
</property> </property>
<property name="maximumSize"> <property name="maximumSize">
<size> <size>
<width>50</width> <width>85</width>
<height>600</height> <height>16777215</height>
</size> </size>
</property> </property>
<property name="title"> <property name="decimals">
<string>REVO</string> <number>0</number>
</property> </property>
<layout class="QVBoxLayout" name="verticalLayout_3"> <property name="maximum">
<property name="spacing"> <double>360.000000000000000</double>
<number>0</number> </property>
</property> <property name="singleStep">
<property name="margin"> <double>15.000000000000000</double>
<number>3</number> </property>
</property> </widget>
<item> </item>
<widget class="QLabel" name="label_14"> </layout>
<property name="enabled"> </widget>
<bool>false</bool> </item>
</property> <item>
<property name="font"> <widget class="QGroupBox" name="SwashplateBox_4">
<font> <property name="sizePolicy">
<pointsize>7</pointsize> <sizepolicy hsizetype="Fixed" vsizetype="Maximum">
</font> <horstretch>0</horstretch>
</property> <verstretch>0</verstretch>
<property name="text"> </sizepolicy>
<string>100%</string> </property>
</property> <property name="maximumSize">
<property name="alignment"> <size>
<set>Qt::AlignCenter</set> <width>190</width>
</property> <height>16777215</height>
</widget> </size>
</item> </property>
<item> <property name="font">
<layout class="QHBoxLayout" name="horizontalLayout_2"> <font>
<item> <pointsize>11</pointsize>
<spacer name="horizontalSpacer_5"> </font>
<property name="orientation"> </property>
<enum>Qt::Horizontal</enum> <property name="title">
</property> <string>CCPM Options</string>
<property name="sizeHint" stdset="0"> </property>
<size> <layout class="QGridLayout" name="gridLayout_21">
<width>5</width> <property name="horizontalSpacing">
<height>25</height> <number>3</number>
</size> </property>
</property> <property name="verticalSpacing">
</spacer> <number>2</number>
</item> </property>
<item> <property name="margin">
<widget class="QSlider" name="ccpmRevoSlider"> <number>3</number>
<property name="enabled"> </property>
<bool>false</bool> <item row="1" column="0">
</property> <widget class="QCheckBox" name="ccpmCollectivePassthrough">
<property name="sizePolicy"> <property name="text">
<sizepolicy hsizetype="Fixed" vsizetype="Expanding"> <string>Collective Pass through</string>
<horstretch>0</horstretch> </property>
<verstretch>0</verstretch> </widget>
</sizepolicy> </item>
</property> <item row="4" column="0">
<property name="minimumSize"> <widget class="QCheckBox" name="ccpmLinkRoll">
<size> <property name="text">
<width>0</width> <string>Link Roll/Pitch</string>
<height>100</height> </property>
</size> <property name="checked">
</property> <bool>true</bool>
<property name="maximum"> </property>
<number>100</number> </widget>
</property> </item>
<property name="singleStep"> <item row="3" column="0">
<number>5</number> <widget class="QCheckBox" name="ccpmLinkCyclic">
</property> <property name="text">
<property name="orientation"> <string>Link Cyclic/Collective</string>
<enum>Qt::Vertical</enum> </property>
</property> <property name="checked">
</widget> <bool>true</bool>
</item> </property>
<item> </widget>
<spacer name="horizontalSpacer_4"> </item>
<property name="orientation"> <item row="2" column="0">
<enum>Qt::Horizontal</enum> <layout class="QHBoxLayout" name="ccpmCollectiveChannelBox">
</property> <property name="sizeConstraint">
<property name="sizeHint" stdset="0"> <enum>QLayout::SetNoConstraint</enum>
<size> </property>
<width>5</width> <item>
<height>25</height> <widget class="QLabel" name="ccpmCollectiveChLabel">
</size> <property name="enabled">
</property> <bool>true</bool>
</spacer> </property>
</item> <property name="sizePolicy">
</layout> <sizepolicy hsizetype="Fixed" vsizetype="Preferred">
</item> <horstretch>0</horstretch>
<item> <verstretch>0</verstretch>
<widget class="QLabel" name="label_13"> </sizepolicy>
<property name="enabled"> </property>
<bool>false</bool> <property name="minimumSize">
</property> <size>
<property name="font"> <width>80</width>
<font> <height>0</height>
<pointsize>7</pointsize> </size>
</font> </property>
</property> <property name="maximumSize">
<property name="text"> <size>
<string>0%</string> <width>80</width>
</property> <height>16777215</height>
<property name="alignment"> </size>
<set>Qt::AlignCenter</set> </property>
</property> <property name="font">
</widget> <font>
</item> <pointsize>11</pointsize>
<item> </font>
<widget class="QSpinBox" name="ccpmREVOspinBox"/> </property>
</item> <property name="layoutDirection">
</layout> <enum>Qt::LeftToRight</enum>
</widget> </property>
</item> <property name="text">
<item row="0" column="2"> <string>Collective Ch</string>
<widget class="QGroupBox" name="ccpmPitchMixingBox"> </property>
<property name="enabled"> <property name="alignment">
<bool>true</bool> <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property> </property>
<property name="sizePolicy"> <property name="wordWrap">
<sizepolicy hsizetype="Fixed" vsizetype="Expanding"> <bool>true</bool>
<horstretch>0</horstretch> </property>
<verstretch>0</verstretch> </widget>
</sizepolicy> </item>
</property> <item>
<property name="minimumSize"> <widget class="QComboBox" name="ccpmCollectiveChannel">
<size> <property name="enabled">
<width>50</width> <bool>true</bool>
<height>100</height> </property>
</size> <property name="sizePolicy">
</property> <sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
<property name="maximumSize"> <horstretch>0</horstretch>
<size> <verstretch>0</verstretch>
<width>50</width> </sizepolicy>
<height>600</height> </property>
</size> <property name="minimumSize">
</property> <size>
<property name="font"> <width>90</width>
<font> <height>0</height>
<pointsize>8</pointsize> </size>
</font> </property>
</property> <property name="maximumSize">
<property name="title"> <size>
<string>CCPM</string> <width>100</width>
</property> <height>16777215</height>
<property name="alignment"> </size>
<set>Qt::AlignCenter</set> </property>
</property> </widget>
<layout class="QVBoxLayout" name="verticalLayout_4"> </item>
<property name="spacing"> </layout>
<number>0</number> </item>
</property> </layout>
<property name="margin"> </widget>
<number>3</number> </item>
</property> <item>
<item> <spacer name="verticalSpacer_3">
<widget class="QLabel" name="label_15"> <property name="orientation">
<property name="enabled"> <enum>Qt::Vertical</enum>
<bool>true</bool> </property>
</property> <property name="sizeHint" stdset="0">
<property name="font"> <size>
<font> <width>20</width>
<pointsize>7</pointsize> <height>40</height>
</font> </size>
</property> </property>
<property name="text"> </spacer>
<string>Collective</string> </item>
</property> </layout>
<property name="scaledContents"> </item>
<bool>true</bool> <item row="0" column="10">
</property> <layout class="QVBoxLayout" name="ccpmSwashImageBox_2">
<property name="alignment"> <property name="topMargin">
<set>Qt::AlignCenter</set> <number>0</number>
</property> </property>
</widget> <property name="rightMargin">
</item> <number>0</number>
<item> </property>
<layout class="QHBoxLayout" name="horizontalLayout"> <item>
<item> <widget class="QGroupBox" name="ccpmSwashImageBox">
<spacer name="horizontalSpacer_3"> <property name="sizePolicy">
<property name="orientation"> <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<enum>Qt::Horizontal</enum> <horstretch>1</horstretch>
</property> <verstretch>1</verstretch>
<property name="sizeHint" stdset="0"> </sizepolicy>
<size> </property>
<width>5</width> <property name="minimumSize">
<height>25</height> <size>
</size> <width>200</width>
</property> <height>200</height>
</spacer> </size>
</item> </property>
<item> <property name="maximumSize">
<widget class="QSlider" name="ccpmCollectiveSlider"> <size>
<property name="enabled"> <width>600</width>
<bool>true</bool> <height>600</height>
</property> </size>
<property name="sizePolicy"> </property>
<sizepolicy hsizetype="Fixed" vsizetype="Expanding"> <property name="sizeIncrement">
<horstretch>0</horstretch> <size>
<verstretch>0</verstretch> <width>10</width>
</sizepolicy> <height>10</height>
</property> </size>
<property name="minimumSize"> </property>
<size> <property name="baseSize">
<width>0</width> <size>
<height>100</height> <width>200</width>
</size> <height>200</height>
</property> </size>
<property name="maximum"> </property>
<number>100</number> <property name="font">
</property> <font>
<property name="singleStep"> <pointsize>11</pointsize>
<number>5</number> </font>
</property> </property>
<property name="value"> <property name="title">
<number>50</number> <string>Swashplate Layout</string>
</property> </property>
<property name="orientation"> <property name="alignment">
<enum>Qt::Vertical</enum> <set>Qt::AlignHCenter|Qt::AlignTop</set>
</property> </property>
</widget> <property name="flat">
</item> <bool>false</bool>
<item> </property>
<spacer name="horizontalSpacer_2"> <property name="checkable">
<property name="orientation"> <bool>false</bool>
<enum>Qt::Horizontal</enum> </property>
</property> <layout class="QGridLayout" name="gridLayout_10">
<property name="sizeHint" stdset="0"> <property name="horizontalSpacing">
<size> <number>3</number>
<width>5</width> </property>
<height>25</height> <property name="margin">
</size> <number>3</number>
</property> </property>
</spacer> <item row="0" column="0">
</item> <widget class="QSplitter" name="splitter_3">
</layout> <property name="orientation">
</item> <enum>Qt::Vertical</enum>
<item> </property>
<widget class="QLabel" name="label_16"> <widget class="QGraphicsView" name="SwashplateImage">
<property name="enabled"> <property name="sizePolicy">
<bool>true</bool> <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
</property> <horstretch>1</horstretch>
<property name="font"> <verstretch>1</verstretch>
<font> </sizepolicy>
<pointsize>7</pointsize> </property>
</font> <property name="minimumSize">
</property> <size>
<property name="text"> <width>10</width>
<string>Cyclic</string> <height>10</height>
</property> </size>
<property name="alignment"> </property>
<set>Qt::AlignCenter</set> <property name="maximumSize">
</property> <size>
</widget> <width>1000</width>
</item> <height>1000</height>
<item> </size>
<widget class="QSpinBox" name="ccpmCollectivespinBox"> </property>
<property name="maximum"> <property name="sizeIncrement">
<number>100</number> <size>
</property> <width>10</width>
<property name="singleStep"> <height>10</height>
<number>5</number> </size>
</property> </property>
<property name="value"> <property name="baseSize">
<number>50</number> <size>
</property> <width>200</width>
</widget> <height>200</height>
</item> </size>
</layout> </property>
</widget> <property name="frameShape">
</item> <enum>QFrame::Box</enum>
<item row="0" column="3"> </property>
<layout class="QVBoxLayout" name="verticalLayout_9"> <property name="frameShadow">
<item> <enum>QFrame::Plain</enum>
<widget class="QGroupBox" name="ccpmSwashImageBox"> </property>
<property name="sizePolicy"> <property name="lineWidth">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding"> <number>1</number>
<horstretch>1</horstretch> </property>
<verstretch>1</verstretch> <property name="verticalScrollBarPolicy">
</sizepolicy> <enum>Qt::ScrollBarAlwaysOff</enum>
</property> </property>
<property name="minimumSize"> <property name="horizontalScrollBarPolicy">
<size> <enum>Qt::ScrollBarAlwaysOff</enum>
<width>200</width> </property>
<height>200</height> <property name="backgroundBrush">
</size> <brush brushstyle="DiagCrossPattern">
</property> <color alpha="50">
<property name="maximumSize"> <red>112</red>
<size> <green>184</green>
<width>600</width> <blue>138</blue>
<height>600</height> </color>
</size> </brush>
</property> </property>
<property name="sizeIncrement"> <property name="foregroundBrush">
<size> <brush brushstyle="SolidPattern">
<width>10</width> <color alpha="0">
<height>10</height> <red>127</red>
</size> <green>127</green>
</property> <blue>127</blue>
<property name="baseSize"> </color>
<size> </brush>
<width>200</width> </property>
<height>200</height> <property name="sceneRect">
</size> <rectf>
</property> <x>0.000000000000000</x>
<property name="title"> <y>0.000000000000000</y>
<string>Swashplate Layout</string> <width>400.000000000000000</width>
</property> <height>400.000000000000000</height>
<property name="alignment"> </rectf>
<set>Qt::AlignHCenter|Qt::AlignTop</set> </property>
</property> <property name="alignment">
<property name="flat"> <set>Qt::AlignCenter</set>
<bool>false</bool> </property>
</property> <property name="resizeAnchor">
<property name="checkable"> <enum>QGraphicsView::AnchorViewCenter</enum>
<bool>false</bool> </property>
</property> </widget>
<layout class="QGridLayout" name="gridLayout_10"> </widget>
<property name="horizontalSpacing"> </item>
<number>3</number> </layout>
</property> </widget>
<property name="margin"> </item>
<number>3</number> </layout>
</property> </item>
<item row="0" column="0"> <item row="0" column="3">
<widget class="QSplitter" name="splitter_3"> <layout class="QHBoxLayout" name="horizontalLayout_10">
<property name="orientation"> <property name="sizeConstraint">
<enum>Qt::Vertical</enum> <enum>QLayout::SetNoConstraint</enum>
</property> </property>
<widget class="QGraphicsView" name="SwashplateImage"> <property name="rightMargin">
<property name="sizePolicy"> <number>3</number>
<sizepolicy hsizetype="Preferred" vsizetype="Preferred"> </property>
<horstretch>1</horstretch> <property name="bottomMargin">
<verstretch>1</verstretch> <number>3</number>
</sizepolicy> </property>
</property> <item>
<property name="minimumSize"> <widget class="QGroupBox" name="ccpmRevoMixingBox">
<size> <property name="enabled">
<width>200</width> <bool>true</bool>
<height>200</height> </property>
</size> <property name="sizePolicy">
</property> <sizepolicy hsizetype="Fixed" vsizetype="Expanding">
<property name="maximumSize"> <horstretch>0</horstretch>
<size> <verstretch>0</verstretch>
<width>500</width> </sizepolicy>
<height>500</height> </property>
</size> <property name="minimumSize">
</property> <size>
<property name="sizeIncrement"> <width>50</width>
<size> <height>100</height>
<width>10</width> </size>
<height>10</height> </property>
</size> <property name="maximumSize">
</property> <size>
<property name="baseSize"> <width>50</width>
<size> <height>600</height>
<width>200</width> </size>
<height>200</height> </property>
</size> <property name="font">
</property> <font>
<property name="frameShape"> <pointsize>8</pointsize>
<enum>QFrame::Box</enum> </font>
</property> </property>
<property name="frameShadow"> <property name="title">
<enum>QFrame::Plain</enum> <string>REVO</string>
</property> </property>
<property name="lineWidth"> <layout class="QVBoxLayout" name="verticalLayout_3">
<number>1</number> <property name="spacing">
</property> <number>0</number>
<property name="verticalScrollBarPolicy"> </property>
<enum>Qt::ScrollBarAlwaysOff</enum> <property name="margin">
</property> <number>3</number>
<property name="horizontalScrollBarPolicy"> </property>
<enum>Qt::ScrollBarAlwaysOff</enum> <item>
</property> <widget class="QLabel" name="label_14">
<property name="backgroundBrush"> <property name="enabled">
<brush brushstyle="DiagCrossPattern"> <bool>false</bool>
<color alpha="50"> </property>
<red>112</red> <property name="font">
<green>184</green> <font>
<blue>138</blue> <pointsize>7</pointsize>
</color> </font>
</brush> </property>
</property> <property name="text">
<property name="foregroundBrush"> <string>100%</string>
<brush brushstyle="SolidPattern"> </property>
<color alpha="0"> <property name="alignment">
<red>127</red> <set>Qt::AlignCenter</set>
<green>127</green> </property>
<blue>127</blue> </widget>
</color> </item>
</brush> <item>
</property> <layout class="QHBoxLayout" name="horizontalLayout_2">
<property name="sceneRect"> <item>
<rectf> <spacer name="horizontalSpacer_5">
<x>0.000000000000000</x> <property name="orientation">
<y>0.000000000000000</y> <enum>Qt::Horizontal</enum>
<width>400.000000000000000</width> </property>
<height>400.000000000000000</height> <property name="sizeHint" stdset="0">
</rectf> <size>
</property> <width>5</width>
<property name="alignment"> <height>25</height>
<set>Qt::AlignCenter</set> </size>
</property> </property>
<property name="resizeAnchor"> </spacer>
<enum>QGraphicsView::AnchorViewCenter</enum> </item>
</property> <item>
</widget> <widget class="QSlider" name="ccpmRevoSlider">
</widget> <property name="enabled">
</item> <bool>true</bool>
</layout> </property>
</widget> <property name="sizePolicy">
</item> <sizepolicy hsizetype="Fixed" vsizetype="Expanding">
</layout> <horstretch>0</horstretch>
</item> <verstretch>0</verstretch>
</layout> </sizepolicy>
</widget> </property>
<widget class="QWidget" name="SwashPlateLevel"> <property name="minimumSize">
<attribute name="title"> <size>
<string>Swashplate Levelling</string> <width>0</width>
</attribute> <height>100</height>
<layout class="QGridLayout" name="gridLayout_8"> </size>
<property name="margin"> </property>
<number>3</number> <property name="maximum">
</property> <number>100</number>
<property name="spacing"> </property>
<number>3</number> <property name="singleStep">
</property> <number>5</number>
<item row="0" column="0"> </property>
<layout class="QVBoxLayout" name="verticalLayout_8"> <property name="orientation">
<property name="leftMargin"> <enum>Qt::Vertical</enum>
<number>3</number> </property>
</property> </widget>
<item> </item>
<widget class="QGroupBox" name="SwashLvlInstructionsBox"> <item>
<property name="sizePolicy"> <spacer name="horizontalSpacer_4">
<sizepolicy hsizetype="Fixed" vsizetype="Maximum"> <property name="orientation">
<horstretch>0</horstretch> <enum>Qt::Horizontal</enum>
<verstretch>0</verstretch> </property>
</sizepolicy> <property name="sizeHint" stdset="0">
</property> <size>
<property name="minimumSize"> <width>5</width>
<size> <height>25</height>
<width>228</width> </size>
<height>0</height> </property>
</size> </spacer>
</property> </item>
<property name="title"> </layout>
<string>Commands</string> </item>
</property> <item>
<layout class="QVBoxLayout" name="verticalLayout"> <widget class="QLabel" name="label_13">
<property name="margin"> <property name="enabled">
<number>3</number> <bool>false</bool>
</property> </property>
<item> <property name="font">
<layout class="QHBoxLayout" name="horizontalLayout_9"> <font>
<property name="spacing"> <pointsize>7</pointsize>
<number>0</number> </font>
</property> </property>
<item> <property name="text">
<widget class="QPushButton" name="SwashLvlStartButton"> <string>0%</string>
<property name="minimumSize"> </property>
<size> <property name="alignment">
<width>85</width> <set>Qt::AlignCenter</set>
<height>0</height> </property>
</size> </widget>
</property> </item>
<property name="maximumSize"> <item>
<size> <widget class="QSpinBox" name="ccpmREVOspinBox"/>
<width>85</width> </item>
<height>16777215</height> </layout>
</size> </widget>
</property> </item>
<property name="text"> <item>
<string>Start</string> <widget class="QGroupBox" name="ccpmPitchMixingBox">
</property> <property name="enabled">
</widget> <bool>true</bool>
</item> </property>
<item> <property name="sizePolicy">
<widget class="QPushButton" name="SwashLvlNextButton"> <sizepolicy hsizetype="Fixed" vsizetype="Expanding">
<property name="enabled"> <horstretch>0</horstretch>
<bool>false</bool> <verstretch>0</verstretch>
</property> </sizepolicy>
<property name="minimumSize"> </property>
<size> <property name="minimumSize">
<width>85</width> <size>
<height>0</height> <width>50</width>
</size> <height>100</height>
</property> </size>
<property name="maximumSize"> </property>
<size> <property name="maximumSize">
<width>85</width> <size>
<height>16777215</height> <width>50</width>
</size> <height>600</height>
</property> </size>
<property name="text"> </property>
<string>Next</string> <property name="font">
</property> <font>
</widget> <pointsize>8</pointsize>
</item> </font>
</layout> </property>
</item> <property name="title">
<item> <string>CCPM</string>
<widget class="QTextEdit" name="SwashLvlStepInstruction"> </property>
<property name="minimumSize"> <property name="alignment">
<size> <set>Qt::AlignCenter</set>
<width>0</width> </property>
<height>150</height> <layout class="QVBoxLayout" name="verticalLayout_4">
</size> <property name="spacing">
</property> <number>0</number>
<property name="maximumSize"> </property>
<size> <property name="margin">
<width>220</width> <number>3</number>
<height>450</height> </property>
</size> <item>
</property> <widget class="QLabel" name="label_15">
<property name="horizontalScrollBarPolicy"> <property name="enabled">
<enum>Qt::ScrollBarAlwaysOff</enum> <bool>true</bool>
</property> </property>
<property name="readOnly"> <property name="font">
<bool>true</bool> <font>
</property> <pointsize>7</pointsize>
</widget> </font>
</item> </property>
<item> <property name="text">
<layout class="QGridLayout" name="gridLayout_3"> <string>Collective</string>
<item row="0" column="0"> </property>
<widget class="QPushButton" name="SwashLvlCancelButton"> <property name="scaledContents">
<property name="enabled"> <bool>true</bool>
<bool>false</bool> </property>
</property> <property name="alignment">
<property name="minimumSize"> <set>Qt::AlignCenter</set>
<size> </property>
<width>170</width> </widget>
<height>0</height> </item>
</size> <item>
</property> <layout class="QHBoxLayout" name="horizontalLayout">
<property name="maximumSize"> <item>
<size> <spacer name="horizontalSpacer_3">
<width>170</width> <property name="orientation">
<height>16777215</height> <enum>Qt::Horizontal</enum>
</size> </property>
</property> <property name="sizeHint" stdset="0">
<property name="text"> <size>
<string>Cancel</string> <width>5</width>
</property> <height>25</height>
</widget> </size>
</item> </property>
<item row="1" column="0"> </spacer>
<widget class="QPushButton" name="SwashLvlFinishButton"> </item>
<property name="enabled"> <item>
<bool>false</bool> <widget class="QSlider" name="ccpmCollectiveSlider">
</property> <property name="enabled">
<property name="minimumSize"> <bool>true</bool>
<size> </property>
<width>170</width> <property name="sizePolicy">
<height>0</height> <sizepolicy hsizetype="Fixed" vsizetype="Expanding">
</size> <horstretch>0</horstretch>
</property> <verstretch>0</verstretch>
<property name="maximumSize"> </sizepolicy>
<size> </property>
<width>170</width> <property name="minimumSize">
<height>16777215</height> <size>
</size> <width>0</width>
</property> <height>100</height>
<property name="text"> </size>
<string>Finish</string> </property>
</property> <property name="maximum">
</widget> <number>100</number>
</item> </property>
</layout> <property name="singleStep">
</item> <number>5</number>
</layout> </property>
</widget> <property name="value">
</item> <number>50</number>
<item> </property>
<widget class="QGroupBox" name="SwashLvlStatusBox"> <property name="orientation">
<property name="sizePolicy"> <enum>Qt::Vertical</enum>
<sizepolicy hsizetype="Fixed" vsizetype="Maximum"> </property>
<horstretch>0</horstretch> </widget>
<verstretch>0</verstretch> </item>
</sizepolicy> <item>
</property> <spacer name="horizontalSpacer_2">
<property name="minimumSize"> <property name="orientation">
<size> <enum>Qt::Horizontal</enum>
<width>200</width> </property>
<height>0</height> <property name="sizeHint" stdset="0">
</size> <size>
</property> <width>5</width>
<property name="title"> <height>25</height>
<string>Status</string> </size>
</property> </property>
<layout class="QGridLayout" name="gridLayout_22"> </spacer>
<property name="horizontalSpacing"> </item>
<number>3</number> </layout>
</property> </item>
<property name="verticalSpacing"> <item>
<number>2</number> <widget class="QLabel" name="label_16">
</property> <property name="enabled">
<property name="margin"> <bool>true</bool>
<number>3</number> </property>
</property> <property name="font">
<item row="1" column="0"> <font>
<widget class="QListWidget" name="SwashLvlStepList"> <pointsize>7</pointsize>
<property name="minimumSize"> </font>
<size> </property>
<width>220</width> <property name="text">
<height>0</height> <string>Cyclic</string>
</size> </property>
</property> <property name="alignment">
<property name="maximumSize"> <set>Qt::AlignCenter</set>
<size> </property>
<width>190</width> </widget>
<height>125</height> </item>
</size> <item>
</property> <widget class="QSpinBox" name="ccpmCollectivespinBox">
<property name="editTriggers"> <property name="maximum">
<set>QAbstractItemView::NoEditTriggers</set> <number>100</number>
</property> </property>
<property name="alternatingRowColors"> <property name="singleStep">
<bool>true</bool> <number>5</number>
</property> </property>
<property name="selectionMode"> <property name="value">
<enum>QAbstractItemView::NoSelection</enum> <number>50</number>
</property> </property>
<property name="selectionBehavior"> </widget>
<enum>QAbstractItemView::SelectRows</enum> </item>
</property> </layout>
<item> </widget>
<property name="text"> </item>
<string>Neutral</string> <item>
</property> <widget class="QGroupBox" name="ccpmCollectiveScalingBox">
<property name="icon"> <property name="enabled">
<iconset> <bool>true</bool>
<normaloff>:/configgadget/images/none.png</normaloff> </property>
<normalon>:/configgadget/images/ok.png</normalon>:/configgadget/images/none.png</iconset> <property name="sizePolicy">
</property> <sizepolicy hsizetype="Fixed" vsizetype="Expanding">
</item> <horstretch>0</horstretch>
<item> <verstretch>0</verstretch>
<property name="text"> </sizepolicy>
<string>Max</string> </property>
</property> <property name="minimumSize">
<property name="icon"> <size>
<iconset> <width>50</width>
<normaloff>:/configgadget/images/none.png</normaloff> <height>100</height>
<normalon>:/configgadget/images/ok.png</normalon>:/configgadget/images/none.png</iconset> </size>
</property> </property>
</item> <property name="maximumSize">
<item> <size>
<property name="text"> <width>50</width>
<string>Min</string> <height>600</height>
</property> </size>
<property name="icon"> </property>
<iconset> <property name="font">
<normaloff>:/configgadget/images/none.png</normaloff> <font>
<normalon>:/configgadget/images/ok.png</normalon>:/configgadget/images/none.png</iconset> <pointsize>8</pointsize>
</property> </font>
<property name="flags"> </property>
<set>ItemIsSelectable|ItemIsEnabled</set> <property name="title">
</property> <string>Collective</string>
</item> </property>
<item> <property name="alignment">
<property name="text"> <set>Qt::AlignCenter</set>
<string>Verify</string> </property>
</property> <layout class="QVBoxLayout" name="verticalLayout_12">
<property name="icon"> <property name="spacing">
<iconset> <number>0</number>
<normaloff>:/configgadget/images/none.png</normaloff> </property>
<normalon>:/configgadget/images/ok.png</normalon>:/configgadget/images/none.png</iconset> <property name="margin">
</property> <number>3</number>
<property name="flags"> </property>
<set>ItemIsEnabled</set> <item>
</property> <layout class="QHBoxLayout" name="horizontalLayout_11">
</item> <item>
</widget> <spacer name="horizontalSpacer_15">
</item> <property name="orientation">
</layout> <enum>Qt::Horizontal</enum>
</widget> </property>
</item> <property name="sizeHint" stdset="0">
<item> <size>
<spacer name="verticalSpacer_4"> <width>5</width>
<property name="orientation"> <height>25</height>
<enum>Qt::Vertical</enum> </size>
</property> </property>
<property name="sizeType"> </spacer>
<enum>QSizePolicy::MinimumExpanding</enum> </item>
</property> <item>
<property name="sizeHint" stdset="0"> <widget class="QSlider" name="ccpmCollectiveScale">
<size> <property name="enabled">
<width>20</width> <bool>true</bool>
<height>0</height> </property>
</size> <property name="sizePolicy">
</property> <sizepolicy hsizetype="Fixed" vsizetype="Expanding">
</spacer> <horstretch>0</horstretch>
</item> <verstretch>0</verstretch>
</layout> </sizepolicy>
</item> </property>
<item row="0" column="1"> <property name="minimumSize">
<widget class="QGroupBox" name="SwashLvlccpmSliderBox"> <size>
<property name="enabled"> <width>0</width>
<bool>true</bool> <height>100</height>
</property> </size>
<property name="sizePolicy"> </property>
<sizepolicy hsizetype="Fixed" vsizetype="Expanding"> <property name="maximum">
<horstretch>0</horstretch> <number>100</number>
<verstretch>0</verstretch> </property>
</sizepolicy> <property name="singleStep">
</property> <number>5</number>
<property name="minimumSize"> </property>
<size> <property name="value">
<width>50</width> <number>50</number>
<height>100</height> </property>
</size> <property name="orientation">
</property> <enum>Qt::Vertical</enum>
<property name="maximumSize"> </property>
<size> </widget>
<width>50</width> </item>
<height>600</height> <item>
</size> <spacer name="horizontalSpacer_16">
</property> <property name="orientation">
<property name="font"> <enum>Qt::Horizontal</enum>
<font> </property>
<pointsize>8</pointsize> <property name="sizeHint" stdset="0">
</font> <size>
</property> <width>5</width>
<property name="title"> <height>25</height>
<string>Position</string> </size>
</property> </property>
<property name="alignment"> </spacer>
<set>Qt::AlignCenter</set> </item>
</property> </layout>
<layout class="QVBoxLayout" name="verticalLayout_5"> </item>
<property name="spacing"> <item>
<number>0</number> <widget class="QSpinBox" name="ccpmCollectiveScaleBox">
</property> <property name="maximum">
<property name="margin"> <number>100</number>
<number>3</number> </property>
</property> <property name="singleStep">
<item> <number>5</number>
<widget class="QLabel" name="label_17"> </property>
<property name="enabled"> <property name="value">
<bool>true</bool> <number>50</number>
</property> </property>
<property name="font"> </widget>
<font> </item>
<pointsize>7</pointsize> </layout>
</font> </widget>
</property> </item>
<property name="text"> <item>
<string>Max</string> <widget class="QGroupBox" name="ccpmCyclicScalingBox">
</property> <property name="enabled">
<property name="scaledContents"> <bool>true</bool>
<bool>true</bool> </property>
</property> <property name="sizePolicy">
<property name="alignment"> <sizepolicy hsizetype="Fixed" vsizetype="Expanding">
<set>Qt::AlignCenter</set> <horstretch>0</horstretch>
</property> <verstretch>0</verstretch>
</widget> </sizepolicy>
</item> </property>
<item> <property name="minimumSize">
<layout class="QHBoxLayout" name="horizontalLayout_4"> <size>
<item> <width>50</width>
<spacer name="horizontalSpacer_7"> <height>100</height>
<property name="orientation"> </size>
<enum>Qt::Horizontal</enum> </property>
</property> <property name="maximumSize">
<property name="sizeHint" stdset="0"> <size>
<size> <width>50</width>
<width>5</width> <height>600</height>
<height>25</height> </size>
</size> </property>
</property> <property name="font">
</spacer> <font>
</item> <pointsize>8</pointsize>
<item> </font>
<widget class="QSlider" name="SwashLvlPositionSlider"> </property>
<property name="enabled"> <property name="title">
<bool>true</bool> <string>Cyclic</string>
</property> </property>
<property name="sizePolicy"> <property name="alignment">
<sizepolicy hsizetype="Fixed" vsizetype="Expanding"> <set>Qt::AlignCenter</set>
<horstretch>0</horstretch> </property>
<verstretch>0</verstretch> <property name="checkable">
</sizepolicy> <bool>false</bool>
</property> </property>
<property name="minimumSize"> <layout class="QVBoxLayout" name="verticalLayout_7">
<size> <property name="spacing">
<width>0</width> <number>0</number>
<height>100</height> </property>
</size> <property name="margin">
</property> <number>3</number>
<property name="maximum"> </property>
<number>100</number> <item>
</property> <layout class="QHBoxLayout" name="horizontalLayout_7">
<property name="singleStep"> <item>
<number>5</number> <spacer name="horizontalSpacer_9">
</property> <property name="orientation">
<property name="value"> <enum>Qt::Horizontal</enum>
<number>50</number> </property>
</property> <property name="sizeHint" stdset="0">
<property name="orientation"> <size>
<enum>Qt::Vertical</enum> <width>5</width>
</property> <height>25</height>
</widget> </size>
</item> </property>
<item> </spacer>
<spacer name="horizontalSpacer_8"> </item>
<property name="orientation"> <item>
<enum>Qt::Horizontal</enum> <widget class="QSlider" name="ccpmCyclicScale">
</property> <property name="enabled">
<property name="sizeHint" stdset="0"> <bool>true</bool>
<size> </property>
<width>5</width> <property name="sizePolicy">
<height>25</height> <sizepolicy hsizetype="Fixed" vsizetype="Expanding">
</size> <horstretch>0</horstretch>
</property> <verstretch>0</verstretch>
</spacer> </sizepolicy>
</item> </property>
</layout> <property name="minimumSize">
</item> <size>
<item> <width>0</width>
<widget class="QLabel" name="label_18"> <height>100</height>
<property name="enabled"> </size>
<bool>true</bool> </property>
</property> <property name="maximum">
<property name="font"> <number>100</number>
<font> </property>
<pointsize>7</pointsize> <property name="singleStep">
</font> <number>5</number>
</property> </property>
<property name="text"> <property name="value">
<string>Min</string> <number>50</number>
</property> </property>
<property name="alignment"> <property name="orientation">
<set>Qt::AlignCenter</set> <enum>Qt::Vertical</enum>
</property> </property>
</widget> </widget>
</item> </item>
<item> <item>
<widget class="QSpinBox" name="SwashLvlPositionSpinBox"> <spacer name="horizontalSpacer_10">
<property name="maximum"> <property name="orientation">
<number>100</number> <enum>Qt::Horizontal</enum>
</property> </property>
<property name="singleStep"> <property name="sizeHint" stdset="0">
<number>5</number> <size>
</property> <width>5</width>
<property name="value"> <height>25</height>
<number>50</number> </size>
</property> </property>
</widget> </spacer>
</item> </item>
</layout> </layout>
</widget> </item>
</item> <item>
<item row="0" column="2"> <widget class="QSpinBox" name="ccpmCyclicScaleBox">
<widget class="QGroupBox" name="SwashLvlccpmSwashImageBox"> <property name="maximum">
<property name="sizePolicy"> <number>100</number>
<sizepolicy hsizetype="Expanding" vsizetype="Expanding"> </property>
<horstretch>1</horstretch> <property name="singleStep">
<verstretch>1</verstretch> <number>5</number>
</sizepolicy> </property>
</property> <property name="value">
<property name="minimumSize"> <number>50</number>
<size> </property>
<width>200</width> </widget>
<height>200</height> </item>
</size> </layout>
</property> </widget>
<property name="maximumSize"> </item>
<size> <item>
<width>600</width> <widget class="QGroupBox" name="ccpmPitchScalingBox">
<height>600</height> <property name="enabled">
</size> <bool>true</bool>
</property> </property>
<property name="sizeIncrement"> <property name="sizePolicy">
<size> <sizepolicy hsizetype="Fixed" vsizetype="Expanding">
<width>10</width> <horstretch>0</horstretch>
<height>10</height> <verstretch>0</verstretch>
</size> </sizepolicy>
</property> </property>
<property name="baseSize"> <property name="minimumSize">
<size> <size>
<width>200</width> <width>50</width>
<height>200</height> <height>100</height>
</size> </size>
</property> </property>
<property name="title"> <property name="maximumSize">
<string>Swashplate Adjustment</string> <size>
</property> <width>50</width>
<property name="alignment"> <height>600</height>
<set>Qt::AlignHCenter|Qt::AlignTop</set> </size>
</property> </property>
<property name="flat"> <property name="font">
<bool>false</bool> <font>
</property> <pointsize>8</pointsize>
<property name="checkable"> </font>
<bool>false</bool> </property>
</property> <property name="title">
<layout class="QGridLayout" name="gridLayout_11"> <string>Pitch</string>
<property name="horizontalSpacing"> </property>
<number>3</number> <property name="alignment">
</property> <set>Qt::AlignCenter</set>
<property name="margin"> </property>
<number>3</number> <layout class="QVBoxLayout" name="verticalLayout_13">
</property> <property name="spacing">
<item row="0" column="0"> <number>0</number>
<widget class="QSplitter" name="splitter_4"> </property>
<property name="orientation"> <property name="margin">
<enum>Qt::Vertical</enum> <number>3</number>
</property> </property>
<widget class="QGraphicsView" name="SwashLvlSwashplateImage"> <item>
<property name="sizePolicy"> <layout class="QHBoxLayout" name="horizontalLayout_12">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred"> <item>
<horstretch>1</horstretch> <spacer name="horizontalSpacer_17">
<verstretch>1</verstretch> <property name="orientation">
</sizepolicy> <enum>Qt::Horizontal</enum>
</property> </property>
<property name="minimumSize"> <property name="sizeHint" stdset="0">
<size> <size>
<width>200</width> <width>5</width>
<height>200</height> <height>25</height>
</size> </size>
</property> </property>
<property name="maximumSize"> </spacer>
<size> </item>
<width>500</width> <item>
<height>500</height> <widget class="QSlider" name="ccpmPitchScale">
</size> <property name="enabled">
</property> <bool>true</bool>
<property name="sizeIncrement"> </property>
<size> <property name="sizePolicy">
<width>10</width> <sizepolicy hsizetype="Fixed" vsizetype="Expanding">
<height>10</height> <horstretch>0</horstretch>
</size> <verstretch>0</verstretch>
</property> </sizepolicy>
<property name="baseSize"> </property>
<size> <property name="minimumSize">
<width>200</width> <size>
<height>200</height> <width>0</width>
</size> <height>100</height>
</property> </size>
<property name="frameShape"> </property>
<enum>QFrame::Box</enum> <property name="maximum">
</property> <number>100</number>
<property name="frameShadow"> </property>
<enum>QFrame::Plain</enum> <property name="singleStep">
</property> <number>5</number>
<property name="lineWidth"> </property>
<number>1</number> <property name="value">
</property> <number>50</number>
<property name="midLineWidth"> </property>
<number>0</number> <property name="orientation">
</property> <enum>Qt::Vertical</enum>
<property name="verticalScrollBarPolicy"> </property>
<enum>Qt::ScrollBarAlwaysOff</enum> </widget>
</property> </item>
<property name="horizontalScrollBarPolicy"> <item>
<enum>Qt::ScrollBarAlwaysOff</enum> <spacer name="horizontalSpacer_18">
</property> <property name="orientation">
<property name="backgroundBrush"> <enum>Qt::Horizontal</enum>
<brush brushstyle="DiagCrossPattern"> </property>
<color alpha="25"> <property name="sizeHint" stdset="0">
<red>126</red> <size>
<green>176</green> <width>5</width>
<blue>220</blue> <height>25</height>
</color> </size>
</brush> </property>
</property> </spacer>
<property name="foregroundBrush"> </item>
<brush brushstyle="NoBrush"> </layout>
<color alpha="255"> </item>
<red>0</red> <item>
<green>0</green> <widget class="QSpinBox" name="ccpmPitchScaleBox">
<blue>0</blue> <property name="maximum">
</color> <number>100</number>
</brush> </property>
</property> <property name="singleStep">
<property name="sceneRect"> <number>5</number>
<rectf> </property>
<x>0.000000000000000</x> <property name="value">
<y>0.000000000000000</y> <number>50</number>
<width>400.000000000000000</width> </property>
<height>400.000000000000000</height> </widget>
</rectf> </item>
</property> </layout>
<property name="alignment"> </widget>
<set>Qt::AlignCenter</set> </item>
</property> <item>
<property name="resizeAnchor"> <widget class="QGroupBox" name="ccpmRollScalingBox">
<enum>QGraphicsView::AnchorViewCenter</enum> <property name="enabled">
</property> <bool>true</bool>
</widget> </property>
</widget> <property name="sizePolicy">
</item> <sizepolicy hsizetype="Fixed" vsizetype="Expanding">
</layout> <horstretch>0</horstretch>
</widget> <verstretch>0</verstretch>
</item> </sizepolicy>
</layout> </property>
</widget> <property name="minimumSize">
<widget class="QWidget" name="CurveTab"> <size>
<attribute name="title"> <width>50</width>
<string>Curve settings</string> <height>100</height>
</attribute> </size>
<layout class="QGridLayout" name="gridLayout_7"> </property>
<property name="margin"> <property name="maximumSize">
<number>3</number> <size>
</property> <width>50</width>
<property name="spacing"> <height>600</height>
<number>3</number> </size>
</property> </property>
<item row="0" column="0"> <property name="font">
<layout class="QHBoxLayout" name="horizontalLayout_5"> <font>
<item> <pointsize>8</pointsize>
<widget class="QComboBox" name="CurveType"> </font>
<property name="minimumSize"> </property>
<size> <property name="title">
<width>150</width> <string>Roll</string>
<height>0</height> </property>
</size> <property name="alignment">
</property> <set>Qt::AlignCenter</set>
<property name="font"> </property>
<font> <layout class="QVBoxLayout" name="verticalLayout_10">
<pointsize>10</pointsize> <property name="spacing">
</font> <number>0</number>
</property> </property>
<property name="toolTip"> <property name="margin">
<string>Select aircraft type here</string> <number>3</number>
</property> </property>
<item> <item>
<property name="text"> <layout class="QHBoxLayout" name="horizontalLayout_8">
<string>Linear</string> <item>
</property> <spacer name="horizontalSpacer_11">
</item> <property name="orientation">
<item> <enum>Qt::Horizontal</enum>
<property name="text"> </property>
<string>Flat</string> <property name="sizeHint" stdset="0">
</property> <size>
</item> <width>5</width>
<item> <height>25</height>
<property name="text"> </size>
<string>Step</string> </property>
</property> </spacer>
</item> </item>
<item> <item>
<property name="text"> <widget class="QSlider" name="ccpmRollScale">
<string>Exp</string> <property name="enabled">
</property> <bool>true</bool>
</item> </property>
<item> <property name="sizePolicy">
<property name="text"> <sizepolicy hsizetype="Fixed" vsizetype="Expanding">
<string>Log</string> <horstretch>0</horstretch>
</property> <verstretch>0</verstretch>
</item> </sizepolicy>
<item> </property>
<property name="text"> <property name="minimumSize">
<string>Custom</string> <size>
</property> <width>0</width>
</item> <height>100</height>
</widget> </size>
</item> </property>
<item> <property name="maximum">
<spacer name="horizontalSpacer"> <number>100</number>
<property name="orientation"> </property>
<enum>Qt::Horizontal</enum> <property name="singleStep">
</property> <number>5</number>
<property name="sizeHint" stdset="0"> </property>
<size> <property name="value">
<width>40</width> <number>50</number>
<height>20</height> </property>
</size> <property name="orientation">
</property> <enum>Qt::Vertical</enum>
</spacer> </property>
</item> </widget>
<item> </item>
<widget class="QLabel" name="label_2"> <item>
<property name="sizePolicy"> <spacer name="horizontalSpacer_12">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed"> <property name="orientation">
<horstretch>0</horstretch> <enum>Qt::Horizontal</enum>
<verstretch>0</verstretch> </property>
</sizepolicy> <property name="sizeHint" stdset="0">
</property> <size>
<property name="text"> <width>5</width>
<string>Number of points</string> <height>25</height>
</property> </size>
</widget> </property>
</item> </spacer>
<item> </item>
<widget class="QSpinBox" name="NumCurvePoints"> </layout>
<property name="sizePolicy"> </item>
<sizepolicy hsizetype="Fixed" vsizetype="Fixed"> <item>
<horstretch>0</horstretch> <widget class="QSpinBox" name="ccpmRollScaleBox">
<verstretch>0</verstretch> <property name="maximum">
</sizepolicy> <number>100</number>
</property> </property>
<property name="minimum"> <property name="singleStep">
<number>2</number> <number>5</number>
</property> </property>
<property name="maximum"> <property name="value">
<number>10</number> <number>50</number>
</property> </property>
<property name="value"> </widget>
<number>5</number> </item>
</property> </layout>
</widget> </widget>
</item> </item>
</layout> </layout>
</item> </item>
<item row="1" column="0"> </layout>
<layout class="QGridLayout" name="gridLayout_2"> </widget>
<item row="0" column="0"> <widget class="QWidget" name="SwashPlateLevel">
<widget class="QLabel" name="CurveLabel1"> <attribute name="title">
<property name="text"> <string>Swashplate Levelling</string>
<string>Min</string> </attribute>
</property> <layout class="QGridLayout" name="gridLayout_8">
</widget> <property name="margin">
</item> <number>3</number>
<item row="0" column="1"> </property>
<widget class="QLabel" name="CurveLabel2"> <property name="spacing">
<property name="text"> <number>3</number>
<string>Max</string> </property>
</property> <item row="0" column="0">
</widget> <layout class="QVBoxLayout" name="verticalLayout_8">
</item> <property name="leftMargin">
<item row="0" column="2"> <number>3</number>
<widget class="QLabel" name="CurveLabel3"> </property>
<property name="text"> <item>
<string>Step point</string> <widget class="QGroupBox" name="SwashLvlInstructionsBox">
</property> <property name="sizePolicy">
</widget> <sizepolicy hsizetype="Fixed" vsizetype="Maximum">
</item> <horstretch>0</horstretch>
<item row="1" column="0"> <verstretch>0</verstretch>
<widget class="QDoubleSpinBox" name="CurveValue1"> </sizepolicy>
<property name="decimals"> </property>
<number>1</number> <property name="minimumSize">
</property> <size>
<property name="maximum"> <width>228</width>
<double>10.000000000000000</double> <height>0</height>
</property> </size>
</widget> </property>
</item> <property name="title">
<item row="1" column="1"> <string>Commands</string>
<widget class="QDoubleSpinBox" name="CurveValue2"> </property>
<property name="decimals"> <layout class="QVBoxLayout" name="verticalLayout">
<number>1</number> <property name="margin">
</property> <number>3</number>
<property name="maximum"> </property>
<double>10.000000000000000</double> <item>
</property> <layout class="QHBoxLayout" name="horizontalLayout_9">
<property name="value"> <property name="spacing">
<double>1.000000000000000</double> <number>0</number>
</property> </property>
</widget> <item>
</item> <widget class="QPushButton" name="SwashLvlStartButton">
<item row="1" column="2"> <property name="minimumSize">
<widget class="QDoubleSpinBox" name="CurveValue3"> <size>
<property name="decimals"> <width>85</width>
<number>1</number> <height>0</height>
</property> </size>
<property name="maximum"> </property>
<double>100.000000000000000</double> <property name="maximumSize">
</property> <size>
<property name="value"> <width>85</width>
<double>50.000000000000000</double> <height>16777215</height>
</property> </size>
</widget> </property>
</item> <property name="text">
</layout> <string>Start</string>
</item> </property>
<item row="2" column="0"> </widget>
<layout class="QHBoxLayout" name="horizontalLayout_6"> </item>
<item> <item>
<widget class="QComboBox" name="CurveToGenerate"> <widget class="QPushButton" name="SwashLvlNextButton">
<property name="sizePolicy"> <property name="enabled">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed"> <bool>false</bool>
<horstretch>0</horstretch> </property>
<verstretch>0</verstretch> <property name="minimumSize">
</sizepolicy> <size>
</property> <width>85</width>
<property name="minimumSize"> <height>0</height>
<size> </size>
<width>150</width> </property>
<height>0</height> <property name="maximumSize">
</size> <size>
</property> <width>85</width>
<property name="font"> <height>16777215</height>
<font> </size>
<pointsize>10</pointsize> </property>
</font> <property name="text">
</property> <string>Next</string>
<property name="toolTip"> </property>
<string>Select aircraft type here</string> </widget>
</property> </item>
<item> </layout>
<property name="text"> </item>
<string>Throttle</string> <item>
</property> <widget class="QTextEdit" name="SwashLvlStepInstruction">
</item> <property name="minimumSize">
<item> <size>
<property name="text"> <width>0</width>
<string>Pitch</string> <height>150</height>
</property> </size>
</item> </property>
</widget> <property name="maximumSize">
</item> <size>
<item> <width>220</width>
<widget class="QPushButton" name="ccpmGenerateCurve"> <height>450</height>
<property name="sizePolicy"> </size>
<sizepolicy hsizetype="Preferred" vsizetype="Fixed"> </property>
<horstretch>0</horstretch> <property name="horizontalScrollBarPolicy">
<verstretch>0</verstretch> <enum>Qt::ScrollBarAlwaysOff</enum>
</sizepolicy> </property>
</property> <property name="readOnly">
<property name="minimumSize"> <bool>true</bool>
<size> </property>
<width>150</width> </widget>
<height>0</height> </item>
</size> <item>
</property> <layout class="QGridLayout" name="gridLayout_3">
<property name="toolTip"> <item row="0" column="0">
<string>Generate curves based on settings</string> <widget class="QPushButton" name="SwashLvlCancelButton">
</property> <property name="enabled">
<property name="text"> <bool>false</bool>
<string>&lt;-- Generate Curve</string> </property>
</property> <property name="minimumSize">
</widget> <size>
</item> <width>170</width>
<item> <height>0</height>
<spacer name="horizontalSpacer_6"> </size>
<property name="orientation"> </property>
<enum>Qt::Horizontal</enum> <property name="maximumSize">
</property> <size>
<property name="sizeHint" stdset="0"> <width>170</width>
<size> <height>16777215</height>
<width>40</width> </size>
<height>20</height> </property>
</size> <property name="text">
</property> <string>Cancel</string>
</spacer> </property>
</item> </widget>
</layout> </item>
</item> <item row="1" column="0">
<item row="3" column="0"> <widget class="QPushButton" name="SwashLvlFinishButton">
<layout class="QHBoxLayout" name="horizontalLayout_3"> <property name="enabled">
<property name="spacing"> <bool>false</bool>
<number>3</number> </property>
</property> <property name="minimumSize">
<item> <size>
<widget class="QTableWidget" name="CurveSettings"> <width>170</width>
<property name="sizePolicy"> <height>0</height>
<sizepolicy hsizetype="Maximum" vsizetype="MinimumExpanding"> </size>
<horstretch>0</horstretch> </property>
<verstretch>0</verstretch> <property name="maximumSize">
</sizepolicy> <size>
</property> <width>170</width>
<property name="minimumSize"> <height>16777215</height>
<size> </size>
<width>250</width> </property>
<height>200</height> <property name="text">
</size> <string>Finish</string>
</property> </property>
<property name="maximumSize"> </widget>
<size> </item>
<width>250</width> </layout>
<height>273</height> </item>
</size> </layout>
</property> </widget>
<property name="font"> </item>
<font> <item>
<pointsize>8</pointsize> <widget class="QGroupBox" name="SwashLvlStatusBox">
</font> <property name="sizePolicy">
</property> <sizepolicy hsizetype="Fixed" vsizetype="Maximum">
<property name="verticalScrollBarPolicy"> <horstretch>0</horstretch>
<enum>Qt::ScrollBarAsNeeded</enum> <verstretch>0</verstretch>
</property> </sizepolicy>
<property name="horizontalScrollBarPolicy"> </property>
<enum>Qt::ScrollBarAsNeeded</enum> <property name="minimumSize">
</property> <size>
<property name="autoScroll"> <width>200</width>
<bool>true</bool> <height>0</height>
</property> </size>
<property name="alternatingRowColors"> </property>
<bool>true</bool> <property name="title">
</property> <string>Status</string>
<property name="cornerButtonEnabled"> </property>
<bool>true</bool> <layout class="QGridLayout" name="gridLayout_22">
</property> <property name="horizontalSpacing">
<attribute name="horizontalHeaderCascadingSectionResizes"> <number>3</number>
<bool>true</bool> </property>
</attribute> <property name="verticalSpacing">
<attribute name="horizontalHeaderStretchLastSection"> <number>2</number>
<bool>true</bool> </property>
</attribute> <property name="margin">
<attribute name="verticalHeaderDefaultSectionSize"> <number>3</number>
<number>25</number> </property>
</attribute> <item row="1" column="0">
<attribute name="verticalHeaderMinimumSectionSize"> <widget class="QListWidget" name="SwashLvlStepList">
<number>25</number> <property name="minimumSize">
</attribute> <size>
<row> <width>220</width>
<property name="text"> <height>0</height>
<string>0%</string> </size>
</property> </property>
</row> <property name="maximumSize">
<row> <size>
<property name="text"> <width>190</width>
<string>25%</string> <height>125</height>
</property> </size>
</row> </property>
<row> <property name="editTriggers">
<property name="text"> <set>QAbstractItemView::NoEditTriggers</set>
<string>50%</string> </property>
</property> <property name="alternatingRowColors">
</row> <bool>true</bool>
<row> </property>
<property name="text"> <property name="selectionMode">
<string>75%</string> <enum>QAbstractItemView::NoSelection</enum>
</property> </property>
</row> <property name="selectionBehavior">
<row> <enum>QAbstractItemView::SelectRows</enum>
<property name="text"> </property>
<string>100%</string> <item>
</property> <property name="text">
</row> <string>Neutral</string>
<row> </property>
<property name="text"> <property name="icon">
<string>none</string> <iconset>
</property> <normaloff>:/configgadget/images/none.png</normaloff>
</row> <normalon>:/configgadget/images/ok.png</normalon>:/configgadget/images/none.png</iconset>
<row> </property>
<property name="text"> </item>
<string>none</string> <item>
</property> <property name="text">
</row> <string>Max</string>
<row> </property>
<property name="text"> <property name="icon">
<string>none</string> <iconset>
</property> <normaloff>:/configgadget/images/none.png</normaloff>
</row> <normalon>:/configgadget/images/ok.png</normalon>:/configgadget/images/none.png</iconset>
<row> </property>
<property name="text"> </item>
<string>none</string> <item>
</property> <property name="text">
</row> <string>Min</string>
<row> </property>
<property name="text"> <property name="icon">
<string>none</string> <iconset>
</property> <normaloff>:/configgadget/images/none.png</normaloff>
</row> <normalon>:/configgadget/images/ok.png</normalon>:/configgadget/images/none.png</iconset>
<column> </property>
<property name="text"> <property name="flags">
<string>Throttle Curve</string> <set>ItemIsSelectable|ItemIsEnabled</set>
</property> </property>
<property name="textAlignment"> </item>
<set>AlignHCenter|AlignVCenter|AlignCenter</set> <item>
</property> <property name="text">
</column> <string>Verify</string>
<column> </property>
<property name="text"> <property name="icon">
<string>Blade Pitch Curve</string> <iconset>
</property> <normaloff>:/configgadget/images/none.png</normaloff>
<property name="textAlignment"> <normalon>:/configgadget/images/ok.png</normalon>:/configgadget/images/none.png</iconset>
<set>AlignHCenter|AlignVCenter|AlignCenter</set> </property>
</property> <property name="flags">
</column> <set>ItemIsEnabled</set>
<item row="0" column="0"> </property>
<property name="text"> </item>
<string>0.000</string> </widget>
</property> </item>
<property name="textAlignment"> </layout>
<set>AlignHCenter|AlignVCenter|AlignCenter</set> </widget>
</property> </item>
</item> <item>
<item row="0" column="1"> <spacer name="verticalSpacer_4">
<property name="text"> <property name="orientation">
<string>0.000</string> <enum>Qt::Vertical</enum>
</property> </property>
<property name="textAlignment"> <property name="sizeType">
<set>AlignHCenter|AlignVCenter|AlignCenter</set> <enum>QSizePolicy::MinimumExpanding</enum>
</property> </property>
</item> <property name="sizeHint" stdset="0">
<item row="1" column="0"> <size>
<property name="text"> <width>20</width>
<string>0.250</string> <height>0</height>
</property> </size>
<property name="textAlignment"> </property>
<set>AlignHCenter|AlignVCenter|AlignCenter</set> </spacer>
</property> </item>
</item> </layout>
<item row="1" column="1"> </item>
<property name="text"> <item row="0" column="1">
<string>0.250</string> <widget class="QGroupBox" name="SwashLvlccpmSliderBox">
</property> <property name="enabled">
<property name="textAlignment"> <bool>true</bool>
<set>AlignHCenter|AlignVCenter|AlignCenter</set> </property>
</property> <property name="sizePolicy">
</item> <sizepolicy hsizetype="Fixed" vsizetype="Expanding">
<item row="2" column="0"> <horstretch>0</horstretch>
<property name="text"> <verstretch>0</verstretch>
<string>0.500</string> </sizepolicy>
</property> </property>
<property name="textAlignment"> <property name="minimumSize">
<set>AlignHCenter|AlignVCenter|AlignCenter</set> <size>
</property> <width>50</width>
</item> <height>100</height>
<item row="2" column="1"> </size>
<property name="text"> </property>
<string>0.500</string> <property name="maximumSize">
</property> <size>
<property name="textAlignment"> <width>50</width>
<set>AlignHCenter|AlignVCenter|AlignCenter</set> <height>600</height>
</property> </size>
</item> </property>
<item row="3" column="0"> <property name="font">
<property name="text"> <font>
<string>0.750</string> <pointsize>8</pointsize>
</property> </font>
<property name="textAlignment"> </property>
<set>AlignHCenter|AlignVCenter|AlignCenter</set> <property name="title">
</property> <string>Position</string>
</item> </property>
<item row="3" column="1"> <property name="alignment">
<property name="text"> <set>Qt::AlignCenter</set>
<string>0.750</string> </property>
</property> <layout class="QVBoxLayout" name="verticalLayout_5">
<property name="textAlignment"> <property name="spacing">
<set>AlignHCenter|AlignVCenter|AlignCenter</set> <number>0</number>
</property> </property>
</item> <property name="margin">
<item row="4" column="0"> <number>3</number>
<property name="text"> </property>
<string>1.000</string> <item>
</property> <widget class="QLabel" name="label_17">
<property name="textAlignment"> <property name="enabled">
<set>AlignHCenter|AlignVCenter|AlignCenter</set> <bool>true</bool>
</property> </property>
</item> <property name="font">
<item row="4" column="1"> <font>
<property name="text"> <pointsize>7</pointsize>
<string>1.000</string> </font>
</property> </property>
<property name="textAlignment"> <property name="text">
<set>AlignHCenter|AlignVCenter|AlignCenter</set> <string>Max</string>
</property> </property>
</item> <property name="scaledContents">
<item row="5" column="0"> <bool>true</bool>
<property name="text"> </property>
<string>-</string> <property name="alignment">
</property> <set>Qt::AlignCenter</set>
<property name="textAlignment"> </property>
<set>AlignHCenter|AlignVCenter|AlignCenter</set> </widget>
</property> </item>
</item> <item>
<item row="5" column="1"> <layout class="QHBoxLayout" name="horizontalLayout_4">
<property name="text"> <item>
<string>-</string> <spacer name="horizontalSpacer_7">
</property> <property name="orientation">
<property name="textAlignment"> <enum>Qt::Horizontal</enum>
<set>AlignHCenter|AlignVCenter|AlignCenter</set> </property>
</property> <property name="sizeHint" stdset="0">
</item> <size>
<item row="6" column="0"> <width>5</width>
<property name="text"> <height>25</height>
<string>-</string> </size>
</property> </property>
<property name="textAlignment"> </spacer>
<set>AlignHCenter|AlignVCenter|AlignCenter</set> </item>
</property> <item>
</item> <widget class="QSlider" name="SwashLvlPositionSlider">
<item row="6" column="1"> <property name="enabled">
<property name="text"> <bool>true</bool>
<string>-</string> </property>
</property> <property name="sizePolicy">
<property name="textAlignment"> <sizepolicy hsizetype="Fixed" vsizetype="Expanding">
<set>AlignHCenter|AlignVCenter|AlignCenter</set> <horstretch>0</horstretch>
</property> <verstretch>0</verstretch>
</item> </sizepolicy>
<item row="7" column="0"> </property>
<property name="text"> <property name="minimumSize">
<string>-</string> <size>
</property> <width>0</width>
<property name="textAlignment"> <height>100</height>
<set>AlignHCenter|AlignVCenter|AlignCenter</set> </size>
</property> </property>
</item> <property name="maximum">
<item row="7" column="1"> <number>100</number>
<property name="text"> </property>
<string>-</string> <property name="singleStep">
</property> <number>5</number>
<property name="textAlignment"> </property>
<set>AlignHCenter|AlignVCenter|AlignCenter</set> <property name="value">
</property> <number>50</number>
</item> </property>
<item row="8" column="0"> <property name="orientation">
<property name="text"> <enum>Qt::Vertical</enum>
<string>-</string> </property>
</property> </widget>
<property name="textAlignment"> </item>
<set>AlignHCenter|AlignVCenter|AlignCenter</set> <item>
</property> <spacer name="horizontalSpacer_8">
</item> <property name="orientation">
<item row="8" column="1"> <enum>Qt::Horizontal</enum>
<property name="text"> </property>
<string>-</string> <property name="sizeHint" stdset="0">
</property> <size>
<property name="textAlignment"> <width>5</width>
<set>AlignHCenter|AlignVCenter|AlignCenter</set> <height>25</height>
</property> </size>
</item> </property>
<item row="9" column="0"> </spacer>
<property name="text"> </item>
<string>-</string> </layout>
</property> </item>
<property name="textAlignment"> <item>
<set>AlignHCenter|AlignVCenter|AlignCenter</set> <widget class="QLabel" name="label_18">
</property> <property name="enabled">
</item> <bool>true</bool>
<item row="9" column="1"> </property>
<property name="text"> <property name="font">
<string>-</string> <font>
</property> <pointsize>7</pointsize>
<property name="textAlignment"> </font>
<set>AlignHCenter|AlignVCenter|AlignCenter</set> </property>
</property> <property name="text">
</item> <string>Min</string>
</widget> </property>
</item> <property name="alignment">
<item> <set>Qt::AlignCenter</set>
<widget class="QGroupBox" name="ThrottleCurveBox"> </property>
<property name="sizePolicy"> </widget>
<sizepolicy hsizetype="Preferred" vsizetype="Preferred"> </item>
<horstretch>1</horstretch> <item>
<verstretch>1</verstretch> <widget class="QSpinBox" name="SwashLvlPositionSpinBox">
</sizepolicy> <property name="maximum">
</property> <number>100</number>
<property name="minimumSize"> </property>
<size> <property name="singleStep">
<width>100</width> <number>5</number>
<height>100</height> </property>
</size> <property name="value">
</property> <number>50</number>
<property name="sizeIncrement"> </property>
<size> </widget>
<width>10</width> </item>
<height>10</height> </layout>
</size> </widget>
</property> </item>
<property name="baseSize"> <item row="0" column="2">
<size> <widget class="QGroupBox" name="SwashLvlccpmSwashImageBox">
<width>100</width> <property name="sizePolicy">
<height>100</height> <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
</size> <horstretch>1</horstretch>
</property> <verstretch>1</verstretch>
<property name="layoutDirection"> </sizepolicy>
<enum>Qt::LeftToRight</enum> </property>
</property> <property name="minimumSize">
<property name="title"> <size>
<string>Throttle Curve</string> <width>200</width>
</property> <height>200</height>
<property name="alignment"> </size>
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set> </property>
</property> <property name="maximumSize">
<property name="flat"> <size>
<bool>false</bool> <width>600</width>
</property> <height>600</height>
<layout class="QGridLayout" name="gridLayout"> </size>
<property name="margin"> </property>
<number>0</number> <property name="sizeIncrement">
</property> <size>
<property name="spacing"> <width>10</width>
<number>0</number> <height>10</height>
</property> </size>
<item row="0" column="0"> </property>
<widget class="MixerCurveWidget" name="ThrottleCurve" native="true"> <property name="baseSize">
<property name="sizePolicy"> <size>
<sizepolicy hsizetype="Expanding" vsizetype="Expanding"> <width>200</width>
<horstretch>1</horstretch> <height>200</height>
<verstretch>1</verstretch> </size>
</sizepolicy> </property>
</property> <property name="title">
<property name="minimumSize"> <string>Swashplate Adjustment</string>
<size> </property>
<width>50</width> <property name="alignment">
<height>50</height> <set>Qt::AlignHCenter|Qt::AlignTop</set>
</size> </property>
</property> <property name="flat">
<property name="maximumSize"> <bool>false</bool>
<size> </property>
<width>1000</width> <property name="checkable">
<height>1000</height> <bool>false</bool>
</size> </property>
</property> <layout class="QGridLayout" name="gridLayout_11">
<property name="sizeIncrement"> <property name="horizontalSpacing">
<size> <number>3</number>
<width>10</width> </property>
<height>10</height> <property name="margin">
</size> <number>3</number>
</property> </property>
<property name="baseSize"> <item row="0" column="0">
<size> <widget class="QSplitter" name="splitter_4">
<width>200</width> <property name="orientation">
<height>200</height> <enum>Qt::Vertical</enum>
</size> </property>
</property> <widget class="QGraphicsView" name="SwashLvlSwashplateImage">
</widget> <property name="sizePolicy">
</item> <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
</layout> <horstretch>1</horstretch>
</widget> <verstretch>1</verstretch>
</item> </sizepolicy>
<item> </property>
<widget class="QGroupBox" name="PitchCurveBox"> <property name="minimumSize">
<property name="sizePolicy"> <size>
<sizepolicy hsizetype="Preferred" vsizetype="Preferred"> <width>10</width>
<horstretch>1</horstretch> <height>10</height>
<verstretch>1</verstretch> </size>
</sizepolicy> </property>
</property> <property name="maximumSize">
<property name="minimumSize"> <size>
<size> <width>1000</width>
<width>100</width> <height>1000</height>
<height>100</height> </size>
</size> </property>
</property> <property name="sizeIncrement">
<property name="sizeIncrement"> <size>
<size> <width>10</width>
<width>10</width> <height>10</height>
<height>10</height> </size>
</size> </property>
</property> <property name="baseSize">
<property name="baseSize"> <size>
<size> <width>200</width>
<width>100</width> <height>200</height>
<height>100</height> </size>
</size> </property>
</property> <property name="frameShape">
<property name="title"> <enum>QFrame::Box</enum>
<string>Pitch Curve</string> </property>
</property> <property name="frameShadow">
<layout class="QGridLayout" name="gridLayout_5"> <enum>QFrame::Plain</enum>
<property name="margin"> </property>
<number>0</number> <property name="lineWidth">
</property> <number>1</number>
<property name="spacing"> </property>
<number>0</number> <property name="midLineWidth">
</property> <number>0</number>
<item row="0" column="0"> </property>
<widget class="MixerCurveWidget" name="PitchCurve" native="true"> <property name="verticalScrollBarPolicy">
<property name="sizePolicy"> <enum>Qt::ScrollBarAlwaysOff</enum>
<sizepolicy hsizetype="Fixed" vsizetype="Expanding"> </property>
<horstretch>1</horstretch> <property name="horizontalScrollBarPolicy">
<verstretch>1</verstretch> <enum>Qt::ScrollBarAlwaysOff</enum>
</sizepolicy> </property>
</property> <property name="backgroundBrush">
<property name="minimumSize"> <brush brushstyle="DiagCrossPattern">
<size> <color alpha="25">
<width>50</width> <red>126</red>
<height>50</height> <green>176</green>
</size> <blue>220</blue>
</property> </color>
<property name="maximumSize"> </brush>
<size> </property>
<width>1000</width> <property name="foregroundBrush">
<height>1000</height> <brush brushstyle="NoBrush">
</size> <color alpha="255">
</property> <red>0</red>
<property name="sizeIncrement"> <green>0</green>
<size> <blue>0</blue>
<width>10</width> </color>
<height>10</height> </brush>
</size> </property>
</property> <property name="sceneRect">
<property name="baseSize"> <rectf>
<size> <x>0.000000000000000</x>
<width>200</width> <y>0.000000000000000</y>
<height>200</height> <width>400.000000000000000</width>
</size> <height>400.000000000000000</height>
</property> </rectf>
</widget> </property>
</item> <property name="alignment">
</layout> <set>Qt::AlignCenter</set>
</widget> </property>
</item> <property name="resizeAnchor">
</layout> <enum>QGraphicsView::AnchorViewCenter</enum>
</item> </property>
<item row="4" column="0"> </widget>
<spacer name="verticalSpacer_2"> </widget>
<property name="orientation"> </item>
<enum>Qt::Vertical</enum> </layout>
</property> </widget>
<property name="sizeType"> </item>
<enum>QSizePolicy::Preferred</enum> </layout>
</property> </widget>
<property name="sizeHint" stdset="0"> <widget class="QWidget" name="CurveTab">
<size> <attribute name="title">
<width>20</width> <string>Curve settings</string>
<height>0</height> </attribute>
</size> <layout class="QGridLayout" name="gridLayout_7">
</property> <property name="margin">
</spacer> <number>3</number>
</item> </property>
</layout> <property name="spacing">
</widget> <number>3</number>
<widget class="QWidget" name="AdvancedTab"> </property>
<attribute name="title"> <item row="0" column="0">
<string>Advanced settings</string> <layout class="QHBoxLayout" name="horizontalLayout_5">
</attribute> <item>
<layout class="QGridLayout" name="gridLayout_4"> <widget class="QComboBox" name="CurveType">
<property name="margin"> <property name="minimumSize">
<number>3</number> <size>
</property> <width>150</width>
<property name="spacing"> <height>0</height>
<number>3</number> </size>
</property> </property>
<item row="0" column="0"> <property name="font">
<widget class="QTableWidget" name="ccpmAdvancedSettingsTable"> <font>
<property name="sizePolicy"> <pointsize>10</pointsize>
<sizepolicy hsizetype="Preferred" vsizetype="MinimumExpanding"> </font>
<horstretch>0</horstretch> </property>
<verstretch>0</verstretch> <property name="toolTip">
</sizepolicy> <string>Select aircraft type here</string>
</property> </property>
<property name="minimumSize"> <item>
<size> <property name="text">
<width>0</width> <string>Linear</string>
<height>200</height> </property>
</size> </item>
</property> <item>
<property name="maximumSize"> <property name="text">
<size> <string>Flat</string>
<width>1000</width> </property>
<height>300</height> </item>
</size> <item>
</property> <property name="text">
<property name="verticalScrollBarPolicy"> <string>Step</string>
<enum>Qt::ScrollBarAlwaysOff</enum> </property>
</property> </item>
<property name="horizontalScrollBarPolicy"> <item>
<enum>Qt::ScrollBarAlwaysOff</enum> <property name="text">
</property> <string>Exp</string>
<property name="autoScroll"> </property>
<bool>true</bool> </item>
</property> <item>
<property name="alternatingRowColors"> <property name="text">
<bool>true</bool> <string>Log</string>
</property> </property>
<property name="selectionMode"> </item>
<enum>QAbstractItemView::NoSelection</enum> <item>
</property> <property name="text">
<property name="wordWrap"> <string>Custom</string>
<bool>false</bool> </property>
</property> </item>
<property name="cornerButtonEnabled"> </widget>
<bool>true</bool> </item>
</property> <item>
<attribute name="horizontalHeaderDefaultSectionSize"> <spacer name="horizontalSpacer">
<number>75</number> <property name="orientation">
</attribute> <enum>Qt::Horizontal</enum>
<attribute name="horizontalHeaderMinimumSectionSize"> </property>
<number>20</number> <property name="sizeHint" stdset="0">
</attribute> <size>
<row> <width>40</width>
<property name="text"> <height>20</height>
<string>Engine</string> </size>
</property> </property>
</row> </spacer>
<row> </item>
<property name="text"> <item>
<string>Tail Rotor</string> <widget class="QLabel" name="label_2">
</property> <property name="sizePolicy">
</row> <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<row> <horstretch>0</horstretch>
<property name="text"> <verstretch>0</verstretch>
<string>Servo W</string> </sizepolicy>
</property> </property>
</row> <property name="text">
<row> <string>Number of points</string>
<property name="text"> </property>
<string>Servo X</string> </widget>
</property> </item>
</row> <item>
<row> <widget class="QSpinBox" name="NumCurvePoints">
<property name="text"> <property name="sizePolicy">
<string>Servo Y</string> <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
</property> <horstretch>0</horstretch>
</row> <verstretch>0</verstretch>
<row> </sizepolicy>
<property name="text"> </property>
<string>Servo Z</string> <property name="minimum">
</property> <number>2</number>
</row> </property>
<column> <property name="maximum">
<property name="text"> <number>10</number>
<string>Channel</string> </property>
</property> <property name="value">
</column> <number>5</number>
<column> </property>
<property name="text"> </widget>
<string>Curve 1</string> </item>
</property> </layout>
</column> </item>
<column> <item row="1" column="0">
<property name="text"> <layout class="QGridLayout" name="gridLayout_2">
<string>Curve 2</string> <item row="0" column="0">
</property> <widget class="QLabel" name="CurveLabel1">
</column> <property name="text">
<column> <string>Min</string>
<property name="text"> </property>
<string>Roll</string> </widget>
</property> </item>
</column> <item row="0" column="1">
<column> <widget class="QLabel" name="CurveLabel2">
<property name="text"> <property name="text">
<string>Pitch</string> <string>Max</string>
</property> </property>
</column> </widget>
<column> </item>
<property name="text"> <item row="0" column="2">
<string>Yaw</string> <widget class="QLabel" name="CurveLabel3">
</property> <property name="text">
</column> <string>Step point</string>
<item row="0" column="0"> </property>
<property name="text"> </widget>
<string>-</string> </item>
</property> <item row="1" column="0">
<property name="textAlignment"> <widget class="QDoubleSpinBox" name="CurveValue1">
<set>AlignHCenter|AlignVCenter|AlignCenter</set> <property name="decimals">
</property> <number>1</number>
</item> </property>
<item row="0" column="1"> <property name="maximum">
<property name="text"> <double>10.000000000000000</double>
<string>-</string> </property>
</property> </widget>
<property name="textAlignment"> </item>
<set>AlignHCenter|AlignVCenter|AlignCenter</set> <item row="1" column="1">
</property> <widget class="QDoubleSpinBox" name="CurveValue2">
</item> <property name="decimals">
<item row="0" column="2"> <number>1</number>
<property name="text"> </property>
<string>-</string> <property name="maximum">
</property> <double>10.000000000000000</double>
<property name="textAlignment"> </property>
<set>AlignHCenter|AlignVCenter|AlignCenter</set> <property name="value">
</property> <double>1.000000000000000</double>
</item> </property>
<item row="0" column="3"> </widget>
<property name="text"> </item>
<string>-</string> <item row="1" column="2">
</property> <widget class="QDoubleSpinBox" name="CurveValue3">
<property name="textAlignment"> <property name="decimals">
<set>AlignHCenter|AlignVCenter|AlignCenter</set> <number>1</number>
</property> </property>
</item> <property name="maximum">
<item row="0" column="4"> <double>100.000000000000000</double>
<property name="text"> </property>
<string>-</string> <property name="value">
</property> <double>50.000000000000000</double>
<property name="textAlignment"> </property>
<set>AlignHCenter|AlignVCenter|AlignCenter</set> </widget>
</property> </item>
</item> </layout>
<item row="0" column="5"> </item>
<property name="text"> <item row="2" column="0">
<string>-</string> <layout class="QHBoxLayout" name="horizontalLayout_6">
</property> <item>
<property name="textAlignment"> <widget class="QComboBox" name="CurveToGenerate">
<set>AlignHCenter|AlignVCenter|AlignCenter</set> <property name="sizePolicy">
</property> <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
</item> <horstretch>0</horstretch>
<item row="1" column="0"> <verstretch>0</verstretch>
<property name="text"> </sizepolicy>
<string>-</string> </property>
</property> <property name="minimumSize">
<property name="textAlignment"> <size>
<set>AlignHCenter|AlignVCenter|AlignCenter</set> <width>150</width>
</property> <height>0</height>
</item> </size>
<item row="1" column="1"> </property>
<property name="text"> <property name="font">
<string>-</string> <font>
</property> <pointsize>10</pointsize>
<property name="textAlignment"> </font>
<set>AlignHCenter|AlignVCenter|AlignCenter</set> </property>
</property> <property name="toolTip">
</item> <string>Select aircraft type here</string>
<item row="1" column="2"> </property>
<property name="text"> <item>
<string>-</string> <property name="text">
</property> <string>Throttle</string>
<property name="textAlignment"> </property>
<set>AlignHCenter|AlignVCenter|AlignCenter</set> </item>
</property> <item>
</item> <property name="text">
<item row="1" column="3"> <string>Pitch</string>
<property name="text"> </property>
<string>-</string> </item>
</property> </widget>
<property name="textAlignment"> </item>
<set>AlignHCenter|AlignVCenter|AlignCenter</set> <item>
</property> <widget class="QPushButton" name="ccpmGenerateCurve">
</item> <property name="sizePolicy">
<item row="1" column="4"> <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<property name="text"> <horstretch>0</horstretch>
<string>-</string> <verstretch>0</verstretch>
</property> </sizepolicy>
<property name="textAlignment"> </property>
<set>AlignHCenter|AlignVCenter|AlignCenter</set> <property name="minimumSize">
</property> <size>
</item> <width>150</width>
<item row="1" column="5"> <height>0</height>
<property name="text"> </size>
<string>-</string> </property>
</property> <property name="toolTip">
<property name="textAlignment"> <string>Generate curves based on settings</string>
<set>AlignHCenter|AlignVCenter|AlignCenter</set> </property>
</property> <property name="text">
</item> <string>&lt;-- Generate Curve</string>
<item row="2" column="0"> </property>
<property name="text"> </widget>
<string>-</string> </item>
</property> <item>
<property name="textAlignment"> <spacer name="horizontalSpacer_6">
<set>AlignHCenter|AlignVCenter|AlignCenter</set> <property name="orientation">
</property> <enum>Qt::Horizontal</enum>
</item> </property>
<item row="2" column="1"> <property name="sizeHint" stdset="0">
<property name="text"> <size>
<string>-</string> <width>40</width>
</property> <height>20</height>
<property name="textAlignment"> </size>
<set>AlignHCenter|AlignVCenter|AlignCenter</set> </property>
</property> </spacer>
</item> </item>
<item row="2" column="2"> </layout>
<property name="text"> </item>
<string>-</string> <item row="3" column="0">
</property> <layout class="QHBoxLayout" name="horizontalLayout_3">
<property name="textAlignment"> <property name="spacing">
<set>AlignHCenter|AlignVCenter|AlignCenter</set> <number>3</number>
</property> </property>
</item> <item>
<item row="2" column="3"> <widget class="QTableWidget" name="CurveSettings">
<property name="text"> <property name="sizePolicy">
<string>-</string> <sizepolicy hsizetype="Maximum" vsizetype="MinimumExpanding">
</property> <horstretch>0</horstretch>
<property name="textAlignment"> <verstretch>0</verstretch>
<set>AlignHCenter|AlignVCenter|AlignCenter</set> </sizepolicy>
</property> </property>
</item> <property name="minimumSize">
<item row="2" column="4"> <size>
<property name="text"> <width>250</width>
<string>-</string> <height>200</height>
</property> </size>
<property name="textAlignment"> </property>
<set>AlignHCenter|AlignVCenter|AlignCenter</set> <property name="maximumSize">
</property> <size>
</item> <width>250</width>
<item row="2" column="5"> <height>273</height>
<property name="text"> </size>
<string>-</string> </property>
</property> <property name="font">
<property name="textAlignment"> <font>
<set>AlignHCenter|AlignVCenter|AlignCenter</set> <pointsize>8</pointsize>
</property> </font>
</item> </property>
<item row="3" column="0"> <property name="verticalScrollBarPolicy">
<property name="text"> <enum>Qt::ScrollBarAsNeeded</enum>
<string>-</string> </property>
</property> <property name="horizontalScrollBarPolicy">
<property name="textAlignment"> <enum>Qt::ScrollBarAsNeeded</enum>
<set>AlignHCenter|AlignVCenter|AlignCenter</set> </property>
</property> <property name="autoScroll">
</item> <bool>true</bool>
<item row="3" column="1"> </property>
<property name="text"> <property name="alternatingRowColors">
<string>-</string> <bool>true</bool>
</property> </property>
<property name="textAlignment"> <property name="cornerButtonEnabled">
<set>AlignHCenter|AlignVCenter|AlignCenter</set> <bool>true</bool>
</property> </property>
</item> <attribute name="horizontalHeaderCascadingSectionResizes">
<item row="3" column="2"> <bool>true</bool>
<property name="text"> </attribute>
<string>-</string> <attribute name="horizontalHeaderStretchLastSection">
</property> <bool>true</bool>
<property name="textAlignment"> </attribute>
<set>AlignHCenter|AlignVCenter|AlignCenter</set> <attribute name="verticalHeaderDefaultSectionSize">
</property> <number>25</number>
</item> </attribute>
<item row="3" column="3"> <attribute name="verticalHeaderMinimumSectionSize">
<property name="text"> <number>25</number>
<string>-</string> </attribute>
</property> <row>
<property name="textAlignment"> <property name="text">
<set>AlignHCenter|AlignVCenter|AlignCenter</set> <string>0%</string>
</property> </property>
</item> </row>
<item row="3" column="4"> <row>
<property name="text"> <property name="text">
<string>-</string> <string>25%</string>
</property> </property>
<property name="textAlignment"> </row>
<set>AlignHCenter|AlignVCenter|AlignCenter</set> <row>
</property> <property name="text">
</item> <string>50%</string>
<item row="3" column="5"> </property>
<property name="text"> </row>
<string>-</string> <row>
</property> <property name="text">
<property name="textAlignment"> <string>75%</string>
<set>AlignHCenter|AlignVCenter|AlignCenter</set> </property>
</property> </row>
</item> <row>
<item row="4" column="0"> <property name="text">
<property name="text"> <string>100%</string>
<string>-</string> </property>
</property> </row>
<property name="textAlignment"> <row>
<set>AlignHCenter|AlignVCenter|AlignCenter</set> <property name="text">
</property> <string>none</string>
</item> </property>
<item row="4" column="1"> </row>
<property name="text"> <row>
<string>-</string> <property name="text">
</property> <string>none</string>
<property name="textAlignment"> </property>
<set>AlignHCenter|AlignVCenter|AlignCenter</set> </row>
</property> <row>
</item> <property name="text">
<item row="4" column="2"> <string>none</string>
<property name="text"> </property>
<string>-</string> </row>
</property> <row>
<property name="textAlignment"> <property name="text">
<set>AlignHCenter|AlignVCenter|AlignCenter</set> <string>none</string>
</property> </property>
</item> </row>
<item row="4" column="3"> <row>
<property name="text"> <property name="text">
<string>-</string> <string>none</string>
</property> </property>
<property name="textAlignment"> </row>
<set>AlignHCenter|AlignVCenter|AlignCenter</set> <column>
</property> <property name="text">
</item> <string>Throttle Curve</string>
<item row="4" column="4"> </property>
<property name="text"> <property name="textAlignment">
<string>-</string> <set>AlignHCenter|AlignVCenter|AlignCenter</set>
</property> </property>
<property name="textAlignment"> </column>
<set>AlignHCenter|AlignVCenter|AlignCenter</set> <column>
</property> <property name="text">
</item> <string>Blade Pitch Curve</string>
<item row="4" column="5"> </property>
<property name="text"> <property name="textAlignment">
<string>-</string> <set>AlignHCenter|AlignVCenter|AlignCenter</set>
</property> </property>
<property name="textAlignment"> </column>
<set>AlignHCenter|AlignVCenter|AlignCenter</set> <item row="0" column="0">
</property> <property name="text">
</item> <string>0.000</string>
<item row="5" column="0"> </property>
<property name="text"> <property name="textAlignment">
<string>-</string> <set>AlignHCenter|AlignVCenter|AlignCenter</set>
</property> </property>
<property name="textAlignment"> </item>
<set>AlignHCenter|AlignVCenter|AlignCenter</set> <item row="0" column="1">
</property> <property name="text">
</item> <string>0.000</string>
<item row="5" column="1"> </property>
<property name="text"> <property name="textAlignment">
<string>-</string> <set>AlignHCenter|AlignVCenter|AlignCenter</set>
</property> </property>
<property name="textAlignment"> </item>
<set>AlignHCenter|AlignVCenter|AlignCenter</set> <item row="1" column="0">
</property> <property name="text">
</item> <string>0.250</string>
<item row="5" column="2"> </property>
<property name="text"> <property name="textAlignment">
<string>-</string> <set>AlignHCenter|AlignVCenter|AlignCenter</set>
</property> </property>
<property name="textAlignment"> </item>
<set>AlignHCenter|AlignVCenter|AlignCenter</set> <item row="1" column="1">
</property> <property name="text">
</item> <string>0.250</string>
<item row="5" column="3"> </property>
<property name="text"> <property name="textAlignment">
<string>-</string> <set>AlignHCenter|AlignVCenter|AlignCenter</set>
</property> </property>
<property name="textAlignment"> </item>
<set>AlignHCenter|AlignVCenter|AlignCenter</set> <item row="2" column="0">
</property> <property name="text">
</item> <string>0.500</string>
<item row="5" column="4"> </property>
<property name="text"> <property name="textAlignment">
<string>-</string> <set>AlignHCenter|AlignVCenter|AlignCenter</set>
</property> </property>
<property name="textAlignment"> </item>
<set>AlignHCenter|AlignVCenter|AlignCenter</set> <item row="2" column="1">
</property> <property name="text">
</item> <string>0.500</string>
<item row="5" column="5"> </property>
<property name="text"> <property name="textAlignment">
<string>-</string> <set>AlignHCenter|AlignVCenter|AlignCenter</set>
</property> </property>
<property name="textAlignment"> </item>
<set>AlignHCenter|AlignVCenter|AlignCenter</set> <item row="3" column="0">
</property> <property name="text">
</item> <string>0.750</string>
</widget> </property>
</item> <property name="textAlignment">
<item row="1" column="0"> <set>AlignHCenter|AlignVCenter|AlignCenter</set>
<spacer name="verticalSpacer"> </property>
<property name="orientation"> </item>
<enum>Qt::Vertical</enum> <item row="3" column="1">
</property> <property name="text">
<property name="sizeType"> <string>0.750</string>
<enum>QSizePolicy::MinimumExpanding</enum> </property>
</property> <property name="textAlignment">
<property name="sizeHint" stdset="0"> <set>AlignHCenter|AlignVCenter|AlignCenter</set>
<size> </property>
<width>20</width> </item>
<height>40</height> <item row="4" column="0">
</size> <property name="text">
</property> <string>1.000</string>
</spacer> </property>
</item> <property name="textAlignment">
</layout> <set>AlignHCenter|AlignVCenter|AlignCenter</set>
</widget> </property>
</widget> </item>
</item> <item row="4" column="1">
</layout> <property name="text">
</item> <string>1.000</string>
</layout> </property>
</widget> <property name="textAlignment">
<customwidgets> <set>AlignHCenter|AlignVCenter|AlignCenter</set>
<customwidget> </property>
<class>MixerCurveWidget</class> </item>
<extends>QWidget</extends> <item row="5" column="0">
<header>mixercurvewidget.h</header> <property name="text">
<container>1</container> <string>-</string>
</customwidget> </property>
</customwidgets> <property name="textAlignment">
<tabstops> <set>AlignHCenter|AlignVCenter|AlignCenter</set>
<tabstop>ccpmType</tabstop> </property>
<tabstop>TabObject</tabstop> </item>
<tabstop>ccpmEngineChannel</tabstop> <item row="5" column="1">
<tabstop>ccpmTailChannel</tabstop> <property name="text">
<tabstop>ccpmServoWChannel</tabstop> <string>-</string>
<tabstop>ccpmServoXChannel</tabstop> </property>
<tabstop>ccpmServoYChannel</tabstop> <property name="textAlignment">
<tabstop>ccpmServoZChannel</tabstop> <set>AlignHCenter|AlignVCenter|AlignCenter</set>
<tabstop>ccpmSingleServo</tabstop> </property>
<tabstop>ccpmAngleW</tabstop> </item>
<tabstop>ccpmAngleX</tabstop> <item row="6" column="0">
<tabstop>ccpmAngleY</tabstop> <property name="text">
<tabstop>ccpmAngleZ</tabstop> <string>-</string>
<tabstop>ccpmCorrectionAngle</tabstop> </property>
<tabstop>ccpmRevoSlider</tabstop> <property name="textAlignment">
<tabstop>ccpmREVOspinBox</tabstop> <set>AlignHCenter|AlignVCenter|AlignCenter</set>
<tabstop>ccpmCollectiveSlider</tabstop> </property>
<tabstop>ccpmCollectivespinBox</tabstop> </item>
<tabstop>SwashplateImage</tabstop> <item row="6" column="1">
<tabstop>SwashLvlStartButton</tabstop> <property name="text">
<tabstop>SwashLvlNextButton</tabstop> <string>-</string>
<tabstop>SwashLvlStepInstruction</tabstop> </property>
<tabstop>SwashLvlCancelButton</tabstop> <property name="textAlignment">
<tabstop>SwashLvlFinishButton</tabstop> <set>AlignHCenter|AlignVCenter|AlignCenter</set>
<tabstop>SwashLvlStepList</tabstop> </property>
<tabstop>SwashLvlPositionSlider</tabstop> </item>
<tabstop>SwashLvlPositionSpinBox</tabstop> <item row="7" column="0">
<tabstop>SwashLvlSwashplateImage</tabstop> <property name="text">
<tabstop>CurveType</tabstop> <string>-</string>
<tabstop>NumCurvePoints</tabstop> </property>
<tabstop>CurveValue1</tabstop> <property name="textAlignment">
<tabstop>CurveValue2</tabstop> <set>AlignHCenter|AlignVCenter|AlignCenter</set>
<tabstop>CurveValue3</tabstop> </property>
<tabstop>CurveToGenerate</tabstop> </item>
<tabstop>ccpmGenerateCurve</tabstop> <item row="7" column="1">
<tabstop>CurveSettings</tabstop> <property name="text">
<tabstop>ccpmAdvancedSettingsTable</tabstop> <string>-</string>
</tabstops> </property>
<resources/> <property name="textAlignment">
<connections> <set>AlignHCenter|AlignVCenter|AlignCenter</set>
<connection> </property>
<sender>ccpmCollectiveSlider</sender> </item>
<signal>sliderMoved(int)</signal> <item row="8" column="0">
<receiver>ccpmCollectivespinBox</receiver> <property name="text">
<slot>setValue(int)</slot> <string>-</string>
<hints> </property>
<hint type="sourcelabel"> <property name="textAlignment">
<x>283</x> <set>AlignHCenter|AlignVCenter|AlignCenter</set>
<y>400</y> </property>
</hint> </item>
<hint type="destinationlabel"> <item row="8" column="1">
<x>294</x> <property name="text">
<y>550</y> <string>-</string>
</hint> </property>
</hints> <property name="textAlignment">
</connection> <set>AlignHCenter|AlignVCenter|AlignCenter</set>
<connection> </property>
<sender>ccpmCollectivespinBox</sender> </item>
<signal>valueChanged(int)</signal> <item row="9" column="0">
<receiver>ccpmCollectiveSlider</receiver> <property name="text">
<slot>setValue(int)</slot> <string>-</string>
<hints> </property>
<hint type="sourcelabel"> <property name="textAlignment">
<x>294</x> <set>AlignHCenter|AlignVCenter|AlignCenter</set>
<y>550</y> </property>
</hint> </item>
<hint type="destinationlabel"> <item row="9" column="1">
<x>283</x> <property name="text">
<y>482</y> <string>-</string>
</hint> </property>
</hints> <property name="textAlignment">
</connection> <set>AlignHCenter|AlignVCenter|AlignCenter</set>
<connection> </property>
<sender>ccpmREVOspinBox</sender> </item>
<signal>valueChanged(int)</signal> </widget>
<receiver>ccpmRevoSlider</receiver> </item>
<slot>setValue(int)</slot> <item>
<hints> <widget class="QGroupBox" name="ThrottleCurveBox">
<hint type="sourcelabel"> <property name="sizePolicy">
<x>241</x> <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<y>550</y> <horstretch>1</horstretch>
</hint> <verstretch>1</verstretch>
<hint type="destinationlabel"> </sizepolicy>
<x>230</x> </property>
<y>484</y> <property name="minimumSize">
</hint> <size>
</hints> <width>100</width>
</connection> <height>100</height>
<connection> </size>
<sender>ccpmRevoSlider</sender> </property>
<signal>sliderMoved(int)</signal> <property name="sizeIncrement">
<receiver>ccpmREVOspinBox</receiver> <size>
<slot>setValue(int)</slot> <width>10</width>
<hints> <height>10</height>
<hint type="sourcelabel"> </size>
<x>230</x> </property>
<y>313</y> <property name="baseSize">
</hint> <size>
<hint type="destinationlabel"> <width>100</width>
<x>241</x> <height>100</height>
<y>550</y> </size>
</hint> </property>
</hints> <property name="layoutDirection">
</connection> <enum>Qt::LeftToRight</enum>
<connection> </property>
<sender>SwashLvlPositionSlider</sender> <property name="title">
<signal>sliderMoved(int)</signal> <string>Throttle Curve</string>
<receiver>SwashLvlPositionSpinBox</receiver> </property>
<slot>setValue(int)</slot> <property name="alignment">
<hints> <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
<hint type="sourcelabel"> </property>
<x>276</x> <property name="flat">
<y>486</y> <bool>false</bool>
</hint> </property>
<hint type="destinationlabel"> <layout class="QGridLayout" name="gridLayout">
<x>270</x> <property name="margin">
<y>537</y> <number>0</number>
</hint> </property>
</hints> <property name="spacing">
</connection> <number>0</number>
<connection> </property>
<sender>SwashLvlPositionSpinBox</sender> <item row="0" column="0">
<signal>valueChanged(int)</signal> <widget class="MixerCurveWidget" name="ThrottleCurve" native="true">
<receiver>SwashLvlPositionSlider</receiver> <property name="sizePolicy">
<slot>setValue(int)</slot> <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<hints> <horstretch>1</horstretch>
<hint type="sourcelabel"> <verstretch>1</verstretch>
<x>257</x> </sizepolicy>
<y>535</y> </property>
</hint> <property name="minimumSize">
<hint type="destinationlabel"> <size>
<x>277</x> <width>50</width>
<y>401</y> <height>50</height>
</hint> </size>
</hints> </property>
</connection> <property name="maximumSize">
</connections> <size>
</ui> <width>1000</width>
<height>1000</height>
</size>
</property>
<property name="sizeIncrement">
<size>
<width>10</width>
<height>10</height>
</size>
</property>
<property name="baseSize">
<size>
<width>200</width>
<height>200</height>
</size>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="PitchCurveBox">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>1</horstretch>
<verstretch>1</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>100</width>
<height>100</height>
</size>
</property>
<property name="sizeIncrement">
<size>
<width>10</width>
<height>10</height>
</size>
</property>
<property name="baseSize">
<size>
<width>100</width>
<height>100</height>
</size>
</property>
<property name="title">
<string>Pitch Curve</string>
</property>
<layout class="QGridLayout" name="gridLayout_5">
<property name="margin">
<number>0</number>
</property>
<property name="spacing">
<number>0</number>
</property>
<item row="0" column="0">
<widget class="MixerCurveWidget" name="PitchCurve" native="true">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Expanding">
<horstretch>1</horstretch>
<verstretch>1</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>50</width>
<height>50</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>1000</width>
<height>1000</height>
</size>
</property>
<property name="sizeIncrement">
<size>
<width>10</width>
<height>10</height>
</size>
</property>
<property name="baseSize">
<size>
<width>200</width>
<height>200</height>
</size>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</item>
<item row="4" column="0">
<spacer name="verticalSpacer_2">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Preferred</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>0</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
<widget class="QWidget" name="AdvancedTab">
<attribute name="title">
<string>Advanced settings</string>
</attribute>
<layout class="QGridLayout" name="gridLayout_4">
<property name="margin">
<number>3</number>
</property>
<property name="spacing">
<number>3</number>
</property>
<item row="0" column="0">
<widget class="QTableWidget" name="ccpmAdvancedSettingsTable">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="MinimumExpanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>0</width>
<height>200</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>1000</width>
<height>300</height>
</size>
</property>
<property name="verticalScrollBarPolicy">
<enum>Qt::ScrollBarAlwaysOff</enum>
</property>
<property name="horizontalScrollBarPolicy">
<enum>Qt::ScrollBarAlwaysOff</enum>
</property>
<property name="autoScroll">
<bool>true</bool>
</property>
<property name="alternatingRowColors">
<bool>true</bool>
</property>
<property name="selectionMode">
<enum>QAbstractItemView::NoSelection</enum>
</property>
<property name="wordWrap">
<bool>false</bool>
</property>
<property name="cornerButtonEnabled">
<bool>true</bool>
</property>
<attribute name="horizontalHeaderDefaultSectionSize">
<number>75</number>
</attribute>
<attribute name="horizontalHeaderMinimumSectionSize">
<number>20</number>
</attribute>
<row>
<property name="text">
<string>Engine</string>
</property>
</row>
<row>
<property name="text">
<string>Tail Rotor</string>
</property>
</row>
<row>
<property name="text">
<string>Servo W</string>
</property>
</row>
<row>
<property name="text">
<string>Servo X</string>
</property>
</row>
<row>
<property name="text">
<string>Servo Y</string>
</property>
</row>
<row>
<property name="text">
<string>Servo Z</string>
</property>
</row>
<column>
<property name="text">
<string>Channel</string>
</property>
</column>
<column>
<property name="text">
<string>Curve 1</string>
</property>
</column>
<column>
<property name="text">
<string>Curve 2</string>
</property>
</column>
<column>
<property name="text">
<string>Roll</string>
</property>
</column>
<column>
<property name="text">
<string>Pitch</string>
</property>
</column>
<column>
<property name="text">
<string>Yaw</string>
</property>
</column>
<item row="0" column="0">
<property name="text">
<string>-</string>
</property>
<property name="textAlignment">
<set>AlignHCenter|AlignVCenter|AlignCenter</set>
</property>
</item>
<item row="0" column="1">
<property name="text">
<string>-</string>
</property>
<property name="textAlignment">
<set>AlignHCenter|AlignVCenter|AlignCenter</set>
</property>
</item>
<item row="0" column="2">
<property name="text">
<string>-</string>
</property>
<property name="textAlignment">
<set>AlignHCenter|AlignVCenter|AlignCenter</set>
</property>
</item>
<item row="0" column="3">
<property name="text">
<string>-</string>
</property>
<property name="textAlignment">
<set>AlignHCenter|AlignVCenter|AlignCenter</set>
</property>
</item>
<item row="0" column="4">
<property name="text">
<string>-</string>
</property>
<property name="textAlignment">
<set>AlignHCenter|AlignVCenter|AlignCenter</set>
</property>
</item>
<item row="0" column="5">
<property name="text">
<string>-</string>
</property>
<property name="textAlignment">
<set>AlignHCenter|AlignVCenter|AlignCenter</set>
</property>
</item>
<item row="1" column="0">
<property name="text">
<string>-</string>
</property>
<property name="textAlignment">
<set>AlignHCenter|AlignVCenter|AlignCenter</set>
</property>
</item>
<item row="1" column="1">
<property name="text">
<string>-</string>
</property>
<property name="textAlignment">
<set>AlignHCenter|AlignVCenter|AlignCenter</set>
</property>
</item>
<item row="1" column="2">
<property name="text">
<string>-</string>
</property>
<property name="textAlignment">
<set>AlignHCenter|AlignVCenter|AlignCenter</set>
</property>
</item>
<item row="1" column="3">
<property name="text">
<string>-</string>
</property>
<property name="textAlignment">
<set>AlignHCenter|AlignVCenter|AlignCenter</set>
</property>
</item>
<item row="1" column="4">
<property name="text">
<string>-</string>
</property>
<property name="textAlignment">
<set>AlignHCenter|AlignVCenter|AlignCenter</set>
</property>
</item>
<item row="1" column="5">
<property name="text">
<string>-</string>
</property>
<property name="textAlignment">
<set>AlignHCenter|AlignVCenter|AlignCenter</set>
</property>
</item>
<item row="2" column="0">
<property name="text">
<string>-</string>
</property>
<property name="textAlignment">
<set>AlignHCenter|AlignVCenter|AlignCenter</set>
</property>
</item>
<item row="2" column="1">
<property name="text">
<string>-</string>
</property>
<property name="textAlignment">
<set>AlignHCenter|AlignVCenter|AlignCenter</set>
</property>
</item>
<item row="2" column="2">
<property name="text">
<string>-</string>
</property>
<property name="textAlignment">
<set>AlignHCenter|AlignVCenter|AlignCenter</set>
</property>
</item>
<item row="2" column="3">
<property name="text">
<string>-</string>
</property>
<property name="textAlignment">
<set>AlignHCenter|AlignVCenter|AlignCenter</set>
</property>
</item>
<item row="2" column="4">
<property name="text">
<string>-</string>
</property>
<property name="textAlignment">
<set>AlignHCenter|AlignVCenter|AlignCenter</set>
</property>
</item>
<item row="2" column="5">
<property name="text">
<string>-</string>
</property>
<property name="textAlignment">
<set>AlignHCenter|AlignVCenter|AlignCenter</set>
</property>
</item>
<item row="3" column="0">
<property name="text">
<string>-</string>
</property>
<property name="textAlignment">
<set>AlignHCenter|AlignVCenter|AlignCenter</set>
</property>
</item>
<item row="3" column="1">
<property name="text">
<string>-</string>
</property>
<property name="textAlignment">
<set>AlignHCenter|AlignVCenter|AlignCenter</set>
</property>
</item>
<item row="3" column="2">
<property name="text">
<string>-</string>
</property>
<property name="textAlignment">
<set>AlignHCenter|AlignVCenter|AlignCenter</set>
</property>
</item>
<item row="3" column="3">
<property name="text">
<string>-</string>
</property>
<property name="textAlignment">
<set>AlignHCenter|AlignVCenter|AlignCenter</set>
</property>
</item>
<item row="3" column="4">
<property name="text">
<string>-</string>
</property>
<property name="textAlignment">
<set>AlignHCenter|AlignVCenter|AlignCenter</set>
</property>
</item>
<item row="3" column="5">
<property name="text">
<string>-</string>
</property>
<property name="textAlignment">
<set>AlignHCenter|AlignVCenter|AlignCenter</set>
</property>
</item>
<item row="4" column="0">
<property name="text">
<string>-</string>
</property>
<property name="textAlignment">
<set>AlignHCenter|AlignVCenter|AlignCenter</set>
</property>
</item>
<item row="4" column="1">
<property name="text">
<string>-</string>
</property>
<property name="textAlignment">
<set>AlignHCenter|AlignVCenter|AlignCenter</set>
</property>
</item>
<item row="4" column="2">
<property name="text">
<string>-</string>
</property>
<property name="textAlignment">
<set>AlignHCenter|AlignVCenter|AlignCenter</set>
</property>
</item>
<item row="4" column="3">
<property name="text">
<string>-</string>
</property>
<property name="textAlignment">
<set>AlignHCenter|AlignVCenter|AlignCenter</set>
</property>
</item>
<item row="4" column="4">
<property name="text">
<string>-</string>
</property>
<property name="textAlignment">
<set>AlignHCenter|AlignVCenter|AlignCenter</set>
</property>
</item>
<item row="4" column="5">
<property name="text">
<string>-</string>
</property>
<property name="textAlignment">
<set>AlignHCenter|AlignVCenter|AlignCenter</set>
</property>
</item>
<item row="5" column="0">
<property name="text">
<string>-</string>
</property>
<property name="textAlignment">
<set>AlignHCenter|AlignVCenter|AlignCenter</set>
</property>
</item>
<item row="5" column="1">
<property name="text">
<string>-</string>
</property>
<property name="textAlignment">
<set>AlignHCenter|AlignVCenter|AlignCenter</set>
</property>
</item>
<item row="5" column="2">
<property name="text">
<string>-</string>
</property>
<property name="textAlignment">
<set>AlignHCenter|AlignVCenter|AlignCenter</set>
</property>
</item>
<item row="5" column="3">
<property name="text">
<string>-</string>
</property>
<property name="textAlignment">
<set>AlignHCenter|AlignVCenter|AlignCenter</set>
</property>
</item>
<item row="5" column="4">
<property name="text">
<string>-</string>
</property>
<property name="textAlignment">
<set>AlignHCenter|AlignVCenter|AlignCenter</set>
</property>
</item>
<item row="5" column="5">
<property name="text">
<string>-</string>
</property>
<property name="textAlignment">
<set>AlignHCenter|AlignVCenter|AlignCenter</set>
</property>
</item>
</widget>
</item>
<item row="1" column="0">
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::MinimumExpanding</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>MixerCurveWidget</class>
<extends>QWidget</extends>
<header>mixercurvewidget.h</header>
<container>1</container>
</customwidget>
</customwidgets>
<tabstops>
<tabstop>ccpmType</tabstop>
<tabstop>TabObject</tabstop>
<tabstop>ccpmEngineChannel</tabstop>
<tabstop>ccpmTailChannel</tabstop>
<tabstop>ccpmServoWChannel</tabstop>
<tabstop>ccpmServoXChannel</tabstop>
<tabstop>ccpmServoYChannel</tabstop>
<tabstop>ccpmServoZChannel</tabstop>
<tabstop>ccpmSingleServo</tabstop>
<tabstop>ccpmAngleW</tabstop>
<tabstop>ccpmAngleX</tabstop>
<tabstop>ccpmAngleY</tabstop>
<tabstop>ccpmAngleZ</tabstop>
<tabstop>ccpmCorrectionAngle</tabstop>
<tabstop>ccpmRevoSlider</tabstop>
<tabstop>ccpmREVOspinBox</tabstop>
<tabstop>ccpmCollectiveSlider</tabstop>
<tabstop>ccpmCollectivespinBox</tabstop>
<tabstop>SwashplateImage</tabstop>
<tabstop>SwashLvlStartButton</tabstop>
<tabstop>SwashLvlNextButton</tabstop>
<tabstop>SwashLvlStepInstruction</tabstop>
<tabstop>SwashLvlCancelButton</tabstop>
<tabstop>SwashLvlFinishButton</tabstop>
<tabstop>SwashLvlStepList</tabstop>
<tabstop>SwashLvlPositionSlider</tabstop>
<tabstop>SwashLvlPositionSpinBox</tabstop>
<tabstop>SwashLvlSwashplateImage</tabstop>
<tabstop>CurveType</tabstop>
<tabstop>NumCurvePoints</tabstop>
<tabstop>CurveValue1</tabstop>
<tabstop>CurveValue2</tabstop>
<tabstop>CurveValue3</tabstop>
<tabstop>CurveToGenerate</tabstop>
<tabstop>ccpmGenerateCurve</tabstop>
<tabstop>CurveSettings</tabstop>
<tabstop>ccpmAdvancedSettingsTable</tabstop>
</tabstops>
<resources/>
<connections>
<connection>
<sender>ccpmCollectiveSlider</sender>
<signal>sliderMoved(int)</signal>
<receiver>ccpmCollectivespinBox</receiver>
<slot>setValue(int)</slot>
<hints>
<hint type="sourcelabel">
<x>261</x>
<y>496</y>
</hint>
<hint type="destinationlabel">
<x>269</x>
<y>546</y>
</hint>
</hints>
</connection>
<connection>
<sender>ccpmCollectivespinBox</sender>
<signal>valueChanged(int)</signal>
<receiver>ccpmCollectiveSlider</receiver>
<slot>setValue(int)</slot>
<hints>
<hint type="sourcelabel">
<x>269</x>
<y>546</y>
</hint>
<hint type="destinationlabel">
<x>261</x>
<y>511</y>
</hint>
</hints>
</connection>
<connection>
<sender>ccpmREVOspinBox</sender>
<signal>valueChanged(int)</signal>
<receiver>ccpmRevoSlider</receiver>
<slot>setValue(int)</slot>
<hints>
<hint type="sourcelabel">
<x>216</x>
<y>546</y>
</hint>
<hint type="destinationlabel">
<x>208</x>
<y>511</y>
</hint>
</hints>
</connection>
<connection>
<sender>ccpmRevoSlider</sender>
<signal>sliderMoved(int)</signal>
<receiver>ccpmREVOspinBox</receiver>
<slot>setValue(int)</slot>
<hints>
<hint type="sourcelabel">
<x>208</x>
<y>412</y>
</hint>
<hint type="destinationlabel">
<x>216</x>
<y>546</y>
</hint>
</hints>
</connection>
<connection>
<sender>SwashLvlPositionSlider</sender>
<signal>sliderMoved(int)</signal>
<receiver>SwashLvlPositionSpinBox</receiver>
<slot>setValue(int)</slot>
<hints>
<hint type="sourcelabel">
<x>276</x>
<y>486</y>
</hint>
<hint type="destinationlabel">
<x>270</x>
<y>537</y>
</hint>
</hints>
</connection>
<connection>
<sender>SwashLvlPositionSpinBox</sender>
<signal>valueChanged(int)</signal>
<receiver>SwashLvlPositionSlider</receiver>
<slot>setValue(int)</slot>
<hints>
<hint type="sourcelabel">
<x>301</x>
<y>546</y>
</hint>
<hint type="destinationlabel">
<x>277</x>
<y>401</y>
</hint>
</hints>
</connection>
<connection>
<sender>ccpmCollectiveScaleBox</sender>
<signal>valueChanged(int)</signal>
<receiver>ccpmCollectiveScale</receiver>
<slot>setValue(int)</slot>
<hints>
<hint type="sourcelabel">
<x>296</x>
<y>534</y>
</hint>
<hint type="destinationlabel">
<x>306</x>
<y>480</y>
</hint>
</hints>
</connection>
<connection>
<sender>ccpmCollectiveScale</sender>
<signal>sliderMoved(int)</signal>
<receiver>ccpmCollectiveScaleBox</receiver>
<slot>setValue(int)</slot>
<hints>
<hint type="sourcelabel">
<x>308</x>
<y>328</y>
</hint>
<hint type="destinationlabel">
<x>292</x>
<y>534</y>
</hint>
</hints>
</connection>
<connection>
<sender>ccpmCyclicScale</sender>
<signal>sliderMoved(int)</signal>
<receiver>ccpmCyclicScaleBox</receiver>
<slot>setValue(int)</slot>
<hints>
<hint type="sourcelabel">
<x>358</x>
<y>306</y>
</hint>
<hint type="destinationlabel">
<x>355</x>
<y>538</y>
</hint>
</hints>
</connection>
<connection>
<sender>ccpmCyclicScaleBox</sender>
<signal>valueChanged(int)</signal>
<receiver>ccpmCyclicScale</receiver>
<slot>setValue(int)</slot>
<hints>
<hint type="sourcelabel">
<x>341</x>
<y>538</y>
</hint>
<hint type="destinationlabel">
<x>351</x>
<y>376</y>
</hint>
</hints>
</connection>
<connection>
<sender>ccpmPitchScale</sender>
<signal>sliderMoved(int)</signal>
<receiver>ccpmPitchScaleBox</receiver>
<slot>setValue(int)</slot>
<hints>
<hint type="sourcelabel">
<x>417</x>
<y>306</y>
</hint>
<hint type="destinationlabel">
<x>406</x>
<y>531</y>
</hint>
</hints>
</connection>
<connection>
<sender>ccpmPitchScaleBox</sender>
<signal>valueChanged(int)</signal>
<receiver>ccpmPitchScale</receiver>
<slot>setValue(int)</slot>
<hints>
<hint type="sourcelabel">
<x>394</x>
<y>531</y>
</hint>
<hint type="destinationlabel">
<x>408</x>
<y>302</y>
</hint>
</hints>
</connection>
<connection>
<sender>ccpmRollScaleBox</sender>
<signal>valueChanged(int)</signal>
<receiver>ccpmRollScale</receiver>
<slot>setValue(int)</slot>
<hints>
<hint type="sourcelabel">
<x>455</x>
<y>529</y>
</hint>
<hint type="destinationlabel">
<x>458</x>
<y>466</y>
</hint>
</hints>
</connection>
<connection>
<sender>ccpmRollScale</sender>
<signal>sliderMoved(int)</signal>
<receiver>ccpmRollScaleBox</receiver>
<slot>setValue(int)</slot>
<hints>
<hint type="sourcelabel">
<x>461</x>
<y>388</y>
</hint>
<hint type="destinationlabel">
<x>474</x>
<y>533</y>
</hint>
</hints>
</connection>
</connections>
</ui>

View File

@ -374,7 +374,7 @@ void ConfigAirframeWidget::resetFwMixer()
{ {
UAVDataObject* obj = dynamic_cast<UAVDataObject*>(getObjectManager()->getObject(QString("MixerSettings"))); UAVDataObject* obj = dynamic_cast<UAVDataObject*>(getObjectManager()->getObject(QString("MixerSettings")));
UAVObjectField* field = obj->getField(QString("ThrottleCurve1")); UAVObjectField* field = obj->getField(QString("ThrottleCurve1"));
resetMixer(m_aircraft->fixedWingThrottle, field->getNumElements()); resetMixer(m_aircraft->fixedWingThrottle, field->getNumElements(),1);
} }
/** /**
@ -384,7 +384,7 @@ void ConfigAirframeWidget::resetMrMixer()
{ {
UAVDataObject* obj = dynamic_cast<UAVDataObject*>(getObjectManager()->getObject(QString("MixerSettings"))); UAVDataObject* obj = dynamic_cast<UAVDataObject*>(getObjectManager()->getObject(QString("MixerSettings")));
UAVObjectField* field = obj->getField(QString("ThrottleCurve1")); UAVObjectField* field = obj->getField(QString("ThrottleCurve1"));
resetMixer(m_aircraft->multiThrottleCurve, field->getNumElements()); resetMixer(m_aircraft->multiThrottleCurve, field->getNumElements(),0.9);
} }
/** /**
@ -394,7 +394,7 @@ void ConfigAirframeWidget::resetCt1Mixer()
{ {
UAVDataObject* obj = dynamic_cast<UAVDataObject*>(getObjectManager()->getObject(QString("MixerSettings"))); UAVDataObject* obj = dynamic_cast<UAVDataObject*>(getObjectManager()->getObject(QString("MixerSettings")));
UAVObjectField* field = obj->getField(QString("ThrottleCurve1")); UAVObjectField* field = obj->getField(QString("ThrottleCurve1"));
resetMixer(m_aircraft->customThrottle1Curve, field->getNumElements()); resetMixer(m_aircraft->customThrottle1Curve, field->getNumElements(),1);
} }
/** /**
@ -404,21 +404,17 @@ void ConfigAirframeWidget::resetCt2Mixer()
{ {
UAVDataObject* obj = dynamic_cast<UAVDataObject*>(getObjectManager()->getObject(QString("MixerSettings"))); UAVDataObject* obj = dynamic_cast<UAVDataObject*>(getObjectManager()->getObject(QString("MixerSettings")));
UAVObjectField* field = obj->getField(QString("ThrottleCurve2")); UAVObjectField* field = obj->getField(QString("ThrottleCurve2"));
resetMixer(m_aircraft->customThrottle2Curve, field->getNumElements()); resetMixer(m_aircraft->customThrottle2Curve, field->getNumElements(),1);
} }
/** /**
Resets a mixer curve Resets a mixer curve
*/ */
void ConfigAirframeWidget::resetMixer(MixerCurveWidget *mixer, int numElements) void ConfigAirframeWidget::resetMixer(MixerCurveWidget *mixer, int numElements, double maxvalue)
{ {
QList<double> curveValues;
for (double i=0; i<numElements; i++) {
curveValues.append(i/(numElements-1));
}
// Setup all Throttle1 curves for all types of airframes // Setup all Throttle1 curves for all types of airframes
mixer->initCurve(curveValues); mixer->initLinearCurve((quint32)numElements,maxvalue);
} }
/** /**
@ -484,18 +480,29 @@ void ConfigAirframeWidget::refreshValues()
// If the 1st element of the curve is <= -10, then the curve // If the 1st element of the curve is <= -10, then the curve
// is a straight line (that's how the mixer works on the mainboard): // is a straight line (that's how the mixer works on the mainboard):
if (field->getValue(0).toInt() <= -10) { if (field->getValue(0).toInt() <= -10) {
for (double i=0; i<field->getNumElements(); i++) { m_aircraft->multiThrottleCurve->initLinearCurve(field->getNumElements(),(double)1);
curveValues.append(i/(field->getNumElements()-1)); m_aircraft->fixedWingThrottle->initLinearCurve(field->getNumElements(),(double)1);
} }
} else { else {
double temp=0;
double value;
for (unsigned int i=0; i < field->getNumElements(); i++) { for (unsigned int i=0; i < field->getNumElements(); i++) {
curveValues.append(field->getValue(i).toDouble()); value=field->getValue(i).toDouble();
temp+=value;
curveValues.append(value);
}
if(temp==0)
{
m_aircraft->multiThrottleCurve->initLinearCurve(field->getNumElements(),0.9);;
m_aircraft->fixedWingThrottle->initLinearCurve(field->getNumElements(),(double)1);
}
else
{
m_aircraft->multiThrottleCurve->initCurve(curveValues);
m_aircraft->fixedWingThrottle->initCurve(curveValues);
} }
} }
// Setup all Throttle1 curves for all types of airframes // Setup all Throttle1 curves for all types of airframes
m_aircraft->fixedWingThrottle->initCurve(curveValues);
m_aircraft->multiThrottleCurve->initCurve(curveValues);
// Load the Settings for fixed wing frames: // Load the Settings for fixed wing frames:
if (frameType.startsWith("FixedWing")) { if (frameType.startsWith("FixedWing")) {
// Then retrieve how channels are setup // Then retrieve how channels are setup
@ -1754,31 +1761,32 @@ void ConfigAirframeWidget::updateCustomAirframeUI()
// If the 1st element of the curve is <= -10, then the curve // If the 1st element of the curve is <= -10, then the curve
// is a straight line (that's how the mixer works on the mainboard): // is a straight line (that's how the mixer works on the mainboard):
if (field->getValue(0).toInt() <= -10) { if (field->getValue(0).toInt() <= -10) {
for (double i=0; i<field->getNumElements(); i++) { m_aircraft->customThrottle1Curve->initLinearCurve(field->getNumElements(),(double)1);
curveValues.append(i/(field->getNumElements()-1));
}
} else { } else {
double temp=0;
double value;
for (unsigned int i=0; i < field->getNumElements(); i++) { for (unsigned int i=0; i < field->getNumElements(); i++) {
curveValues.append(field->getValue(i).toDouble()); value=field->getValue(i).toDouble();
temp+=value;
curveValues.append(value);
} }
if(temp==0)
m_aircraft->customThrottle1Curve->initLinearCurve(field->getNumElements(),(double)1);
else
m_aircraft->customThrottle1Curve->initCurve(curveValues);
} }
m_aircraft->customThrottle1Curve->initCurve(curveValues);
field = obj->getField(QString("ThrottleCurve2")); field = obj->getField(QString("ThrottleCurve2"));
curveValues.clear();; curveValues.clear();;
// If the 1st element of the curve is <= -10, then the curve // If the 1st element of the curve is <= -10, then the curve
// is a straight line (that's how the mixer works on the mainboard): // is a straight line (that's how the mixer works on the mainboard):
if (field->getValue(0).toInt() <= -10) { if (field->getValue(0).toInt() <= -10) {
for (double i=0; i<field->getNumElements(); i++) { m_aircraft->customThrottle2Curve->initLinearCurve(field->getNumElements(),(double)1);
curveValues.append(i/(field->getNumElements()-1));
}
} else { } else {
for (unsigned int i=0; i < field->getNumElements(); i++) { for (unsigned int i=0; i < field->getNumElements(); i++) {
curveValues.append(field->getValue(i).toDouble()); curveValues.append(field->getValue(i).toDouble());
} }
m_aircraft->customThrottle2Curve->initCurve(curveValues);
} }
m_aircraft->customThrottle2Curve->initCurve(curveValues);
// Retrieve Feed Forward: // Retrieve Feed Forward:
field = obj->getField(QString("FeedForward")); field = obj->getField(QString("FeedForward"));
m_aircraft->customFFSlider->setValue(field->getDouble()*100); m_aircraft->customFFSlider->setValue(field->getDouble()*100);

View File

@ -61,7 +61,7 @@ private:
virtual void enableControls(bool enable); virtual void enableControls(bool enable);
void resetField(UAVObjectField * field); void resetField(UAVObjectField * field);
void resetMixer (MixerCurveWidget *mixer, int numElements); void resetMixer (MixerCurveWidget *mixer, int numElements, double maxvalue);
void resetActuators(); void resetActuators();
//void setMixerChannel(int channelNumber, bool channelIsMotor, QList<double> vector); //void setMixerChannel(int channelNumber, bool channelIsMotor, QList<double> vector);
void setupQuadMotor(int channel, double roll, double pitch, double yaw); void setupQuadMotor(int channel, double roll, double pitch, double yaw);

View File

@ -25,6 +25,7 @@
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/ */
#include "configccpmwidget.h" #include "configccpmwidget.h"
#include "mixersettings.h"
#include <QDebug> #include <QDebug>
#include <QStringList> #include <QStringList>
@ -32,6 +33,7 @@
#include <QtGui/QTextEdit> #include <QtGui/QTextEdit>
#include <QtGui/QVBoxLayout> #include <QtGui/QVBoxLayout>
#include <QtGui/QPushButton> #include <QtGui/QPushButton>
#include <QBrush>
#include <math.h> #include <math.h>
#include <QMessageBox> #include <QMessageBox>
@ -41,11 +43,14 @@
ConfigccpmWidget::ConfigccpmWidget(QWidget *parent) : ConfigTaskWidget(parent) ConfigccpmWidget::ConfigccpmWidget(QWidget *parent) : ConfigTaskWidget(parent)
{ {
int i; int i;
m_ccpm = new Ui_ccpmWidget(); m_ccpm = new Ui_ccpmWidget();
m_ccpm->setupUi(this); m_ccpm->setupUi(this);
SwashLvlConfigurationInProgress=0; SwashLvlConfigurationInProgress=0;
SwashLvlState=0; SwashLvlState=0;
SwashLvlServoInterlock=0; SwashLvlServoInterlock=0;
updatingFromHardware=FALSE;
updatingToHardware=FALSE;
// Now connect the widget to the ManualControlCommand / Channel UAVObject // Now connect the widget to the ManualControlCommand / Channel UAVObject
//ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance(); //ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance();
@ -55,12 +60,12 @@ ConfigccpmWidget::ConfigccpmWidget(QWidget *parent) : ConfigTaskWidget(parent)
m_ccpm->SwashplateImage->setScene(new QGraphicsScene(this)); m_ccpm->SwashplateImage->setScene(new QGraphicsScene(this));
m_ccpm->SwashLvlSwashplateImage->setScene(m_ccpm->SwashplateImage->scene()); m_ccpm->SwashLvlSwashplateImage->setScene(m_ccpm->SwashplateImage->scene());
m_ccpm->SwashLvlSwashplateImage->setSceneRect(-50,-30,500,500); m_ccpm->SwashLvlSwashplateImage->setSceneRect(-50,-50,500,500);
m_ccpm->SwashLvlSwashplateImage->scale(.85,.85); //m_ccpm->SwashLvlSwashplateImage->scale(.85,.85);
//m_ccpm->SwashplateImage->setSceneRect(SwashplateImg->boundingRect()); //m_ccpm->SwashplateImage->setSceneRect(SwashplateImg->boundingRect());
m_ccpm->SwashplateImage->setSceneRect(-50,-30,500,500); m_ccpm->SwashplateImage->setSceneRect(-50,-30,500,500);
m_ccpm->SwashplateImage->scale(.85,.85); //m_ccpm->SwashplateImage->scale(.85,.85);
@ -72,9 +77,10 @@ ConfigccpmWidget::ConfigccpmWidget(QWidget *parent) : ConfigTaskWidget(parent)
SwashplateImg->setSharedRenderer(renderer); SwashplateImg->setSharedRenderer(renderer);
SwashplateImg->setElementId("Swashplate"); SwashplateImg->setElementId("Swashplate");
SwashplateImg->setObjectName("Swashplate"); SwashplateImg->setObjectName("Swashplate");
//SwashplateImg->setScale(0.75);
m_ccpm->SwashplateImage->scene()->addItem(SwashplateImg); m_ccpm->SwashplateImage->scene()->addItem(SwashplateImg);
QFont serifFont("Times", 16, QFont::Bold); QFont serifFont("Times", 24, QFont::Bold);
QPen pen; // creates a default pen QPen pen; // creates a default pen
pen.setStyle(Qt::DotLine); pen.setStyle(Qt::DotLine);
@ -83,6 +89,19 @@ ConfigccpmWidget::ConfigccpmWidget(QWidget *parent) : ConfigTaskWidget(parent)
pen.setCapStyle(Qt::RoundCap); pen.setCapStyle(Qt::RoundCap);
pen.setJoinStyle(Qt::RoundJoin); pen.setJoinStyle(Qt::RoundJoin);
QBrush brush(Qt::darkBlue);
QPen pen2; // creates a default pen
//pen2.setStyle(Qt::DotLine);
pen2.setWidth(1);
pen2.setBrush(Qt::blue);
//pen2.setCapStyle(Qt::RoundCap);
//pen2.setJoinStyle(Qt::RoundJoin);
//brush.setStyle(Qt::RadialGradientPattern);
QList<QString> ServoNames; QList<QString> ServoNames;
ServoNames << "ServoW" << "ServoX" << "ServoY" << "ServoZ" ; ServoNames << "ServoW" << "ServoX" << "ServoY" << "ServoZ" ;
@ -96,10 +115,16 @@ ConfigccpmWidget::ConfigccpmWidget(QWidget *parent) : ConfigTaskWidget(parent)
m_ccpm->SwashplateImage->scene()->addItem(Servos[i]); m_ccpm->SwashplateImage->scene()->addItem(Servos[i]);
ServosText[i] = new QGraphicsTextItem(); ServosText[i] = new QGraphicsTextItem();
ServosText[i]->setDefaultTextColor(Qt::red); ServosText[i]->setDefaultTextColor(Qt::yellow);
ServosText[i]->setPlainText(QString("-")); ServosText[i]->setPlainText(QString("-"));
ServosText[i]->setFont(serifFont); ServosText[i]->setFont(serifFont);
ServosTextCircles[i] = new QGraphicsEllipseItem(1,1,30,30);
ServosTextCircles[i]->setBrush(brush);
ServosTextCircles[i]->setPen(pen2);
m_ccpm->SwashplateImage->scene()->addItem(ServosTextCircles[i]);
m_ccpm->SwashplateImage->scene()->addItem(ServosText[i]); m_ccpm->SwashplateImage->scene()->addItem(ServosText[i]);
SwashLvlSpinBoxes[i] = new QSpinBox(m_ccpm->SwashLvlSwashplateImage); // use QGraphicsView SwashLvlSpinBoxes[i] = new QSpinBox(m_ccpm->SwashLvlSwashplateImage); // use QGraphicsView
@ -172,7 +197,10 @@ ConfigccpmWidget::ConfigccpmWidget(QWidget *parent) : ConfigTaskWidget(parent)
QStringList channels; QStringList channels;
channels << "Channel1" << "Channel2" << channels << "Channel1" << "Channel2" <<
"Channel3" << "Channel4" << "Channel5" << "Channel6" << "Channel7" << "Channel8" << "None" ; "Channel3" << "Channel4" << "Channel5" << "Channel6" << "Channel7" << "Channel8" ;
m_ccpm->ccpmCollectiveChannel->addItems(channels);
m_ccpm->ccpmCollectiveChannel->setCurrentIndex(8);
channels << "None" ;
m_ccpm->ccpmEngineChannel->addItems(channels); m_ccpm->ccpmEngineChannel->addItems(channels);
m_ccpm->ccpmEngineChannel->setCurrentIndex(8); m_ccpm->ccpmEngineChannel->setCurrentIndex(8);
m_ccpm->ccpmTailChannel->addItems(channels); m_ccpm->ccpmTailChannel->addItems(channels);
@ -187,7 +215,7 @@ ConfigccpmWidget::ConfigccpmWidget(QWidget *parent) : ConfigTaskWidget(parent)
m_ccpm->ccpmServoZChannel->setCurrentIndex(8); m_ccpm->ccpmServoZChannel->setCurrentIndex(8);
QStringList Types; QStringList Types;
Types << "CCPM 2 Servo 90º" << "CCPM 3 Servo 120º" << "CCPM 3 Servo 140º" << "FP 2 Servo 90º" << "Custom - User Angles" << "Custom - Advanced Settings" ; Types << "CCPM 2 Servo 90º" << "CCPM 3 Servo 90º" << "CCPM 4 Servo 90º" << "CCPM 3 Servo 120º" << "CCPM 3 Servo 140º" << "FP 2 Servo 90º" << "Custom - User Angles" << "Custom - Advanced Settings" ;
m_ccpm->ccpmType->addItems(Types); m_ccpm->ccpmType->addItems(Types);
m_ccpm->ccpmType->setCurrentIndex(m_ccpm->ccpmType->count() - 1); m_ccpm->ccpmType->setCurrentIndex(m_ccpm->ccpmType->count() - 1);
requestccpmUpdate(); requestccpmUpdate();
@ -196,6 +224,8 @@ ConfigccpmWidget::ConfigccpmWidget(QWidget *parent) : ConfigTaskWidget(parent)
//disable changing number of points in curves until UAVObjects have more than 5 //disable changing number of points in curves until UAVObjects have more than 5
m_ccpm->NumCurvePoints->setEnabled(0); m_ccpm->NumCurvePoints->setEnabled(0);
UpdateType(); UpdateType();
@ -237,7 +267,13 @@ ConfigccpmWidget::ConfigccpmWidget(QWidget *parent) : ConfigTaskWidget(parent)
connect(m_ccpm->SwashLvlCancelButton, SIGNAL(clicked()), this, SLOT(SwashLvlCancelButtonPressed())); connect(m_ccpm->SwashLvlCancelButton, SIGNAL(clicked()), this, SLOT(SwashLvlCancelButtonPressed()));
connect(m_ccpm->SwashLvlFinishButton, SIGNAL(clicked()), this, SLOT(SwashLvlFinishButtonPressed())); connect(m_ccpm->SwashLvlFinishButton, SIGNAL(clicked()), this, SLOT(SwashLvlFinishButtonPressed()));
connect(m_ccpm->ccpmCollectivePassthrough, SIGNAL(clicked()), this, SLOT(SetUIComponentVisibilities()));
connect(m_ccpm->ccpmLinkCyclic, SIGNAL(clicked()), this, SLOT(SetUIComponentVisibilities()));
connect(m_ccpm->ccpmLinkRoll, SIGNAL(clicked()), this, SLOT(SetUIComponentVisibilities()));
ccpmSwashplateRedraw();
// connect(parent, SIGNAL(autopilotConnected()),this, SLOT(requestccpmUpdate())); // connect(parent, SIGNAL(autopilotConnected()),this, SLOT(requestccpmUpdate()));
} }
@ -249,11 +285,13 @@ ConfigccpmWidget::~ConfigccpmWidget()
void ConfigccpmWidget::UpdateType() void ConfigccpmWidget::UpdateType()
{ {
int TypeInt,SingleServoIndex; int TypeInt,SingleServoIndex,NumServosDefined;
QString TypeText; QString TypeText;
double AdjustmentAngle=0; double AdjustmentAngle=0;
UpdatCCPMOptionsFromUI();
SetUIComponentVisibilities();
TypeInt = m_ccpm->ccpmType->count() - m_ccpm->ccpmType->currentIndex()-1; TypeInt = m_ccpm->ccpmType->count() - m_ccpm->ccpmType->currentIndex()-1;
TypeText = m_ccpm->ccpmType->currentText(); TypeText = m_ccpm->ccpmType->currentText();
SingleServoIndex = m_ccpm->ccpmSingleServo->currentIndex(); SingleServoIndex = m_ccpm->ccpmSingleServo->currentIndex();
@ -266,7 +304,7 @@ void ConfigccpmWidget::UpdateType()
m_ccpm->ccpmAngleX->setEnabled(TypeInt==1); m_ccpm->ccpmAngleX->setEnabled(TypeInt==1);
m_ccpm->ccpmAngleY->setEnabled(TypeInt==1); m_ccpm->ccpmAngleY->setEnabled(TypeInt==1);
m_ccpm->ccpmAngleZ->setEnabled(TypeInt==1); m_ccpm->ccpmAngleZ->setEnabled(TypeInt==1);
m_ccpm->ccpmCorrectionAngle->setEnabled(TypeInt==1); m_ccpm->ccpmCorrectionAngle->setEnabled(TypeInt!=0);
m_ccpm->ccpmServoWChannel->setEnabled(TypeInt>0); m_ccpm->ccpmServoWChannel->setEnabled(TypeInt>0);
m_ccpm->ccpmServoXChannel->setEnabled(TypeInt>0); m_ccpm->ccpmServoXChannel->setEnabled(TypeInt>0);
@ -289,6 +327,7 @@ void ConfigccpmWidget::UpdateType()
//m_ccpm->customThrottleCurve2Value->setVisible(1); //m_ccpm->customThrottleCurve2Value->setVisible(1);
//m_ccpm->label_41->setVisible(1); //m_ccpm->label_41->setVisible(1);
NumServosDefined=4;
//set values for pre defined heli types //set values for pre defined heli types
if (TypeText.compare(QString("CCPM 2 Servo 90º"), Qt::CaseInsensitive)==0) if (TypeText.compare(QString("CCPM 2 Servo 90º"), Qt::CaseInsensitive)==0)
{ {
@ -302,8 +341,34 @@ void ConfigccpmWidget::UpdateType()
m_ccpm->ccpmServoZChannel->setCurrentIndex(8); m_ccpm->ccpmServoZChannel->setCurrentIndex(8);
m_ccpm->ccpmServoYChannel->setEnabled(0); m_ccpm->ccpmServoYChannel->setEnabled(0);
m_ccpm->ccpmServoZChannel->setEnabled(0); m_ccpm->ccpmServoZChannel->setEnabled(0);
m_ccpm->ccpmCorrectionAngle->setValue(0); //m_ccpm->ccpmCorrectionAngle->setValue(0);
NumServosDefined=2;
}
if (TypeText.compare(QString("CCPM 3 Servo 90º"), Qt::CaseInsensitive)==0)
{
m_ccpm->ccpmAngleW->setValue(AdjustmentAngle + 0);
m_ccpm->ccpmAngleX->setValue(fmod(AdjustmentAngle + 90,360));
m_ccpm->ccpmAngleY->setValue(fmod(AdjustmentAngle + 180,360));
m_ccpm->ccpmAngleZ->setValue(0);
m_ccpm->ccpmAngleZ->setEnabled(0);
m_ccpm->ccpmServoZChannel->setCurrentIndex(8);
m_ccpm->ccpmServoZChannel->setEnabled(0);
//m_ccpm->ccpmCorrectionAngle->setValue(0);
NumServosDefined=3;
}
if (TypeText.compare(QString("CCPM 4 Servo 90º"), Qt::CaseInsensitive)==0)
{
m_ccpm->ccpmAngleW->setValue(AdjustmentAngle + 0);
m_ccpm->ccpmAngleX->setValue(fmod(AdjustmentAngle + 90,360));
m_ccpm->ccpmAngleY->setValue(fmod(AdjustmentAngle + 180,360));
m_ccpm->ccpmAngleZ->setValue(fmod(AdjustmentAngle + 270,360));
//m_ccpm->ccpmCorrectionAngle->setValue(0);
m_ccpm->ccpmSingleServo->setEnabled(0);
m_ccpm->ccpmSingleServo->setCurrentIndex(0);
NumServosDefined=4;
} }
if (TypeText.compare(QString("CCPM 3 Servo 120º"), Qt::CaseInsensitive)==0) if (TypeText.compare(QString("CCPM 3 Servo 120º"), Qt::CaseInsensitive)==0)
{ {
@ -314,8 +379,9 @@ void ConfigccpmWidget::UpdateType()
m_ccpm->ccpmAngleZ->setEnabled(0); m_ccpm->ccpmAngleZ->setEnabled(0);
m_ccpm->ccpmServoZChannel->setCurrentIndex(8); m_ccpm->ccpmServoZChannel->setCurrentIndex(8);
m_ccpm->ccpmServoZChannel->setEnabled(0); m_ccpm->ccpmServoZChannel->setEnabled(0);
m_ccpm->ccpmCorrectionAngle->setValue(0); //m_ccpm->ccpmCorrectionAngle->setValue(0);
NumServosDefined=3;
} }
if (TypeText.compare(QString("CCPM 3 Servo 140º"), Qt::CaseInsensitive)==0) if (TypeText.compare(QString("CCPM 3 Servo 140º"), Qt::CaseInsensitive)==0)
{ {
@ -326,7 +392,8 @@ void ConfigccpmWidget::UpdateType()
m_ccpm->ccpmAngleZ->setEnabled(0); m_ccpm->ccpmAngleZ->setEnabled(0);
m_ccpm->ccpmServoZChannel->setCurrentIndex(8); m_ccpm->ccpmServoZChannel->setCurrentIndex(8);
m_ccpm->ccpmServoZChannel->setEnabled(0); m_ccpm->ccpmServoZChannel->setEnabled(0);
m_ccpm->ccpmCorrectionAngle->setValue(0); //m_ccpm->ccpmCorrectionAngle->setValue(0);
NumServosDefined=3;
} }
if (TypeText.compare(QString("FP 2 Servo 90º"), Qt::CaseInsensitive)==0) if (TypeText.compare(QString("FP 2 Servo 90º"), Qt::CaseInsensitive)==0)
@ -341,7 +408,7 @@ void ConfigccpmWidget::UpdateType()
m_ccpm->ccpmServoZChannel->setCurrentIndex(8); m_ccpm->ccpmServoZChannel->setCurrentIndex(8);
m_ccpm->ccpmServoYChannel->setEnabled(0); m_ccpm->ccpmServoYChannel->setEnabled(0);
m_ccpm->ccpmServoZChannel->setEnabled(0); m_ccpm->ccpmServoZChannel->setEnabled(0);
m_ccpm->ccpmCorrectionAngle->setValue(0); //m_ccpm->ccpmCorrectionAngle->setValue(0);
m_ccpm->ccpmCollectivespinBox->setEnabled(0); m_ccpm->ccpmCollectivespinBox->setEnabled(0);
m_ccpm->ccpmCollectiveSlider->setEnabled(0); m_ccpm->ccpmCollectiveSlider->setEnabled(0);
@ -353,8 +420,29 @@ void ConfigccpmWidget::UpdateType()
m_ccpm->PitchCurve->setVisible(0); m_ccpm->PitchCurve->setVisible(0);
//m_ccpm->customThrottleCurve2Value->setVisible(0); //m_ccpm->customThrottleCurve2Value->setVisible(0);
//m_ccpm->label_41->setVisible(0); //m_ccpm->label_41->setVisible(0);
NumServosDefined=2;
} }
//set the visibility of the swashplate servo selection boxes
m_ccpm->ccpmServoWLabel->setVisible(NumServosDefined>=1);
m_ccpm->ccpmServoXLabel->setVisible(NumServosDefined>=2);
m_ccpm->ccpmServoYLabel->setVisible(NumServosDefined>=3);
m_ccpm->ccpmServoZLabel->setVisible(NumServosDefined>=4);
m_ccpm->ccpmServoWChannel->setVisible(NumServosDefined>=1);
m_ccpm->ccpmServoXChannel->setVisible(NumServosDefined>=2);
m_ccpm->ccpmServoYChannel->setVisible(NumServosDefined>=3);
m_ccpm->ccpmServoZChannel->setVisible(NumServosDefined>=4);
//set the visibility of the swashplate angle selection boxes
m_ccpm->ccpmServoWLabel_2->setVisible(NumServosDefined>=1);
m_ccpm->ccpmServoXLabel_2->setVisible(NumServosDefined>=2);
m_ccpm->ccpmServoYLabel_2->setVisible(NumServosDefined>=3);
m_ccpm->ccpmServoZLabel_2->setVisible(NumServosDefined>=4);
m_ccpm->ccpmAngleW->setVisible(NumServosDefined>=1);
m_ccpm->ccpmAngleX->setVisible(NumServosDefined>=2);
m_ccpm->ccpmAngleY->setVisible(NumServosDefined>=3);
m_ccpm->ccpmAngleZ->setVisible(NumServosDefined>=4);
m_ccpm->ccpmAdvancedSettingsTable->resizeColumnsToContents(); m_ccpm->ccpmAdvancedSettingsTable->resizeColumnsToContents();
for (int i=0;i<6;i++) { for (int i=0;i<6;i++) {
@ -362,9 +450,12 @@ void ConfigccpmWidget::UpdateType()
m_ccpm->ccpmAdvancedSettingsTable->verticalHeader()->width())/6); m_ccpm->ccpmAdvancedSettingsTable->verticalHeader()->width())/6);
} }
//update UI //update UI
ccpmSwashplateUpdate(); ccpmSwashplateUpdate();
} }
/** /**
@ -372,12 +463,7 @@ void ConfigccpmWidget::UpdateType()
*/ */
void ConfigccpmWidget::resetMixer(MixerCurveWidget *mixer, int numElements) void ConfigccpmWidget::resetMixer(MixerCurveWidget *mixer, int numElements)
{ {
QList<double> curveValues; mixer->initLinearCurve(numElements,(double)1);
for (double i=0; i<numElements; i++) {
curveValues.append(i/(numElements-1));
}
// Setup all Throttle1 curves for all types of airframes
mixer->initCurve(curveValues);
} }
void ConfigccpmWidget::UpdateCurveWidgets() void ConfigccpmWidget::UpdateCurveWidgets()
@ -660,17 +746,43 @@ void ConfigccpmWidget::GenerateCurve()
void ConfigccpmWidget::ccpmSwashplateRedraw() void ConfigccpmWidget::ccpmSwashplateRedraw()
{ {
double angle[CCPM_MAX_SWASH_SERVOS],CorrectionAngle,x,y,w,h,radius,CenterX,CenterY; double angle[CCPM_MAX_SWASH_SERVOS],CorrectionAngle,x,y,w,h,radius,CenterX,CenterY;
int used[CCPM_MAX_SWASH_SERVOS],i; int used[CCPM_MAX_SWASH_SERVOS],defined[CCPM_MAX_SWASH_SERVOS],i;
QRectF bounds;
QRect size;
double scale,xscale,yscale;
size = m_ccpm->SwashplateImage->rect();
xscale=size.width();
yscale=size.height();
scale=xscale;
if (yscale<scale)scale=yscale;
scale/=460.00;
m_ccpm->SwashplateImage->resetTransform ();
m_ccpm->SwashplateImage->scale(scale,scale);
size = m_ccpm->SwashLvlSwashplateImage->rect();
xscale=size.width();
yscale=size.height();
scale=xscale;
if (yscale<scale)scale=yscale;
scale/=590.00;
m_ccpm->SwashLvlSwashplateImage->resetTransform ();
m_ccpm->SwashLvlSwashplateImage->scale(scale,scale);
CorrectionAngle=m_ccpm->ccpmCorrectionAngle->value(); CorrectionAngle=m_ccpm->ccpmCorrectionAngle->value();
//CenterX=m_ccpm->SwashplateImage->scene()->sceneRect().center().x();
// CenterY=m_ccpm->SwashplateImage->scene()->sceneRect().center().y();
CenterX=200; CenterX=200;
CenterY=220; CenterY=200;
SwashplateImg->setPos(CenterX-200,CenterY-200); bounds=SwashplateImg->boundingRect();
SwashplateImg->setPos(CenterX-bounds.width()/2,CenterY-bounds.height()/2);
defined[0]=(m_ccpm->ccpmServoWChannel->isEnabled());
defined[1]=(m_ccpm->ccpmServoXChannel->isEnabled());
defined[2]=(m_ccpm->ccpmServoYChannel->isEnabled());
defined[3]=(m_ccpm->ccpmServoZChannel->isEnabled());
used[0]=((m_ccpm->ccpmServoWChannel->currentIndex()<8)&&(m_ccpm->ccpmServoWChannel->isEnabled())); used[0]=((m_ccpm->ccpmServoWChannel->currentIndex()<8)&&(m_ccpm->ccpmServoWChannel->isEnabled()));
used[1]=((m_ccpm->ccpmServoXChannel->currentIndex()<8)&&(m_ccpm->ccpmServoXChannel->isEnabled())); used[1]=((m_ccpm->ccpmServoXChannel->currentIndex()<8)&&(m_ccpm->ccpmServoXChannel->isEnabled()));
used[2]=((m_ccpm->ccpmServoYChannel->currentIndex()<8)&&(m_ccpm->ccpmServoYChannel->isEnabled())); used[2]=((m_ccpm->ccpmServoYChannel->currentIndex()<8)&&(m_ccpm->ccpmServoYChannel->isEnabled()));
@ -689,11 +801,28 @@ void ConfigccpmWidget::ccpmSwashplateRedraw()
Servos[i]->setPos(x, y); Servos[i]->setPos(x, y);
Servos[i]->setVisible(used[i]!=0); Servos[i]->setVisible(used[i]!=0);
radius=170; radius=150;
x=CenterX-(radius*sin(angle[i]))-10.00; bounds=ServosText[i]->boundingRect();
y=CenterY+(radius*cos(angle[i]))-10.00; x=CenterX-(radius*sin(angle[i]))-bounds.width()/2;
y=CenterY+(radius*cos(angle[i]))-bounds.height()/2;
ServosText[i]->setPos(x, y); ServosText[i]->setPos(x, y);
ServosText[i]->setVisible(used[i]!=0); ServosText[i]->setVisible(used[i]!=0);
if (bounds.width()>bounds.height())
{
bounds.setHeight(bounds.width());
}
else
{
bounds.setWidth(bounds.height());
}
x=CenterX-(radius*sin(angle[i]))-bounds.width()/2;
y=CenterY+(radius*cos(angle[i]))-bounds.height()/2;
ServosTextCircles[i]->setRect(bounds);
ServosTextCircles[i]->setPos(x, y);
ServosTextCircles[i]->setVisible(used[i]!=0);
w=SwashLvlSpinBoxes[i]->width()/2; w=SwashLvlSpinBoxes[i]->width()/2;
h=SwashLvlSpinBoxes[i]->height()/2; h=SwashLvlSpinBoxes[i]->height()/2;
@ -707,7 +836,7 @@ void ConfigccpmWidget::ccpmSwashplateRedraw()
x=CenterX-(radius*sin(angle[i])); x=CenterX-(radius*sin(angle[i]));
y=CenterY+(radius*cos(angle[i])); y=CenterY+(radius*cos(angle[i]));
ServoLines[i]->setLine(CenterX,CenterY,x,y); ServoLines[i]->setLine(CenterX,CenterY,x,y);
ServoLines[i]->setVisible(used[i]!=0); ServoLines[i]->setVisible(defined[i]!=0);
} }
//m_ccpm->SwashplateImage->centerOn (CenterX, CenterY); //m_ccpm->SwashplateImage->centerOn (CenterX, CenterY);
@ -718,22 +847,104 @@ void ConfigccpmWidget::ccpmSwashplateRedraw()
void ConfigccpmWidget::ccpmSwashplateUpdate() void ConfigccpmWidget::ccpmSwashplateUpdate()
{ {
ccpmSwashplateRedraw(); ccpmSwashplateRedraw();
SetUIComponentVisibilities();
UpdateMixer(); UpdateMixer();
} }
void ConfigccpmWidget::ccpmChannelCheck()
{
if((m_ccpm->ccpmServoWChannel->currentIndex()==8)&&(m_ccpm->ccpmServoWChannel->isEnabled()))
{
m_ccpm->ccpmServoWLabel->setText("<font color=red>Servo W</font>");
}
else
{
m_ccpm->ccpmServoWLabel->setText("<font color=black>Servo W</font>");
}
if((m_ccpm->ccpmServoXChannel->currentIndex()==8)&&(m_ccpm->ccpmServoXChannel->isEnabled()))
{
m_ccpm->ccpmServoXLabel->setText("<font color=red>Servo X</font>");
}
else
{
m_ccpm->ccpmServoXLabel->setText("<font color=black>Servo X</font>");
}
if((m_ccpm->ccpmServoYChannel->currentIndex()==8)&&(m_ccpm->ccpmServoYChannel->isEnabled()))
{
m_ccpm->ccpmServoYLabel->setText("<font color=red>Servo Y</font>");
}
else
{
m_ccpm->ccpmServoYLabel->setText("<font color=black>Servo Y</font>");
}
if((m_ccpm->ccpmServoZChannel->currentIndex()==8)&&(m_ccpm->ccpmServoZChannel->isEnabled()))
{
m_ccpm->ccpmServoZLabel->setText("<font color=red>Servo Z</font>");
}
else
{
m_ccpm->ccpmServoZLabel->setText("<font color=black>Servo Z</font>");
}
if((m_ccpm->ccpmEngineChannel->currentIndex()==8)&&(m_ccpm->ccpmEngineChannel->isEnabled()))
{
m_ccpm->ccpmEngineLabel->setText("<font color=red>Engine</font>");
}
else
{
m_ccpm->ccpmEngineLabel->setText("<font color=black>Engine</font>");
}
if((m_ccpm->ccpmTailChannel->currentIndex()==8)&&(m_ccpm->ccpmTailChannel->isEnabled()))
{
m_ccpm->ccpmTailLabel->setText("<font color=red>Tail Rotor</font>");
}
else
{
m_ccpm->ccpmTailLabel->setText("<font color=black>Tail Rotor</font>");
}
}
void ConfigccpmWidget::UpdateMixer() void ConfigccpmWidget::UpdateMixer()
{ {
int i,j,Type,ThisEnable[6]; bool useCCPM;
float CollectiveConstant,CorrectionAngle,ThisAngle[6]; bool useCyclic;
int i,j,ThisEnable[6];
float CollectiveConstant,PitchConstant,RollConstant,ThisAngle[6];
//QTableWidgetItem *newItem;// = new QTableWidgetItem(); //QTableWidgetItem *newItem;// = new QTableWidgetItem();
QString Channel; QString Channel;
Type = m_ccpm->ccpmType->count() - m_ccpm->ccpmType->currentIndex()-1; ccpmChannelCheck();
CollectiveConstant=m_ccpm->ccpmCollectiveSlider->value()/100.0; //Type = m_ccpm->ccpmType->count() - m_ccpm->ccpmType->currentIndex()-1;
CorrectionAngle=m_ccpm->ccpmCorrectionAngle->value(); //CollectiveConstant=m_ccpm->ccpmCollectiveSlider->value()/100.0;
//CorrectionAngle=m_ccpm->ccpmCorrectionAngle->value();
UpdatCCPMOptionsFromUI();
useCCPM = !(GUIConfigData.heli.ccpmCollectivePassthroughState || !GUIConfigData.heli.ccpmLinkCyclicState);
useCyclic = GUIConfigData.heli.ccpmLinkRollState;
CollectiveConstant = (float)GUIConfigData.heli.SliderValue0 / 100.00;
if (Type>0) if (useCCPM)
{//cyclic = 1 - collective
PitchConstant = 1-CollectiveConstant;
RollConstant = PitchConstant;
}
else
{
PitchConstant = (float)GUIConfigData.heli.SliderValue1 / 100.00;;
if (useCyclic)
{
RollConstant = PitchConstant;
}
else
{
RollConstant = (float)GUIConfigData.heli.SliderValue2 / 100.00;;
}
}
if (GUIConfigData.heli.SwasplateType>0)
{//not advanced settings {//not advanced settings
//get the channel data from the ui //get the channel data from the ui
MixerChannelData[0] = m_ccpm->ccpmEngineChannel->currentIndex(); MixerChannelData[0] = m_ccpm->ccpmEngineChannel->currentIndex();
@ -797,8 +1008,8 @@ void ConfigccpmWidget::UpdateMixer()
{//Swashplate {//Swashplate
m_ccpm->ccpmAdvancedSettingsTable->item(i,1)->setText(QString("%1").arg(0));//ThrottleCurve1 m_ccpm->ccpmAdvancedSettingsTable->item(i,1)->setText(QString("%1").arg(0));//ThrottleCurve1
m_ccpm->ccpmAdvancedSettingsTable->item(i,2)->setText(QString("%1").arg((int)(127.0*CollectiveConstant)));//ThrottleCurve2 m_ccpm->ccpmAdvancedSettingsTable->item(i,2)->setText(QString("%1").arg((int)(127.0*CollectiveConstant)));//ThrottleCurve2
m_ccpm->ccpmAdvancedSettingsTable->item(i,3)->setText(QString("%1").arg((int)(127.0*(1-CollectiveConstant)*sin((180+CorrectionAngle + ThisAngle[i])*Pi/180.00))));//Roll m_ccpm->ccpmAdvancedSettingsTable->item(i,3)->setText(QString("%1").arg((int)(127.0*(RollConstant)*sin((180+GUIConfigData.heli.CorrectionAngle + ThisAngle[i])*Pi/180.00))));//Roll
m_ccpm->ccpmAdvancedSettingsTable->item(i,4)->setText(QString("%1").arg((int)(127.0*(1-CollectiveConstant)*cos((CorrectionAngle + ThisAngle[i])*Pi/180.00))));//Pitch m_ccpm->ccpmAdvancedSettingsTable->item(i,4)->setText(QString("%1").arg((int)(127.0*(PitchConstant)*cos((GUIConfigData.heli.CorrectionAngle + ThisAngle[i])*Pi/180.00))));//Pitch
m_ccpm->ccpmAdvancedSettingsTable->item(i,5)->setText(QString("%1").arg(0));//Yaw m_ccpm->ccpmAdvancedSettingsTable->item(i,5)->setText(QString("%1").arg(0));//Yaw
} }
@ -827,6 +1038,140 @@ void ConfigccpmWidget::UpdateMixer()
/************************** /**************************
* ccpm settings * ccpm settings
**************************/ **************************/
/*
Get the state of the UI check boxes and change the visibility of sliders
typedef struct {
uint SwasplateType:3;
uint FirstServoIndex:2;
uint CorrectionAngle:9;
uint ccpmCollectivePassthroughState:1;
uint ccpmLinkCyclicState:1;
uint ccpmLinkRollState:1;
uint CollectiveChannel:3;
uint padding:12;
} __attribute__((packed)) heliGUISettingsStruct;
*/
void ConfigccpmWidget::UpdatCCPMOptionsFromUI()
{
bool useCCPM;
bool useCyclic;
if (updatingFromHardware) return;
//get the user options
//swashplate config
GUIConfigData.heli.SwasplateType = m_ccpm->ccpmType->count() - m_ccpm->ccpmType->currentIndex()-1;
GUIConfigData.heli.FirstServoIndex = m_ccpm->ccpmSingleServo->currentIndex();
//ccpm mixing options
GUIConfigData.heli.ccpmCollectivePassthroughState = m_ccpm->ccpmCollectivePassthrough->isChecked();
GUIConfigData.heli.ccpmLinkCyclicState = m_ccpm->ccpmLinkCyclic->isChecked();
GUIConfigData.heli.ccpmLinkRollState = m_ccpm->ccpmLinkRoll->isChecked();
useCCPM = !(GUIConfigData.heli.ccpmCollectivePassthroughState || !GUIConfigData.heli.ccpmLinkCyclicState);
useCyclic = GUIConfigData.heli.ccpmLinkRollState;
//correction angle
GUIConfigData.heli.CorrectionAngle = m_ccpm->ccpmCorrectionAngle->value();
//CollectiveChannel
GUIConfigData.heli.CollectiveChannel = m_ccpm->ccpmCollectiveChannel->currentIndex();
//update sliders
if (useCCPM)
{
GUIConfigData.heli.SliderValue0 = m_ccpm->ccpmCollectiveSlider->value();
}
else
{
GUIConfigData.heli.SliderValue0 = m_ccpm->ccpmCollectiveScale->value();
}
if (useCyclic)
{
GUIConfigData.heli.SliderValue1 = m_ccpm->ccpmCyclicScale->value();
}
else
{
GUIConfigData.heli.SliderValue1 = m_ccpm->ccpmPitchScale->value();
}
GUIConfigData.heli.SliderValue2 = m_ccpm->ccpmRollScale->value();
//GUIConfigData.heli.RevoSlider = m_ccpm->ccpmREVOScale->value();
//servo assignments
GUIConfigData.heli.ServoIndexW = m_ccpm->ccpmServoWChannel->currentIndex();
GUIConfigData.heli.ServoIndexX = m_ccpm->ccpmServoXChannel->currentIndex();
GUIConfigData.heli.ServoIndexY = m_ccpm->ccpmServoYChannel->currentIndex();
GUIConfigData.heli.ServoIndexZ = m_ccpm->ccpmServoZChannel->currentIndex();
}
void ConfigccpmWidget::UpdatCCPMUIFromOptions()
{
//swashplate config
m_ccpm->ccpmType->setCurrentIndex(m_ccpm->ccpmType->count() - (GUIConfigData.heli.SwasplateType +1));
m_ccpm->ccpmSingleServo->setCurrentIndex(GUIConfigData.heli.FirstServoIndex);
//ccpm mixing options
m_ccpm->ccpmCollectivePassthrough->setChecked(GUIConfigData.heli.ccpmCollectivePassthroughState);
m_ccpm->ccpmLinkCyclic->setChecked(GUIConfigData.heli.ccpmLinkCyclicState);
m_ccpm->ccpmLinkRoll->setChecked(GUIConfigData.heli.ccpmLinkRollState);
//correction angle
m_ccpm->ccpmCorrectionAngle->setValue(GUIConfigData.heli.CorrectionAngle);
//CollectiveChannel
m_ccpm->ccpmCollectiveChannel->setCurrentIndex(GUIConfigData.heli.CollectiveChannel);
//update sliders
m_ccpm->ccpmCollectiveScale->setValue(GUIConfigData.heli.SliderValue0);
m_ccpm->ccpmCollectiveScaleBox->setValue(GUIConfigData.heli.SliderValue0);
m_ccpm->ccpmCyclicScale->setValue(GUIConfigData.heli.SliderValue1);
m_ccpm->ccpmCyclicScaleBox->setValue(GUIConfigData.heli.SliderValue1);
m_ccpm->ccpmPitchScale->setValue(GUIConfigData.heli.SliderValue1);
m_ccpm->ccpmPitchScaleBox->setValue(GUIConfigData.heli.SliderValue1);
m_ccpm->ccpmRollScale->setValue(GUIConfigData.heli.SliderValue2);
m_ccpm->ccpmRollScaleBox->setValue(GUIConfigData.heli.SliderValue2);
m_ccpm->ccpmCollectiveSlider->setValue(GUIConfigData.heli.SliderValue0);
m_ccpm->ccpmCollectivespinBox->setValue(GUIConfigData.heli.SliderValue0);
//m_ccpm->ccpmREVOScale->setValue(GUIConfigData.heli.RevoSlider);
//servo assignments
m_ccpm->ccpmServoWChannel->setCurrentIndex(GUIConfigData.heli.ServoIndexW);
m_ccpm->ccpmServoXChannel->setCurrentIndex(GUIConfigData.heli.ServoIndexX);
m_ccpm->ccpmServoYChannel->setCurrentIndex(GUIConfigData.heli.ServoIndexY);
m_ccpm->ccpmServoZChannel->setCurrentIndex(GUIConfigData.heli.ServoIndexZ);
}
void ConfigccpmWidget::SetUIComponentVisibilities()
{
UpdatCCPMOptionsFromUI();
//set which sliders are user...
m_ccpm->ccpmRevoMixingBox->setVisible(0);
m_ccpm->ccpmPitchMixingBox->setVisible(!GUIConfigData.heli.ccpmCollectivePassthroughState && GUIConfigData.heli.ccpmLinkCyclicState);
m_ccpm->ccpmCollectiveScalingBox->setVisible(GUIConfigData.heli.ccpmCollectivePassthroughState || !GUIConfigData.heli.ccpmLinkCyclicState);
m_ccpm->ccpmCollectiveChLabel->setVisible(GUIConfigData.heli.ccpmCollectivePassthroughState);
m_ccpm->ccpmCollectiveChannel->setVisible(GUIConfigData.heli.ccpmCollectivePassthroughState);
m_ccpm->ccpmLinkCyclic->setVisible(!GUIConfigData.heli.ccpmCollectivePassthroughState);
m_ccpm->ccpmCyclicScalingBox->setVisible((GUIConfigData.heli.ccpmCollectivePassthroughState || !GUIConfigData.heli.ccpmLinkCyclicState) && GUIConfigData.heli.ccpmLinkRollState);
if (!GUIConfigData.heli.ccpmCollectivePassthroughState && GUIConfigData.heli.ccpmLinkCyclicState)
{
m_ccpm->ccpmPitchScalingBox->setVisible(0);
m_ccpm->ccpmRollScalingBox->setVisible(0);
m_ccpm->ccpmLinkRoll->setVisible(0);
}
else
{
m_ccpm->ccpmPitchScalingBox->setVisible(!GUIConfigData.heli.ccpmLinkRollState);
m_ccpm->ccpmRollScalingBox->setVisible(!GUIConfigData.heli.ccpmLinkRollState);
m_ccpm->ccpmLinkRoll->setVisible(1);
}
}
/** /**
Request the current value of the SystemSettings which holds the ccpm type Request the current value of the SystemSettings which holds the ccpm type
*/ */
@ -843,12 +1188,22 @@ void ConfigccpmWidget::requestccpmUpdate()
int isCCPM=0; int isCCPM=0;
if (SwashLvlConfigurationInProgress)return; if (SwashLvlConfigurationInProgress)return;
if (updatingToHardware)return;
updatingFromHardware=TRUE;
ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance(); ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance();
UAVObjectManager *objManager = pm->getObject<UAVObjectManager>(); UAVObjectManager *objManager = pm->getObject<UAVObjectManager>();
int i,j; int i,j;
UAVObjectField *field; UAVObjectField *field;
UAVDataObject* obj; UAVDataObject* obj;
obj = dynamic_cast<UAVDataObject*>(getObjectManager()->getObject(QString("SystemSettings")));
field = obj->getField(QString("GUIConfigData"));
GUIConfigData.UAVObject[0]=field->getValue(0).toUInt();
GUIConfigData.UAVObject[1]=field->getValue(1).toUInt();
UpdatCCPMUIFromOptions();
obj = dynamic_cast<UAVDataObject*>(objManager->getObject(QString("MixerSettings"))); obj = dynamic_cast<UAVDataObject*>(objManager->getObject(QString("MixerSettings")));
Q_ASSERT(obj); Q_ASSERT(obj);
@ -933,6 +1288,7 @@ void ConfigccpmWidget::requestccpmUpdate()
//just call it user angles for now.... //just call it user angles for now....
/*
m_ccpm->ccpmType->setCurrentIndex(m_ccpm->ccpmType->findText("Custom - User Angles")); m_ccpm->ccpmType->setCurrentIndex(m_ccpm->ccpmType->findText("Custom - User Angles"));
if (NumServos>1) if (NumServos>1)
@ -963,9 +1319,11 @@ void ConfigccpmWidget::requestccpmUpdate()
{//must be a custom config... "Custom - Advanced Settings" {//must be a custom config... "Custom - Advanced Settings"
m_ccpm->ccpmType->setCurrentIndex(m_ccpm->ccpmType->findText("Custom - Advanced Settings")); m_ccpm->ccpmType->setCurrentIndex(m_ccpm->ccpmType->findText("Custom - Advanced Settings"));
} }
HeadRotation=0; HeadRotation=0;
//calculate the angles
HeadRotation=m_ccpm->ccpmSingleServo->currentIndex();
//calculate the angles
for(j=0;j<NumServos;j++) for(j=0;j<NumServos;j++)
{ {
//MixerDataFromHeli[i][2]=(127.0*(1-CollectiveConstant)*sin((CorrectionAngle + ThisAngle[i])*Pi/180.00))));//Roll //MixerDataFromHeli[i][2]=(127.0*(1-CollectiveConstant)*sin((CorrectionAngle + ThisAngle[i])*Pi/180.00))));//Roll
@ -981,7 +1339,7 @@ void ConfigccpmWidget::requestccpmUpdate()
} }
//set the head rotation //set the head rotation
m_ccpm->ccpmSingleServo->setCurrentIndex(HeadRotation); //m_ccpm->ccpmSingleServo->setCurrentIndex(HeadRotation);
//calculate the un rotated angles //calculate the un rotated angles
for(j=0;j<NumServos;j++) for(j=0;j<NumServos;j++)
@ -1001,15 +1359,19 @@ void ConfigccpmWidget::requestccpmUpdate()
} }
m_ccpm->ccpmAngleW->setValue(ServoAngles[SortAngles[0]]); //m_ccpm->ccpmAngleW->setValue(ServoAngles[SortAngles[0]]);
m_ccpm->ccpmAngleX->setValue(ServoAngles[SortAngles[1]]); //m_ccpm->ccpmAngleX->setValue(ServoAngles[SortAngles[1]]);
m_ccpm->ccpmAngleY->setValue(ServoAngles[SortAngles[2]]); //m_ccpm->ccpmAngleY->setValue(ServoAngles[SortAngles[2]]);
m_ccpm->ccpmAngleZ->setValue(ServoAngles[SortAngles[3]]); //m_ccpm->ccpmAngleZ->setValue(ServoAngles[SortAngles[3]]);
m_ccpm->ccpmServoWChannel->setCurrentIndex(ServoChannels[SortAngles[0]]); //m_ccpm->ccpmServoWChannel->setCurrentIndex(ServoChannels[SortAngles[0]]);
m_ccpm->ccpmServoXChannel->setCurrentIndex(ServoChannels[SortAngles[1]]); //m_ccpm->ccpmServoXChannel->setCurrentIndex(ServoChannels[SortAngles[1]]);
m_ccpm->ccpmServoYChannel->setCurrentIndex(ServoChannels[SortAngles[2]]); //m_ccpm->ccpmServoYChannel->setCurrentIndex(ServoChannels[SortAngles[2]]);
m_ccpm->ccpmServoZChannel->setCurrentIndex(ServoChannels[SortAngles[3]]); //m_ccpm->ccpmServoZChannel->setCurrentIndex(ServoChannels[SortAngles[3]]);
m_ccpm->ccpmServoWChannel->setCurrentIndex(ServoChannels[0]);
m_ccpm->ccpmServoXChannel->setCurrentIndex(ServoChannels[1]);
m_ccpm->ccpmServoYChannel->setCurrentIndex(ServoChannels[2]);
m_ccpm->ccpmServoZChannel->setCurrentIndex(ServoChannels[3]);
//Types << "CCPM 2 Servo 90º" << "CCPM 3 Servo 120º" << "CCPM 3 Servo 140º" << "FP 2 Servo 90º" << "Custom - User Angles" << "Custom - Advanced Settings" ; //Types << "CCPM 2 Servo 90º" << "CCPM 3 Servo 120º" << "CCPM 3 Servo 140º" << "FP 2 Servo 90º" << "Custom - User Angles" << "Custom - Advanced Settings" ;
@ -1075,7 +1437,7 @@ void ConfigccpmWidget::requestccpmUpdate()
{ {
} }
*/
@ -1096,7 +1458,8 @@ void ConfigccpmWidget::requestccpmUpdate()
updatingFromHardware=FALSE;
UpdatCCPMUIFromOptions();
ccpmSwashplateUpdate(); ccpmSwashplateUpdate();
} }
@ -1112,10 +1475,22 @@ void ConfigccpmWidget::sendccpmUpdate()
UAVDataObject* obj; UAVDataObject* obj;
if (SwashLvlConfigurationInProgress)return; if (SwashLvlConfigurationInProgress)return;
ShowDisclaimer(1); updatingToHardware=TRUE;
//ShowDisclaimer(1);
ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance(); ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance();
UAVObjectManager *objManager = pm->getObject<UAVObjectManager>(); UAVObjectManager *objManager = pm->getObject<UAVObjectManager>();
UpdatCCPMOptionsFromUI();
obj = dynamic_cast<UAVDataObject*>(getObjectManager()->getObject(QString("SystemSettings")));
field = obj->getField(QString("GUIConfigData"));
field->setValue(GUIConfigData.UAVObject[0],0);
field->setValue(GUIConfigData.UAVObject[1],1);
obj->updated();
obj = dynamic_cast<UAVDataObject*>(objManager->getObject(QString("MixerSettings"))); obj = dynamic_cast<UAVDataObject*>(objManager->getObject(QString("MixerSettings")));
Q_ASSERT(obj); Q_ASSERT(obj);
@ -1181,8 +1556,32 @@ void ConfigccpmWidget::sendccpmUpdate()
field->setValue(m_ccpm->CurveSettings->item(i, 1)->text().toDouble(),i); field->setValue(m_ccpm->CurveSettings->item(i, 1)->text().toDouble(),i);
} }
obj->updated();
field = obj->getField(QString("Curve2Source"));
//mapping of collective input to curve 2...
//MixerSettings.Curve2Source = Throttle,Roll,Pitch,Yaw,Accessory0,Accessory1,Accessory2,Accessory3,Accessory4,Accessory5
//check if we are using throttle or directly from a channel...
if (GUIConfigData.heli.ccpmCollectivePassthroughState)
{// input channel
field->setValue("Accessory0");
obj->updated(); obj->updated();
obj = dynamic_cast<UAVDataObject*>(objManager->getObject(QString("ManualControlSettings")));
Q_ASSERT(obj);
field = obj->getField(QString("Accessory0"));
field->setValue(tr( "Channel%1" ).arg(GUIConfigData.heli.CollectiveChannel+1));
}
else
{// throttle
field->setValue("Throttle");
}
obj->updated();
updatingToHardware=FALSE;
} }
@ -1220,6 +1619,7 @@ void ConfigccpmWidget::showEvent(QShowEvent *event)
m_ccpm->ccpmAdvancedSettingsTable->setColumnWidth(i,(m_ccpm->ccpmAdvancedSettingsTable->width()- m_ccpm->ccpmAdvancedSettingsTable->setColumnWidth(i,(m_ccpm->ccpmAdvancedSettingsTable->width()-
m_ccpm->ccpmAdvancedSettingsTable->verticalHeader()->width())/6); m_ccpm->ccpmAdvancedSettingsTable->verticalHeader()->width())/6);
} }
ccpmSwashplateRedraw();
} }

View File

@ -34,6 +34,7 @@
#include "uavobject.h" #include "uavobject.h"
#include <QtSvg/QSvgRenderer> #include <QtSvg/QSvgRenderer>
#include <QtSvg/QGraphicsSvgItem> #include <QtSvg/QGraphicsSvgItem>
#include <QGraphicsEllipseItem>
#include <QtGui/QWidget> #include <QtGui/QWidget>
#include <QList> #include <QList>
@ -49,6 +50,30 @@ typedef struct {
int Min[CCPM_MAX_SWASH_SERVOS]; int Min[CCPM_MAX_SWASH_SERVOS];
} SwashplateServoSettingsStruct; } SwashplateServoSettingsStruct;
typedef struct {
uint SwasplateType:3;
uint FirstServoIndex:2;
uint CorrectionAngle:9;
uint ccpmCollectivePassthroughState:1;
uint ccpmLinkCyclicState:1;
uint ccpmLinkRollState:1;
uint CollectiveChannel:3;//20bits
uint SliderValue0:7;
uint SliderValue1:7;
uint SliderValue2:7;//41bits
uint ServoIndexW:4;
uint ServoIndexX:4;
uint ServoIndexY:4;
uint ServoIndexZ:4;//57bits
uint padding:7;
} __attribute__((packed)) heliGUISettingsStruct;
typedef union
{
uint UAVObject[2];//32bits * 2
heliGUISettingsStruct heli;//64bits
} GUIConfigDataUnion;
class ConfigccpmWidget: public ConfigTaskWidget class ConfigccpmWidget: public ConfigTaskWidget
{ {
Q_OBJECT Q_OBJECT
@ -72,6 +97,7 @@ private:
QGraphicsSvgItem *Servos[CCPM_MAX_SWASH_SERVOS]; QGraphicsSvgItem *Servos[CCPM_MAX_SWASH_SERVOS];
QGraphicsTextItem *ServosText[CCPM_MAX_SWASH_SERVOS]; QGraphicsTextItem *ServosText[CCPM_MAX_SWASH_SERVOS];
QGraphicsLineItem *ServoLines[CCPM_MAX_SWASH_SERVOS]; QGraphicsLineItem *ServoLines[CCPM_MAX_SWASH_SERVOS];
QGraphicsEllipseItem *ServosTextCircles[CCPM_MAX_SWASH_SERVOS];
QSpinBox *SwashLvlSpinBoxes[CCPM_MAX_SWASH_SERVOS]; QSpinBox *SwashLvlSpinBoxes[CCPM_MAX_SWASH_SERVOS];
bool SwashLvlConfigurationInProgress; bool SwashLvlConfigurationInProgress;
@ -82,11 +108,15 @@ private:
SwashplateServoSettingsStruct oldSwashLvlConfiguration; SwashplateServoSettingsStruct oldSwashLvlConfiguration;
SwashplateServoSettingsStruct newSwashLvlConfiguration; SwashplateServoSettingsStruct newSwashLvlConfiguration;
GUIConfigDataUnion GUIConfigData;
int MixerChannelData[6]; int MixerChannelData[6];
int ShowDisclaimer(int messageID); int ShowDisclaimer(int messageID);
virtual void enableControls(bool enable) { Q_UNUSED(enable)}; // Not used by this widget virtual void enableControls(bool enable) { Q_UNUSED(enable)}; // Not used by this widget
bool updatingFromHardware;
bool updatingToHardware;
private slots: private slots:
void ccpmSwashplateUpdate(); void ccpmSwashplateUpdate();
void ccpmSwashplateRedraw(); void ccpmSwashplateRedraw();
@ -104,6 +134,12 @@ private:
void SwashLvlCancelButtonPressed(); void SwashLvlCancelButtonPressed();
void SwashLvlFinishButtonPressed(); void SwashLvlFinishButtonPressed();
void UpdatCCPMOptionsFromUI();
void UpdatCCPMUIFromOptions();
void SetUIComponentVisibilities();
void ccpmChannelCheck();
void enableSwashplateLevellingControl(bool state); void enableSwashplateLevellingControl(bool state);
void setSwashplateLevel(int percent); void setSwashplateLevel(int percent);
void SwashLvlSpinBoxChanged(int value); void SwashLvlSpinBoxChanged(int value);

View File

@ -538,7 +538,7 @@ void ConfigInputWidget::updateChannels(UAVObject* controlCommand)
obj->setMetadata(mdata); obj->setMetadata(mdata);
// Set some slider values to better defaults // Set some slider values to better defaults
// Find what channel we used for throttle, set it 2% about min: // Find some channels first
int throttleChannel = -1; int throttleChannel = -1;
int fmChannel = -1; int fmChannel = -1;
for (int i=0; i < inChannelAssign.length(); i++) { for (int i=0; i < inChannelAssign.length(); i++) {
@ -558,17 +558,10 @@ void ConfigInputWidget::updateChannels(UAVObject* controlCommand)
// Throttle neutral defaults to 2% of range // Throttle neutral defaults to 2% of range
if (throttleChannel > -1) { if (throttleChannel > -1) {
if (inRevCheckboxes[throttleChannel]->isChecked()) { inSliders.at(throttleChannel)->setValue(
inSliders.at(throttleChannel)->setValue( inSliders.at(throttleChannel)->minimum() +
inSliders.at(throttleChannel)->maximum() - (inSliders.at(throttleChannel)->maximum()-
(inSliders.at(throttleChannel)->maximum()- inSliders.at(throttleChannel)->minimum())*0.02);
inSliders.at(throttleChannel)->minimum())*0.02);
} else {
inSliders.at(throttleChannel)->setValue(
inSliders.at(throttleChannel)->minimum() +
(inSliders.at(throttleChannel)->maximum()-
inSliders.at(throttleChannel)->minimum())*0.02);
}
} }
// Flight mode at 50% of range: // Flight mode at 50% of range:

View File

@ -147,7 +147,17 @@ QList<double> MixerCurveWidget::getCurve() {
return list; return list;
} }
/**
Sets a linear graph
*/
void MixerCurveWidget::initLinearCurve(quint32 numPoints, double maxValue)
{
QList<double> points;
for (double i=0; i<numPoints;i++) {
points.append(maxValue*(i/(numPoints-1)));
}
initCurve(points);
}
/** /**
Setd the current curve settings Setd the current curve settings
*/ */

View File

@ -45,6 +45,7 @@ public:
void itemMoved(double itemValue); // Callback when a point is moved, to be updated void itemMoved(double itemValue); // Callback when a point is moved, to be updated
void initCurve (QList<double> points); void initCurve (QList<double> points);
QList<double> getCurve(); QList<double> getCurve();
void initLinearCurve(quint32 numPoints, double maxValue);
void setCurve(QList<double>); void setCurve(QList<double>);
void setMin(double value); void setMin(double value);
void setMax(double value); void setMax(double value);

View File

@ -68,6 +68,7 @@ HEADERS += $$UAVOBJECT_SYNTHETICS/accessorydesired.h \
$$UAVOBJECT_SYNTHETICS/nedaccel.h \ $$UAVOBJECT_SYNTHETICS/nedaccel.h \
$$UAVOBJECT_SYNTHETICS/sonaraltitude.h \ $$UAVOBJECT_SYNTHETICS/sonaraltitude.h \
$$UAVOBJECT_SYNTHETICS/flightstatus.h \ $$UAVOBJECT_SYNTHETICS/flightstatus.h \
$$UAVOBJECT_SYNTHETICS/hwsettings.h \
$$UAVOBJECT_SYNTHETICS/attitudesettings.h $$UAVOBJECT_SYNTHETICS/attitudesettings.h
SOURCES += $$UAVOBJECT_SYNTHETICS/accessorydesired.cpp \ SOURCES += $$UAVOBJECT_SYNTHETICS/accessorydesired.cpp \
@ -116,4 +117,5 @@ SOURCES += $$UAVOBJECT_SYNTHETICS/accessorydesired.cpp \
$$UAVOBJECT_SYNTHETICS/sonaraltitude.cpp \ $$UAVOBJECT_SYNTHETICS/sonaraltitude.cpp \
$$UAVOBJECT_SYNTHETICS/uavobjectsinit.cpp \ $$UAVOBJECT_SYNTHETICS/uavobjectsinit.cpp \
$$UAVOBJECT_SYNTHETICS/flightstatus.cpp \ $$UAVOBJECT_SYNTHETICS/flightstatus.cpp \
$$UAVOBJECT_SYNTHETICS/hwsettings.cpp \
$$UAVOBJECT_SYNTHETICS/attitudesettings.cpp $$UAVOBJECT_SYNTHETICS/attitudesettings.cpp

View File

@ -261,18 +261,45 @@ QByteArray UAVObjectUtilManager::getBoardCPUSerial()
loop.exec(); loop.exec();
UAVObjectField* cpuField = obj->getField("CPUSerial"); UAVObjectField* cpuField = obj->getField("CPUSerial");
for (int i = 0; i < cpuField->getNumElements(); ++i) { for (uint i = 0; i < cpuField->getNumElements(); ++i) {
cpuSerial.append(cpuField->getValue(i).toUInt()); cpuSerial.append(cpuField->getValue(i).toUInt());
} }
return cpuSerial; return cpuSerial;
} }
quint32 UAVObjectUtilManager::getFirmwareCRC()
{
quint32 fwCRC;
ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance();
if (!pm)
return 0;
UAVObjectManager *om = pm->getObject<UAVObjectManager>();
if (!om)
return 0;
UAVDataObject *obj = dynamic_cast<UAVDataObject *>(om->getObject(QString("FirmwareIAPObj")));
obj->getField("crc")->setValue(0);
obj->updated();
// The code below will ask for the object update and wait for the updated to be received,
// or the timeout of the timer, set to 1 second.
QEventLoop loop;
connect(obj, SIGNAL(objectUpdated(UAVObject*)), &loop, SLOT(quit()));
QTimer::singleShot(1000, &loop, SLOT(quit())); // Create a timeout
obj->requestUpdate();
loop.exec();
UAVObjectField* fwCRCField = obj->getField("crc");
fwCRC=(quint32)fwCRCField->getValue().toLongLong();
return fwCRC;
}
/** /**
* Get the UAV Board Description, for anyone interested. * Get the UAV Board Description, for anyone interested.
*/ */
QString UAVObjectUtilManager::getBoardDescription() QByteArray UAVObjectUtilManager::getBoardDescription()
{ {
QString description; QByteArray ret;
ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance(); ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance();
if (!pm) if (!pm)
return 0; return 0;
@ -291,10 +318,10 @@ QString UAVObjectUtilManager::getBoardDescription()
UAVObjectField* descriptionField = obj->getField("Description"); UAVObjectField* descriptionField = obj->getField("Description");
// Description starts with an offset of // Description starts with an offset of
for (int i = 14; i < descriptionField->getNumElements(); ++i) { for (uint i = 0; i < descriptionField->getNumElements(); ++i) {
description.append(descriptionField->getValue(i).toChar()); ret.append(descriptionField->getValue(i).toInt());
} }
return description; return ret;
} }

View File

@ -63,7 +63,8 @@ public:
int getBoardModel(); int getBoardModel();
QByteArray getBoardCPUSerial(); QByteArray getBoardCPUSerial();
QString getBoardDescription(); quint32 getFirmwareCRC();
QByteArray getBoardDescription();
UAVObjectManager* getObjectManager(); UAVObjectManager* getObjectManager();
void saveObjectToSD(UAVObject *obj); void saveObjectToSD(UAVObject *obj);

View File

@ -0,0 +1,5 @@
#include "devicedescriptorstruct.h"
deviceDescriptorStruct::deviceDescriptorStruct()
{
}

View File

@ -0,0 +1,36 @@
#ifndef DEVICEDESCRIPTORSTRUCT_H
#define DEVICEDESCRIPTORSTRUCT_H
#include <QString>
struct deviceDescriptorStruct
{
public:
QString gitTag;
QString buildDate;
QString description;
int boardType;
int boardRevision;
static QString idToBoardName(int id)
{
switch (id | 0x0011) {
case 0x0111://MB
return QString("Board name: OpenPilot MainBoard");
break;
case 0x0311://PipX
return QString("Board name: PipXtreame");
break;
case 0x0411://Coptercontrol
return QString("Board name: CopterControl");
break;
case 0x0211://INS
return QString("Board name: OpenPilot INS");
break;
default:
return QString("");
break;
}
}
deviceDescriptorStruct();
};
#endif // DEVICEDESCRIPTORSTRUCT_H

View File

@ -34,16 +34,18 @@ deviceWidget::deviceWidget(QWidget *parent) :
devicePic = NULL; // Initialize pointer to null devicePic = NULL; // Initialize pointer to null
// Initialization of the Device icon display // Initialization of the Device icon display
myDevice->devicePicture->setScene(new QGraphicsScene(this)); myDevice->verticalGroupBox_loaded->setVisible(false);
myDevice->groupCustom->setVisible(false);
connect(myDevice->verifyButton, SIGNAL(clicked()), this, SLOT(verifyFirmware())); myDevice->youdont->setVisible(false);
myDevice->gVDevice->setScene(new QGraphicsScene(this));
connect(myDevice->retrieveButton, SIGNAL(clicked()), this, SLOT(downloadFirmware())); connect(myDevice->retrieveButton, SIGNAL(clicked()), this, SLOT(downloadFirmware()));
connect(myDevice->updateButton, SIGNAL(clicked()), this, SLOT(uploadFirmware())); connect(myDevice->updateButton, SIGNAL(clicked()), this, SLOT(uploadFirmware()));
connect(myDevice->pbLoad, SIGNAL(clicked()), this, SLOT(loadFirmware()));
connect(myDevice->youdont, SIGNAL(stateChanged(int)), this, SLOT(confirmCB(int)));
QPixmap pix = QPixmap(QString(":uploader/images/view-refresh.svg")); QPixmap pix = QPixmap(QString(":uploader/images/view-refresh.svg"));
myDevice->statusIcon->setPixmap(pix); myDevice->statusIcon->setPixmap(pix);
myDevice->certifiedFW->setText(""); myDevice->lblCertified->setText("");
} }
@ -54,14 +56,16 @@ void deviceWidget::showEvent(QShowEvent *event)
// widget is shown, otherwise it cannot compute its values and // widget is shown, otherwise it cannot compute its values and
// the result is usually a ahrsbargraph that is way too small. // the result is usually a ahrsbargraph that is way too small.
if (devicePic) if (devicePic)
myDevice->devicePicture->fitInView(devicePic,Qt::KeepAspectRatio); {
myDevice->gVDevice->fitInView(devicePic,Qt::KeepAspectRatio);
}
} }
void deviceWidget::resizeEvent(QResizeEvent* event) void deviceWidget::resizeEvent(QResizeEvent* event)
{ {
Q_UNUSED(event); Q_UNUSED(event);
if (devicePic) if (devicePic)
myDevice->devicePicture->fitInView(devicePic, Qt::KeepAspectRatio); myDevice->gVDevice->fitInView(devicePic, Qt::KeepAspectRatio);
} }
@ -74,21 +78,43 @@ void deviceWidget::setDfu(DFUObject *dfu)
m_dfu = dfu; m_dfu = dfu;
} }
QString deviceWidget::idToBoardName(int id)
{
switch (id | 0x0011) {
case 0x0111://MB
return QString("Board name: OpenPilot MainBoard");
break;
case 0x0311://PipX
return QString("Board name: PipXtreame");
break;
case 0x0411://Coptercontrol
return QString("Board name: CopterControl");
break;
case 0x0211://INS
return QString("Board name: OpenPilot INS");
break;
default:
return QString("");
break;
}
}
/** /**
Fills the various fields for the device Fills the various fields for the device
*/ */
void deviceWidget::populate() void deviceWidget::populate()
{ {
int id = m_dfu->devices[deviceID].ID; int id = m_dfu->devices[deviceID].ID;
myDevice->deviceID->setText(QString("Device ID: ") + QString::number(id, 16)); myDevice->lbldevID->setText(QString("Device ID: ") + QString::number(id, 16));
// DeviceID tells us what sort of HW we have detected: // DeviceID tells us what sort of HW we have detected:
// display a nice icon: // display a nice icon:
myDevice->devicePicture->scene()->clear(); myDevice->gVDevice->scene()->clear();
if (devicePic) myDevice->lblDevName->setText(deviceDescriptorStruct::idToBoardName(id));
delete devicePic; myDevice->lblHWRev->setText(QString(tr("HW Revision: "))+QString::number(id & 0x0011, 16));
devicePic = new QGraphicsSvgItem(); devicePic = new QGraphicsSvgItem();
devicePic->setSharedRenderer(new QSvgRenderer()); devicePic->setSharedRenderer(new QSvgRenderer());
switch (id) { switch (id) {
case 0x0101: case 0x0101:
devicePic->renderer()->load(QString(":/uploader/images/deviceID-0101.svg")); devicePic->renderer()->load(QString(":/uploader/images/deviceID-0101.svg"));
@ -106,35 +132,35 @@ void deviceWidget::populate()
break; break;
} }
devicePic->setElementId("device"); devicePic->setElementId("device");
myDevice->devicePicture->scene()->addItem(devicePic); myDevice->gVDevice->scene()->addItem(devicePic);
myDevice->devicePicture->setSceneRect(devicePic->boundingRect()); myDevice->gVDevice->setSceneRect(devicePic->boundingRect());
myDevice->devicePicture->fitInView(devicePic,Qt::KeepAspectRatio); myDevice->gVDevice->fitInView(devicePic,Qt::KeepAspectRatio);
bool r = m_dfu->devices[deviceID].Readable; bool r = m_dfu->devices[deviceID].Readable;
bool w = m_dfu->devices[deviceID].Writable; bool w = m_dfu->devices[deviceID].Writable;
myDevice->deviceACL->setText(QString("Access: ") + QString(r ? "R" : "-") + QString(w ? "W" : "-"));
myDevice->maxCodeSize->setText(QString("Max code size: ") +QString::number(m_dfu->devices[deviceID].SizeOfCode));
myDevice->fwCRC->setText(QString("FW CRC: ") + QString::number(m_dfu->devices[deviceID].FW_CRC));
myDevice->BLVersion->setText(QString("BL Version: ") + QString::number(m_dfu->devices[deviceID].BL_Version));
myDevice->lblAccess->setText(QString("Flash access: ") + QString(r ? "R" : "-") + QString(w ? "W" : "-"));
myDevice->lblMaxCode->setText(QString("Max code size: ") +QString::number(m_dfu->devices[deviceID].SizeOfCode));
myDevice->lblCRC->setText(QString("Firmware CRC: ") + QString::number(m_dfu->devices[deviceID].FW_CRC));
myDevice->lblBLVer->setText(QString("BL version: ") + QString::number(m_dfu->devices[deviceID].BL_Version));
int size=((OP_DFU::device)m_dfu->devices[deviceID]).SizeOfDesc; int size=((OP_DFU::device)m_dfu->devices[deviceID]).SizeOfDesc;
m_dfu->enterDFU(deviceID); m_dfu->enterDFU(deviceID);
QByteArray desc = m_dfu->DownloadDescriptionAsBA(size); QByteArray desc = m_dfu->DownloadDescriptionAsBA(size);
if (! populateStructuredDescription(desc)) {
if (! populateBoardStructuredDescription(desc)) {
//TODO
// desc was not a structured description // desc was not a structured description
QString str = m_dfu->DownloadDescription(size); QString str = m_dfu->DownloadDescription(size);
myDevice->description->setMaxLength(size); myDevice->lblDescription->setText(QString("Firmware custom description: ")+str.left(str.indexOf(QChar(255))));
myDevice->description->setText(str.left(str.indexOf(QChar(255)))); QPixmap pix = QPixmap(QString(":uploader/images/warning.svg"));
QPixmap pix = QPixmap(QString(":uploader/images/gtk-info.svg")); myDevice->lblCertified->setPixmap(pix);
myDevice->certifiedFW->setPixmap(pix); myDevice->lblCertified->setToolTip(tr("Custom Firmware Build"));
myDevice->certifiedFW->setToolTip(tr("Custom Firmware Build")); myDevice->lblBuildDate->setText("Warning: development firmware");
myDevice->buildDate->setText("Warning: development firmware"); myDevice->lblGitTag->setText("");
myDevice->commitTag->setText(""); myDevice->lblBrdName->setText("");
} }
status("Ready...", STATUSICON_INFO); status("Ready...", STATUSICON_INFO);
} }
/** /**
@ -143,61 +169,75 @@ void deviceWidget::populate()
*/ */
void deviceWidget::freeze() void deviceWidget::freeze()
{ {
myDevice->description->setEnabled(false); myDevice->description->setEnabled(false);
myDevice->updateButton->setEnabled(false); myDevice->updateButton->setEnabled(false);
myDevice->verifyButton->setEnabled(false); myDevice->retrieveButton->setEnabled(false);
myDevice->retrieveButton->setEnabled(false);
} }
/** /**
Populates the widget field with the description in case Populates the widget field with the description in case
it is structured properly it is structured properly
*/ */
bool deviceWidget::populateStructuredDescription(QByteArray desc) bool deviceWidget::populateBoardStructuredDescription(QByteArray desc)
{ {
if (desc.startsWith("OpFw")) { if(UploaderGadgetWidget::descriptionToStructure(desc,&onBoardDescrition))
// This looks like a binary with a description at the end {
/* myDevice->lblGitTag->setText("Git commit tag: "+onBoardDescrition.gitTag);
# 4 bytes: header: "OpFw" myDevice->lblBuildDate->setText(QString("Firmware date: ") + onBoardDescrition.buildDate);
# 4 bytes: GIT commit tag (short version of SHA1) if(onBoardDescrition.description.startsWith("release",Qt::CaseInsensitive))
# 4 bytes: Unix timestamp of compile time {
# 2 bytes: target platform. Should follow same rule as BOARD_TYPE and BOARD_REVISION in board define files. myDevice->lblDescription->setText(QString("Firmware tag: ")+onBoardDescrition.description);
# 26 bytes: commit tag if it is there, otherwise "Unreleased". Zero-padded QPixmap pix = QPixmap(QString(":uploader/images/application-certificate.svg"));
# ---- 40 bytes limit --- myDevice->lblCertified->setPixmap(pix);
# 20 bytes: SHA1 sum of the firmware. myDevice->lblCertified->setToolTip(tr("Official Firmware Build"));
# 40 bytes: free for now.
*/
// Note: the ARM binary is big-endian:
quint32 gitCommitTag = desc.at(7)&0xFF;
for (int i=1;i<4;i++) {
gitCommitTag = gitCommitTag<<8;
gitCommitTag += desc.at(7-i) & 0xFF;
} }
myDevice->commitTag->setText("GIT tag 0x" + QString::number(gitCommitTag,16)); else
quint32 buildDate = desc.at(11)&0xFF; {
for (int i=1;i<4;i++) { myDevice->lblDescription->setText(QString("Firmware tag: ")+onBoardDescrition.description+QString(" (beta or custom build)"));
buildDate = buildDate<<8; QPixmap pix = QPixmap(QString(":uploader/images/warning.svg"));
buildDate += desc.at(11-i) & 0xFF; myDevice->lblCertified->setPixmap(pix);
myDevice->lblCertified->setToolTip(tr("Custom Firmware Build"));
} }
myDevice->buildDate->setText(QString("Build time: ") + QDateTime::fromTime_t(buildDate).toString()); myDevice->lblBrdName->setText(idToBoardName(onBoardDescrition.boardType<<8));
QByteArray targetPlatform = desc.mid(12,2);
// TODO: check platform compatibility
QString dscText = QString(desc.mid(14,26));
myDevice->description->setText(dscText);
QPixmap pix = QPixmap(QString(":uploader/images/application-certificate.svg"));
myDevice->certifiedFW->setPixmap(pix);
myDevice->certifiedFW->setToolTip(tr("Official Firmware Build"));
return true; return true;
} }
return false; return false;
} }
bool deviceWidget::populateLoadedStructuredDescription(QByteArray desc)
{
if(UploaderGadgetWidget::descriptionToStructure(desc,&LoadedDescrition))
{
myDevice->lblGitTagL->setText("Git commit tag: "+LoadedDescrition.gitTag);
myDevice->lblBuildDateL->setText(QString("Firmware date: ") + LoadedDescrition.buildDate);
if(LoadedDescrition.description.startsWith("release",Qt::CaseInsensitive))
{
myDevice->lblDescritpionL->setText(QString("Firmware tag: ")+LoadedDescrition.description);
myDevice->description->setText(LoadedDescrition.description);
QPixmap pix = QPixmap(QString(":uploader/images/application-certificate.svg"));
myDevice->lblCertifiedL->setPixmap(pix);
myDevice->lblCertifiedL->setToolTip(tr("Official Firmware Build"));
}
else
{
myDevice->lblDescritpionL->setText(QString("Firmware tag: ")+LoadedDescrition.description+QString(" (beta or custom build)"));
myDevice->description->setText(LoadedDescrition.description);
QPixmap pix = QPixmap(QString(":uploader/images/warning.svg"));
myDevice->lblCertifiedL->setPixmap(pix);
myDevice->lblCertifiedL->setToolTip(tr("Custom Firmware Build"));
}
myDevice->lblBrdNameL->setText(deviceDescriptorStruct::idToBoardName(LoadedDescrition.boardType<<8));
return true;
}
return false;
}
/** /**
Updates status message for messages coming from DFU Updates status message for messages coming from DFU
*/ */
@ -206,6 +246,16 @@ void deviceWidget::dfuStatus(QString str)
status(str, STATUSICON_RUNNING); status(str, STATUSICON_RUNNING);
} }
void deviceWidget::confirmCB(int value)
{
if(value==Qt::Checked)
{
myDevice->updateButton->setEnabled(true);
}
else
myDevice->updateButton->setEnabled(false);
}
/** /**
Updates status message Updates status message
*/ */
@ -229,11 +279,74 @@ void deviceWidget::status(QString str, StatusIcon ic)
myDevice->statusIcon->setPixmap(px); myDevice->statusIcon->setPixmap(px);
} }
/**
Verifies the firmware CRC void deviceWidget::loadFirmware()
*/
void deviceWidget::verifyFirmware()
{ {
myDevice->verticalGroupBox_loaded->setVisible(false);
myDevice->groupCustom->setVisible(false);
filename = setOpenFileName();
if (filename.isEmpty()) {
status("Empty filename", STATUSICON_FAIL);
return;
}
QFile file(filename);
if (!file.open(QIODevice::ReadOnly)) {
status("Can't open file", STATUSICON_FAIL);
return;
}
loadedFW = file.readAll();
myDevice->youdont->setVisible(false);
myDevice->youdont->setChecked(false);
QByteArray desc = loadedFW.right(100);
QPixmap px;
myDevice->lblCRCL->setText(QString("FW CRC: ") + QString::number(DFUObject::CRCFromQBArray(loadedFW,m_dfu->devices[deviceID].SizeOfCode)));
myDevice->lblFirmwareSizeL->setText(QString("Firmware size: ")+QVariant(loadedFW.length()).toString()+ QString(" bytes"));
if (populateLoadedStructuredDescription(desc))
{
myDevice->youdont->setChecked(true);
myDevice->verticalGroupBox_loaded->setVisible(true);
myDevice->groupCustom->setVisible(false);
if(myDevice->lblCRC->text()==myDevice->lblCRCL->text())
{
myDevice->statusLabel->setText(tr("The loaded firmware maches the firmware on the board. You shouldn't upload it"));
px.load(QString(":/uploader/images/warning.svg"));
}
else if(myDevice->lblDevName->text()!=myDevice->lblBrdNameL->text())
{
myDevice->statusLabel->setText(tr("The loaded firmware is not suited for the HW connected. You shouldn't upload it"));
px.load(QString(":/uploader/images/warning.svg"));
}
else if(QDateTime::fromString(onBoardDescrition.buildDate)>QDateTime::fromString(LoadedDescrition.buildDate))
{
myDevice->statusLabel->setText(tr("The loaded firmware is older then the firmware on the board. You shouldn't upload it"));
px.load(QString(":/uploader/images/warning.svg"));
}
else if(!LoadedDescrition.description.startsWith("release",Qt::CaseInsensitive))
{
myDevice->statusLabel->setText(tr("The loaded firmware is not an oficial OpenPilot release. You should upload it only if you know what you are doing"));
px.load(QString(":/uploader/images/warning.svg"));
}
else
{
myDevice->statusLabel->setText(tr("Everything seems OK. You should upload the loaded firmware by pressing 'upload'"));
px.load(QString(":/uploader/images/gtk-info.svg"));
}
}
else
{
myDevice->statusLabel->setText(tr("The loaded firmware was not packaged with a compatible format. You shouldn't' upload it, if you know what you are doing and still want to upload it confirm it by checking the checkbox bellow"));
px.load(QString(":/uploader/images/warning.svg"));
myDevice->youdont->setChecked(false);
myDevice->youdont->setVisible(true);
myDevice->verticalGroupBox_loaded->setVisible(false);
myDevice->groupCustom->setVisible(true);
}
myDevice->statusIcon->setPixmap(px);
//myDevice->updateButton->setEnabled(true);
} }
@ -253,22 +366,8 @@ void deviceWidget::uploadFirmware()
verify = true; verify = true;
*/ */
QString filename = setOpenFileName(); QByteArray desc = loadedFW.right(100);
if (desc.startsWith("OpFw")) {
if (filename.isEmpty()) {
status("Empty filename", STATUSICON_FAIL);
return;
}
QFile file(filename);
if (!file.open(QIODevice::ReadOnly)) {
status("Can't open file", STATUSICON_FAIL);
return;
}
QByteArray arr = file.readAll();
QByteArray desc = arr.right(100);
if (populateStructuredDescription(desc)) {
descriptionArray = desc; descriptionArray = desc;
// Now do sanity checking: // Now do sanity checking:
// - Check whether board type matches firmware: // - Check whether board type matches firmware:
@ -280,7 +379,7 @@ void deviceWidget::uploadFirmware()
} }
// Check the firmware embedded in the file: // Check the firmware embedded in the file:
QByteArray firmwareHash = desc.mid(40,20); QByteArray firmwareHash = desc.mid(40,20);
QByteArray fileHash = QCryptographicHash::hash(arr.left(arr.length()-100), QCryptographicHash::Sha1); QByteArray fileHash = QCryptographicHash::hash(loadedFW.left(loadedFW.length()-100), QCryptographicHash::Sha1);
if (firmwareHash != fileHash) { if (firmwareHash != fileHash) {
status("Error: firmware file corrupt", STATUSICON_FAIL); status("Error: firmware file corrupt", STATUSICON_FAIL);
return; return;
@ -370,27 +469,27 @@ void deviceWidget::uploadFinished(OP_DFU::Status retstatus)
status(QString("Upload failed with code: ") + m_dfu->StatusToString(retstatus).toLatin1().data(), STATUSICON_FAIL); status(QString("Upload failed with code: ") + m_dfu->StatusToString(retstatus).toLatin1().data(), STATUSICON_FAIL);
return; return;
} else } else
if (!descriptionArray.isEmpty()) { if (!descriptionArray.isEmpty()) {
// We have a structured array to save // We have a structured array to save
status(QString("Updating description"), STATUSICON_RUNNING); status(QString("Updating description"), STATUSICON_RUNNING);
repaint(); // Make sure the text above shows right away repaint(); // Make sure the text above shows right away
retstatus = m_dfu->UploadDescription(descriptionArray); retstatus = m_dfu->UploadDescription(descriptionArray);
if( retstatus != OP_DFU::Last_operation_Success) { if( retstatus != OP_DFU::Last_operation_Success) {
status(QString("Upload failed with code: ") + m_dfu->StatusToString(retstatus).toLatin1().data(), STATUSICON_FAIL); status(QString("Upload failed with code: ") + m_dfu->StatusToString(retstatus).toLatin1().data(), STATUSICON_FAIL);
return; return;
}
} else if (!myDevice->description->text().isEmpty()) {
// Fallback: we save the description field:
status(QString("Updating description"), STATUSICON_RUNNING);
repaint(); // Make sure the text above shows right away
retstatus = m_dfu->UploadDescription(myDevice->description->text());
if( retstatus != OP_DFU::Last_operation_Success) {
status(QString("Upload failed with code: ") + m_dfu->StatusToString(retstatus).toLatin1().data(), STATUSICON_FAIL);
return;
}
} }
populate();
} else if (!myDevice->description->text().isEmpty()) {
// Fallback: we save the description field:
status(QString("Updating description"), STATUSICON_RUNNING);
repaint(); // Make sure the text above shows right away
retstatus = m_dfu->UploadDescription(myDevice->description->text());
if( retstatus != OP_DFU::Last_operation_Success) {
status(QString("Upload failed with code: ") + m_dfu->StatusToString(retstatus).toLatin1().data(), STATUSICON_FAIL);
return;
}
}
status("Upload successful", STATUSICON_OK); status("Upload successful", STATUSICON_OK);
} }

View File

@ -38,9 +38,9 @@
#include <QtSvg/QGraphicsSvgItem> #include <QtSvg/QGraphicsSvgItem>
#include <QtSvg/QSvgRenderer> #include <QtSvg/QSvgRenderer>
#include <QCryptographicHash> #include <QCryptographicHash>
#include "uavobjectutilmanager.h"
#include "devicedescriptorstruct.h"
using namespace OP_DFU; using namespace OP_DFU;
class deviceWidget : public QWidget class deviceWidget : public QWidget
{ {
Q_OBJECT Q_OBJECT
@ -54,6 +54,10 @@ public:
QString setOpenFileName(); QString setOpenFileName();
QString setSaveFileName(); QString setSaveFileName();
private: private:
deviceDescriptorStruct onBoardDescrition;
deviceDescriptorStruct LoadedDescrition;
QByteArray loadedFW;
QString idToBoardName(int id);
Ui_deviceWidget *myDevice; Ui_deviceWidget *myDevice;
int deviceID; int deviceID;
DFUObject *m_dfu; DFUObject *m_dfu;
@ -62,19 +66,20 @@ private:
QGraphicsSvgItem *devicePic; QGraphicsSvgItem *devicePic;
QByteArray descriptionArray; QByteArray descriptionArray;
void status(QString str, StatusIcon ic); void status(QString str, StatusIcon ic);
bool populateStructuredDescription(QByteArray arr); bool populateBoardStructuredDescription(QByteArray arr);
bool populateLoadedStructuredDescription(QByteArray arr);
signals: signals:
public slots: public slots:
void verifyFirmware();
void uploadFirmware(); void uploadFirmware();
void loadFirmware();
void downloadFirmware(); void downloadFirmware();
void setProgress(int); void setProgress(int);
void downloadFinished(); void downloadFinished();
void uploadFinished(OP_DFU::Status); void uploadFinished(OP_DFU::Status);
void dfuStatus(QString); void dfuStatus(QString);
void confirmCB(int);
protected: protected:
void showEvent(QShowEvent *event); void showEvent(QShowEvent *event);

View File

@ -7,7 +7,7 @@
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>516</width> <width>516</width>
<height>253</height> <height>582</height>
</rect> </rect>
</property> </property>
<property name="windowTitle"> <property name="windowTitle">
@ -15,164 +15,310 @@
</property> </property>
<layout class="QVBoxLayout" name="verticalLayout"> <layout class="QVBoxLayout" name="verticalLayout">
<item> <item>
<layout class="QGridLayout" name="gridLayout"> <widget class="QGroupBox" name="verticalGroupBox_4">
<item row="2" column="0" colspan="3"> <property name="title">
<widget class="QLineEdit" name="description"> <string>Device Information</string>
<property name="readOnly"> </property>
<bool>true</bool> <layout class="QVBoxLayout" name="verticalLayout_7">
</property> <item>
</widget> <layout class="QHBoxLayout" name="horizontalLayout_6">
</item> <item>
<item row="4" column="0"> <widget class="QGraphicsView" name="gVDevice">
<widget class="QLabel" name="deviceID"> <property name="maximumSize">
<property name="text"> <size>
<string>DeviceID</string> <width>160</width>
</property> <height>160</height>
</widget> </size>
</item> </property>
<item row="8" column="0" colspan="2"> <property name="styleSheet">
<widget class="QProgressBar" name="progressBar"> <string notr="true">background: transparent</string>
<property name="value"> </property>
<number>0</number> </widget>
</property> </item>
</widget> <item>
</item> <layout class="QVBoxLayout" name="verticalLayout_4">
<item row="4" column="1"> <item>
<widget class="QLabel" name="deviceACL"> <widget class="QLabel" name="lblDevName">
<property name="text"> <property name="text">
<string>ReadWrite</string> <string>lblDevName</string>
</property> </property>
</widget> </widget>
</item> </item>
<item row="3" column="2" rowspan="3"> <item>
<widget class="QGraphicsView" name="devicePicture"> <widget class="QLabel" name="lbldevID">
<property name="maximumSize"> <property name="text">
<size> <string>DeviceID</string>
<width>160</width> </property>
<height>160</height> </widget>
</size> </item>
</property> <item>
<property name="styleSheet"> <widget class="QLabel" name="lblHWRev">
<string notr="true">background: transparent</string> <property name="text">
</property> <string>lblHWRev</string>
<property name="frameShape"> </property>
<enum>QFrame::NoFrame</enum> </widget>
</property> </item>
</widget> <item>
</item> <widget class="QLabel" name="lblAccess">
<item row="6" column="2"> <property name="text">
<widget class="QPushButton" name="verifyButton"> <string>RW</string>
<property name="enabled"> </property>
<bool>false</bool> </widget>
</property> </item>
<property name="text"> <item>
<string>Verify...</string> <widget class="QLabel" name="lblBLVer">
</property> <property name="text">
</widget> <string>BL Version</string>
</item> </property>
<item row="7" column="2"> </widget>
<widget class="QPushButton" name="updateButton"> </item>
<property name="toolTip"> <item>
<string>Update the firmware on this board.</string> <widget class="QLabel" name="lblMaxCode">
</property> <property name="text">
<property name="text"> <string>MaxCodeSize</string>
<string>Update...</string> </property>
</property> </widget>
</widget> </item>
</item> </layout>
<item row="8" column="2"> </item>
<widget class="QPushButton" name="retrieveButton"> <item>
<property name="toolTip"> <layout class="QVBoxLayout" name="verticalLayout_6">
<string>Download the current board firmware to your computer</string> <item>
</property> <widget class="QPushButton" name="pbLoad">
<property name="text"> <property name="toolTip">
<string>Retrieve...</string> <string>Loads the firmware</string>
</property> </property>
</widget> <property name="text">
</item> <string>Open</string>
<item row="5" column="1"> </property>
<widget class="QLabel" name="BLVersion"> </widget>
<property name="text"> </item>
<string>BootLoaderVersion</string> <item>
</property> <widget class="QPushButton" name="updateButton">
</widget> <property name="enabled">
</item> <bool>false</bool>
<item row="5" column="0"> </property>
<widget class="QLabel" name="fwCRC"> <property name="toolTip">
<property name="text"> <string>Update the firmware on this board.</string>
<string>fwCRC</string> </property>
</property> <property name="text">
</widget> <string>Flash</string>
</item> </property>
<item row="6" column="1"> </widget>
<widget class="QLabel" name="maxCodeSize"> </item>
<property name="text"> <item>
<string>MaxCodeSize</string> <widget class="QPushButton" name="retrieveButton">
</property> <property name="toolTip">
</widget> <string>Download the current board firmware to your computer</string>
</item> </property>
<item row="7" column="0" colspan="2"> <property name="text">
<layout class="QHBoxLayout" name="horizontalLayout"> <string>Retrieve...</string>
<item> </property>
<widget class="QLabel" name="statusIcon"> </widget>
<property name="text"> </item>
<string>ic</string> </layout>
</property> </item>
</widget> </layout>
</item> </item>
<item> <item>
<widget class="QLabel" name="statusLabel"> <widget class="QProgressBar" name="progressBar">
<property name="sizePolicy"> <property name="value">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred"> <number>0</number>
<horstretch>0</horstretch> </property>
<verstretch>0</verstretch> </widget>
</sizepolicy> </item>
</property> <item>
<property name="font"> <layout class="QHBoxLayout" name="horizontalLayout">
<font> <item>
<weight>75</weight> <widget class="QLabel" name="statusIcon">
<bold>true</bold> <property name="text">
</font> <string>ic</string>
</property> </property>
<property name="text"> </widget>
<string>Status</string> </item>
</property> <item>
</widget> <widget class="QLabel" name="statusLabel">
</item> <property name="sizePolicy">
</layout> <sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
</item> <horstretch>0</horstretch>
<item row="6" column="0"> <verstretch>0</verstretch>
<widget class="QLabel" name="commitTag"> </sizepolicy>
<property name="text"> </property>
<string>Commit tag</string> <property name="font">
</property> <font>
</widget> <weight>75</weight>
</item> <bold>true</bold>
<item row="3" column="0" colspan="2"> </font>
<layout class="QHBoxLayout" name="horizontalLayout_2"> </property>
<item> <property name="text">
<widget class="QLabel" name="certifiedFW"> <string>Status</string>
<property name="text"> </property>
<string>certified</string> <property name="wordWrap">
</property> <bool>true</bool>
</widget> </property>
</item> </widget>
<item> </item>
<widget class="QLabel" name="buildDate"> </layout>
<property name="sizePolicy"> </item>
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred"> <item>
<horstretch>0</horstretch> <widget class="QCheckBox" name="youdont">
<verstretch>0</verstretch> <property name="text">
</sizepolicy> <string>I know what I'm doing</string>
</property> </property>
<property name="text"> <property name="checked">
<string>buildDate</string> <bool>true</bool>
</property> </property>
</widget> </widget>
</item> </item>
</layout> </layout>
</item> </widget>
</layout> </item>
<item>
<widget class="QGroupBox" name="verticalGroupBox_3">
<property name="title">
<string>Firmware currently on the device</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_5">
<item>
<layout class="QHBoxLayout" name="horizontalLayout_5">
<item>
<layout class="QVBoxLayout" name="verticalLayout_8">
<item>
<widget class="QLabel" name="lblBrdName">
<property name="text">
<string>lblBrdName</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="lblDescription">
<property name="text">
<string>lblDescription</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="lblBuildDate">
<property name="text">
<string>lblBuildDate</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="lblGitTag">
<property name="text">
<string>lblGitTag</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="lblCRC">
<property name="text">
<string>lblCRC</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="QLabel" name="lblCertified">
<property name="text">
<string>lblCertified</string>
</property>
<property name="scaledContents">
<bool>false</bool>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="verticalGroupBox_loaded">
<property name="enabled">
<bool>true</bool>
</property>
<property name="title">
<string>Loaded Firmware</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<layout class="QVBoxLayout" name="verticalLayout_3">
<item>
<widget class="QLabel" name="lblBrdNameL">
<property name="text">
<string>lblBrdName</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="lblDescritpionL">
<property name="text">
<string>lblDescritpionL</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="lblBuildDateL">
<property name="text">
<string>lblBuildDate</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="lblGitTagL">
<property name="text">
<string>lblGitTag</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="lblCRCL">
<property name="text">
<string>lblCRC</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="lblFirmwareSizeL">
<property name="text">
<string>lblFirmwareSizeL</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="QLabel" name="lblCertifiedL">
<property name="text">
<string>lblCertifiedL</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="groupCustom">
<layout class="QHBoxLayout" name="horizontalLayout_3">
<item>
<widget class="QLabel" name="lblX">
<property name="text">
<string>Custom description:</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="description"/>
</item>
</layout>
</widget>
</item> </item>
</layout> </layout>
</widget> </widget>

View File

@ -0,0 +1,102 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Generator: Adobe Illustrator 15.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
version="1.1"
id="Layer_1"
x="0px"
y="0px"
width="51.537998"
height="46.021885"
viewBox="0 0 51.538001 46.021886"
enable-background="new 0 0 514.475 473.977"
xml:space="preserve"
inkscape:version="0.48.1 "
sodipodi:docname="warning_s.svg"><metadata
id="metadata3095"><rdf:RDF><cc:Work
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title /></cc:Work></rdf:RDF></metadata><defs
id="defs3093" /><sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="1280"
inkscape:window-height="738"
id="namedview3091"
showgrid="false"
inkscape:zoom="1.0949899"
inkscape:cx="249.10624"
inkscape:cy="125.11088"
inkscape:window-x="-8"
inkscape:window-y="-8"
inkscape:window-maximized="1"
inkscape:current-layer="Layer_1"
fit-margin-top="0"
fit-margin-left="0"
fit-margin-right="0"
fit-margin-bottom="0" />
<radialGradient
id="SVGID_1_"
cx="255.45261"
cy="231.6748"
r="206.35049"
gradientTransform="matrix(0.1182761,0,0,0.12913623,-4.4457028,-6.9088686)"
gradientUnits="userSpaceOnUse">
<stop
offset="0"
style="stop-color:#FFDE17"
id="stop3074" />
<stop
offset="1"
style="stop-color:#ABA01F"
id="stop3076" />
</radialGradient>
<path
stroke-miterlimit="10"
d="M 1.2974519,42.730481 C -1.4443604,39.150401 21.620352,1.0717714 25.887967,1.0717714 c 4.269682,0 27.060213,38.8621096 24.35608,41.6587096 -3.013913,3.11312 -46.8075615,2.80177 -48.9465951,0 z"
id="path3078"
style="fill:url(#SVGID_1_);stroke:#000000;stroke-width:2.14355946;stroke-miterlimit:10"
inkscape:connector-curvature="0" />
<path
d="m 22.987071,36.405661 c 0,-1.55651 1.465096,-2.59423 3.118544,-2.59423 1.674394,0 3.013911,1.03772 3.013911,2.59423 0,1.55658 -1.255794,2.59427 -3.118542,2.59427 -1.674391,0 -3.034841,-1.03769 -3.034841,-2.59427 z m 1.465096,-5.24042 c -0.627898,-0.77824 -1.67439,-20.36495 -0.627898,-21.3507596 0.837188,-0.77831 3.872026,-0.77831 4.604571,0 0.8372,0.7782796 -0.209304,20.8059796 -0.627897,21.3507596 -0.418602,0.51889 -2.762741,0.51889 -3.265057,0 z"
id="path3080"
inkscape:connector-curvature="0" />
<linearGradient
id="SVGID_2_"
gradientUnits="userSpaceOnUse"
x1="256.45209"
y1="304.9277"
x2="256.45209"
y2="48.449699"
gradientTransform="matrix(0.11827613,0,0,0.10761355,-4.4457031,-1.9220086)">
<stop
offset="0"
style="stop-color:#FFFFFF"
id="stop3083" />
<stop
offset="0.0896"
style="stop-color:#FFFFFF;stop-opacity:0.9104"
id="stop3085" />
<stop
offset="1"
style="stop-color:#FFFFFF;stop-opacity:0"
id="stop3087" />
</linearGradient>
<path
d="M 10.709612,23.014111 C 16.695555,12.974321 23.623336,3.2976914 25.779115,3.2976914 c 2.197635,0 9.313793,10.2991996 15.320665,20.7021496 5.651063,9.75447 -36.2902985,8.92436 -30.396443,-1.03772 z"
id="path3089"
style="opacity:0.31999996;fill:url(#SVGID_2_)"
inkscape:connector-curvature="0" />
</svg>

After

Width:  |  Height:  |  Size: 3.6 KiB

View File

@ -718,7 +718,7 @@ OP_DFU::Status DFUObject::UploadFirmwareT(const QString &sfile, const bool &veri
return OP_DFU::abort;; return OP_DFU::abort;;
} }
quint32 crc=CRCFromQBArray(arr,devices[device].SizeOfCode); quint32 crc=DFUObject::CRCFromQBArray(arr,devices[device].SizeOfCode);
if (debug) if (debug)
qDebug() << "NEW FIRMWARE CRC=" << crc; qDebug() << "NEW FIRMWARE CRC=" << crc;
@ -817,7 +817,7 @@ OP_DFU::Status DFUObject::CompareFirmware(const QString &sfile, const CompareTyp
} }
if(type==OP_DFU::crccompare) if(type==OP_DFU::crccompare)
{ {
quint32 crc=CRCFromQBArray(arr,devices[device].SizeOfCode); quint32 crc=DFUObject::CRCFromQBArray(arr,devices[device].SizeOfCode);
if(crc==devices[device].FW_CRC) if(crc==devices[device].FW_CRC)
{ {
cout<<"Compare Successfull CRC MATCH!\n"; cout<<"Compare Successfull CRC MATCH!\n";
@ -971,7 +971,7 @@ quint32 DFUObject::CRCFromQBArray(QByteArray array, quint32 Size)
aux+=(char)array[x*4+0]&0xFF; aux+=(char)array[x*4+0]&0xFF;
t[x]=aux; t[x]=aux;
} }
return CRC32WideFast(0xFFFFFFFF,Size/4,(quint32*)t); return DFUObject::CRC32WideFast(0xFFFFFFFF,Size/4,(quint32*)t);
} }

View File

@ -108,7 +108,7 @@ namespace OP_DFU {
Q_OBJECT; Q_OBJECT;
public: public:
static quint32 CRCFromQBArray(QByteArray array, quint32 Size);
//DFUObject(bool debug); //DFUObject(bool debug);
DFUObject(bool debug,bool use_serial,QString port); DFUObject(bool debug,bool use_serial,QString port);
@ -152,7 +152,7 @@ namespace OP_DFU {
// Helper functions: // Helper functions:
QString StatusToString(OP_DFU::Status const & status); QString StatusToString(OP_DFU::Status const & status);
quint32 CRC32WideFast(quint32 Crc, quint32 Size, quint32 *Buffer); static quint32 CRC32WideFast(quint32 Crc, quint32 Size, quint32 *Buffer);
@ -179,7 +179,7 @@ namespace OP_DFU {
// USB Bootloader: // USB Bootloader:
pjrc_rawhid hidHandle; pjrc_rawhid hidHandle;
int setStartBit(int command){ return command|0x20; } int setStartBit(int command){ return command|0x20; }
quint32 CRCFromQBArray(QByteArray array, quint32 Size);
void CopyWords(char * source, char* destination, int count); void CopyWords(char * source, char* destination, int count);
void printProgBar( int const & percent,QString const& label); void printProgBar( int const & percent,QString const& label);
bool StartUpload(qint32 const &numberOfBytes, TransferTypes const & type,quint32 crc); bool StartUpload(qint32 const &numberOfBytes, TransferTypes const & type,quint32 crc);

View File

@ -25,7 +25,8 @@
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/ */
#include "runningdevicewidget.h" #include "runningdevicewidget.h"
#include "devicedescriptorstruct.h"
#include "uploadergadgetwidget.h"
runningDeviceWidget::runningDeviceWidget(QWidget *parent) : runningDeviceWidget::runningDeviceWidget(QWidget *parent) :
QWidget(parent) QWidget(parent)
{ {
@ -68,8 +69,11 @@ void runningDeviceWidget::populate()
UAVObjectUtilManager* utilMngr = pm->getObject<UAVObjectUtilManager>(); UAVObjectUtilManager* utilMngr = pm->getObject<UAVObjectUtilManager>();
int id = utilMngr->getBoardModel(); int id = utilMngr->getBoardModel();
myDevice->deviceID->setText(QString("Device ID: ") + QString::number(id, 16)); myDevice->lblDeviceID->setText(QString("Device ID: ") + QString::number(id, 16));
myDevice->lblBoardName->setText(deviceDescriptorStruct::idToBoardName(id));
myDevice->lblHWRev->setText(QString(tr("HW Revision: "))+QString::number(id & 0x0011, 16));
qDebug()<<"CRC"<<utilMngr->getFirmwareCRC();
myDevice->lblCRC->setText(QString(tr("Firmware CRC: "))+QVariant(utilMngr->getFirmwareCRC()).toString());
// DeviceID tells us what sort of HW we have detected: // DeviceID tells us what sort of HW we have detected:
// display a nice icon: // display a nice icon:
myDevice->devicePicture->scene()->clear(); myDevice->devicePicture->scene()->clear();
@ -100,13 +104,41 @@ void runningDeviceWidget::populate()
myDevice->devicePicture->fitInView(devicePic,Qt::KeepAspectRatio); myDevice->devicePicture->fitInView(devicePic,Qt::KeepAspectRatio);
QString serial = utilMngr->getBoardCPUSerial().toHex(); QString serial = utilMngr->getBoardCPUSerial().toHex();
myDevice->cpuSerial->setText(serial); myDevice->lblCPU->setText(QString("CPU serial number: "+serial));
QString description = utilMngr->getBoardDescription(); QByteArray description = utilMngr->getBoardDescription();
myDevice->description->setText(description); deviceDescriptorStruct devDesc;
if(UploaderGadgetWidget::descriptionToStructure(description,&devDesc))
{
if(devDesc.description.startsWith("release",Qt::CaseInsensitive))
{
myDevice->lblFWTag->setText(QString("Firmware tag: ")+devDesc.description);
QPixmap pix = QPixmap(QString(":uploader/images/application-certificate.svg"));
myDevice->lblCertified->setPixmap(pix);
myDevice->lblCertified->setToolTip(tr("Official Firmware Build"));
}
else
{
myDevice->lblFWTag->setText(QString("Firmware tag: ")+devDesc.description+QString(" (beta or custom build)"));
QPixmap pix = QPixmap(QString(":uploader/images/warning.svg"));
myDevice->lblCertified->setPixmap(pix);
myDevice->lblCertified->setToolTip(tr("Custom Firmware Build"));
}
myDevice->lblGitCommitTag->setText("Git commit tag: "+devDesc.gitTag);
myDevice->lblFWDate->setText(QString("Firmware date: ") + devDesc.buildDate);
}
else
{
myDevice->lblFWTag->setText(QString("Firmware tag: ")+QString(description).left(QString(description).indexOf(QChar(255))));
myDevice->lblGitCommitTag->setText("Git commit tag: Unknown");
myDevice->lblFWDate->setText(QString("Firmware date: Unknown"));
QPixmap pix = QPixmap(QString(":uploader/images/warning.svg"));
myDevice->lblCertified->setPixmap(pix);
myDevice->lblCertified->setToolTip(tr("Custom Firmware Build"));
}
status("Ready...", STATUSICON_INFO); status("Ready...", STATUSICON_INFO);
} }

View File

@ -29,7 +29,7 @@
#define RUNNINGDEVICEWIDGET_H #define RUNNINGDEVICEWIDGET_H
#include "ui_runningdevicewidget.h" #include "ui_runningdevicewidget.h"
#include "uploadergadgetwidget.h"
#include <QWidget> #include <QWidget>
#include <QErrorMessage> #include <QErrorMessage>
#include <QtSvg/QGraphicsSvgItem> #include <QtSvg/QGraphicsSvgItem>

View File

@ -14,9 +14,114 @@
<string>Form</string> <string>Form</string>
</property> </property>
<layout class="QVBoxLayout" name="verticalLayout"> <layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QGroupBox" name="horizontalGroupBox">
<property name="title">
<string>Device Information</string>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QGraphicsView" name="devicePicture">
<property name="maximumSize">
<size>
<width>160</width>
<height>160</height>
</size>
</property>
<property name="styleSheet">
<string notr="true">background: transparent</string>
</property>
<property name="frameShape">
<enum>QFrame::NoFrame</enum>
</property>
</widget>
</item>
<item>
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<widget class="QLabel" name="lblBoardName">
<property name="text">
<string>TextLabel</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="lblDeviceID">
<property name="text">
<string>TextLabel</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="lblHWRev">
<property name="text">
<string>TextLabel</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="lblCPU">
<property name="text">
<string>TextLabel</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="horizontalGroupBox">
<property name="title">
<string>Firmware Information</string>
</property>
<layout class="QHBoxLayout" name="_2">
<item>
<layout class="QVBoxLayout" name="verticalLayout_3">
<item>
<widget class="QLabel" name="lblFWTag">
<property name="text">
<string>TextLabel</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="lblFWDate">
<property name="text">
<string>TextLabel</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="lblGitCommitTag">
<property name="text">
<string>TextLabel</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="lblCRC">
<property name="text">
<string>TextLabel</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="QLabel" name="lblCertified">
<property name="text">
<string>TextLabel</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item> <item>
<layout class="QGridLayout" name="gridLayout"> <layout class="QGridLayout" name="gridLayout">
<item row="6" column="0" colspan="2"> <item row="3" column="0" colspan="2">
<layout class="QHBoxLayout" name="horizontalLayout"> <layout class="QHBoxLayout" name="horizontalLayout">
<item> <item>
<widget class="QLabel" name="statusIcon"> <widget class="QLabel" name="statusIcon">
@ -46,50 +151,6 @@
</item> </item>
</layout> </layout>
</item> </item>
<item row="5" column="0">
<widget class="QLabel" name="deviceID">
<property name="text">
<string>DeviceID</string>
</property>
</widget>
</item>
<item row="4" column="0">
<widget class="QLabel" name="cpuSerialLabel">
<property name="text">
<string>CPU Serial:</string>
</property>
</widget>
</item>
<item row="4" column="2" rowspan="2">
<widget class="QGraphicsView" name="devicePicture">
<property name="maximumSize">
<size>
<width>160</width>
<height>160</height>
</size>
</property>
<property name="styleSheet">
<string notr="true">background: transparent</string>
</property>
<property name="frameShape">
<enum>QFrame::NoFrame</enum>
</property>
</widget>
</item>
<item row="2" column="0" colspan="3">
<widget class="QLineEdit" name="description">
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
</item>
<item row="4" column="1">
<widget class="QLineEdit" name="cpuSerial">
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
</item>
</layout> </layout>
</item> </item>
</layout> </layout>

View File

@ -22,7 +22,8 @@ HEADERS += uploadergadget.h \
SSP/qssp.h \ SSP/qssp.h \
SSP/qsspt.h \ SSP/qsspt.h \
SSP/common.h \ SSP/common.h \
runningdevicewidget.h runningdevicewidget.h \
devicedescriptorstruct.h
SOURCES += uploadergadget.cpp \ SOURCES += uploadergadget.cpp \
uploadergadgetconfiguration.cpp \ uploadergadgetconfiguration.cpp \
uploadergadgetfactory.cpp \ uploadergadgetfactory.cpp \
@ -35,7 +36,8 @@ SOURCES += uploadergadget.cpp \
SSP/port.cpp \ SSP/port.cpp \
SSP/qssp.cpp \ SSP/qssp.cpp \
SSP/qsspt.cpp \ SSP/qsspt.cpp \
runningdevicewidget.cpp runningdevicewidget.cpp \
devicedescriptorstruct.cpp
OTHER_FILES += Uploader.pluginspec OTHER_FILES += Uploader.pluginspec
FORMS += \ FORMS += \

View File

@ -10,5 +10,6 @@
<file>images/deviceID-0201.svg</file> <file>images/deviceID-0201.svg</file>
<file>images/deviceID-0101.svg</file> <file>images/deviceID-0101.svg</file>
<file>images/application-certificate.svg</file> <file>images/application-certificate.svg</file>
<file>images/warning.svg</file>
</qresource> </qresource>
</RCC> </RCC>

View File

@ -27,7 +27,44 @@
#include "uploadergadgetwidget.h" #include "uploadergadgetwidget.h"
#define DFU_DEBUG true #define DFU_DEBUG true
bool UploaderGadgetWidget::descriptionToStructure(QByteArray desc,deviceDescriptorStruct * struc)
{
if (desc.startsWith("OpFw")) {
// This looks like a binary with a description at the end
/*
# 4 bytes: header: "OpFw"
# 4 bytes: GIT commit tag (short version of SHA1)
# 4 bytes: Unix timestamp of compile time
# 2 bytes: target platform. Should follow same rule as BOARD_TYPE and BOARD_REVISION in board define files.
# 26 bytes: commit tag if it is there, otherwise "Unreleased". Zero-padded
# ---- 40 bytes limit ---
# 20 bytes: SHA1 sum of the firmware.
# 40 bytes: free for now.
*/
// Note: the ARM binary is big-endian:
quint32 gitCommitTag = desc.at(7)&0xFF;
for (int i=1;i<4;i++) {
gitCommitTag = gitCommitTag<<8;
gitCommitTag += desc.at(7-i) & 0xFF;
}
struc->gitTag=QString::number(gitCommitTag,16);
quint32 buildDate = desc.at(11)&0xFF;
for (int i=1;i<4;i++) {
buildDate = buildDate<<8;
buildDate += desc.at(11-i) & 0xFF;
}
struc->buildDate= QDateTime::fromTime_t(buildDate).toLocalTime().toString("yyyy MMMM dd HH:mm:ss");
QByteArray targetPlatform = desc.mid(12,2);
// TODO: check platform compatibility
QString dscText = QString(desc.mid(14,26));
struc->boardType=(int)targetPlatform.at(0);
struc->boardRevision=(int)targetPlatform.at(1);
struc->description=dscText;
return true;
}
return false;
}
UploaderGadgetWidget::UploaderGadgetWidget(QWidget *parent) : QWidget(parent) UploaderGadgetWidget::UploaderGadgetWidget(QWidget *parent) : QWidget(parent)
{ {
m_config = new Ui_UploaderWidget(); m_config = new Ui_UploaderWidget();

View File

@ -52,20 +52,23 @@
#include <QThread> #include <QThread>
#include <QMessageBox> #include <QMessageBox>
#include <QTimer> #include <QTimer>
#include "devicedescriptorstruct.h"
#include <QProgressDialog> #include <QProgressDialog>
using namespace OP_DFU; using namespace OP_DFU;
class UploaderGadgetWidget : public QWidget class UploaderGadgetWidget : public QWidget
{ {
Q_OBJECT Q_OBJECT
public: public:
UploaderGadgetWidget(QWidget *parent = 0); UploaderGadgetWidget(QWidget *parent = 0);
~UploaderGadgetWidget(); ~UploaderGadgetWidget();
typedef enum { IAP_STATE_READY, IAP_STATE_STEP_1, IAP_STATE_STEP_2, IAP_STEP_RESET, IAP_STATE_BOOTLOADER} IAPStep; typedef enum { IAP_STATE_READY, IAP_STATE_STEP_1, IAP_STATE_STEP_2, IAP_STEP_RESET, IAP_STATE_BOOTLOADER} IAPStep;
void log(QString str); void log(QString str);
static bool descriptionToStructure(QByteArray desc,deviceDescriptorStruct * struc);
public slots: public slots:
void onAutopilotConnect(); void onAutopilotConnect();

View File

@ -33,16 +33,15 @@ CLEAN_GROUND := YES
CLEAN_FLIGHT := YES CLEAN_FLIGHT := YES
endif endif
# Set up targets # Set up targets (PPM target seems to be broken at the moment)
FW_STEMS_COMMON := ahrs pipxtreme FW_TARGETS_COMMON := $(addprefix fw_, ahrs pipxtreme)
FW_STEMS_INPUT := coptercontrol openpilot FW_TARGETS_PWM := $(addprefix fw_, coptercontrol openpilot)
FW_STEMS_TOOLS := coptercontrol FW_TARGETS_DSM2 := $(addprefix fw_, coptercontrol openpilot)
FW_STEMS_ALL := $(FW_STEMS_COMMON) $(FW_STEMS_INPUT) FW_TARGETS_SBUS := $(addprefix fw_, coptercontrol)
FW_TARGETS_COMMON := $(addprefix fw_, $(FW_STEMS_COMMON)) FW_TARGETS_PPM := $(addprefix fw_, openpilot)
FW_TARGETS_INPUT := $(addprefix fw_, $(FW_STEMS_INPUT)) FW_TARGETS_TOOLS := $(addprefix fw_, coptercontrol)
FW_TARGETS_TOOLS := $(addprefix fw_, $(FW_STEMS_TOOLS)) BL_TARGETS := $(addprefix bl_, coptercontrol openpilot ahrs pipxtreme)
BL_TARGETS := $(addprefix bl_, $(FW_STEMS_ALL)) BU_TARGETS := $(addprefix bu_, coptercontrol openpilot ahrs pipxtreme)
BU_TARGETS := $(addprefix bu_, $(FW_STEMS_ALL))
help: help:
@echo @echo
@ -102,9 +101,10 @@ endef
# Firmware for different input drivers # Firmware for different input drivers
$(eval $(call INSTALL_TEMPLATE,fw_common,uavobjects,$(FW_DIR),,-$(PACKAGE_LBL),,,$(FW_TARGETS_COMMON),install)) $(eval $(call INSTALL_TEMPLATE,fw_common,uavobjects,$(FW_DIR),,-$(PACKAGE_LBL),,,$(FW_TARGETS_COMMON),install))
$(eval $(call INSTALL_TEMPLATE,fw_pwm,uavobjects,$(FW_DIR),,-pwm-$(PACKAGE_LBL),,clean,$(FW_TARGETS_INPUT),install)) $(eval $(call INSTALL_TEMPLATE,fw_pwm,uavobjects,$(FW_DIR),,-pwm-$(PACKAGE_LBL),,clean,$(FW_TARGETS_PWM),install))
$(eval $(call INSTALL_TEMPLATE,fw_spektrum,uavobjects,$(FW_DIR),,-dsm2sat-$(PACKAGE_LBL),USE_SPEKTRUM=YES,clean,$(FW_TARGETS_INPUT),install)) $(eval $(call INSTALL_TEMPLATE,fw_dsm2,uavobjects,$(FW_DIR),,-dsm2sat-$(PACKAGE_LBL),USE_SPEKTRUM=YES,clean,$(FW_TARGETS_DSM2),install))
$(eval $(call INSTALL_TEMPLATE,fw_ppm,uavobjects,$(FW_DIR),,-ppm-$(PACKAGE_LBL),USE_PPM=YES,clean,$(FW_TARGETS_INPUT),install)) $(eval $(call INSTALL_TEMPLATE,fw_sbus,uavobjects,$(FW_DIR),,-sbus-$(PACKAGE_LBL),USE_SBUS=YES USE_TELEMETRY=3,clean,$(FW_TARGETS_SBUS),install))
$(eval $(call INSTALL_TEMPLATE,fw_ppm,uavobjects,$(FW_DIR),,-ppm-$(PACKAGE_LBL),USE_PPM=YES,clean,$(FW_TARGETS_PPM),install))
# Bootloaders (change 'install' to 'bin' if you don't want to install bootloaders) # Bootloaders (change 'install' to 'bin' if you don't want to install bootloaders)
$(eval $(call INSTALL_TEMPLATE,all_bl,uavobjects,$(BL_DIR),,-$(PACKAGE_LBL),,,$(BL_TARGETS),install)) $(eval $(call INSTALL_TEMPLATE,all_bl,uavobjects,$(BL_DIR),,-$(PACKAGE_LBL),,,$(BL_TARGETS),install))
@ -119,15 +119,17 @@ $(eval $(call INSTALL_TEMPLATE,fw_tools,uavobjects,$(FE_DIR),,-flash-erase-$(PAC
# They are bit complicated to support parallel (-j) builds and to create # They are bit complicated to support parallel (-j) builds and to create
# the pwm/ppm/spektrum and CC flash eraser targets in some fixed order # the pwm/ppm/spektrum and CC flash eraser targets in some fixed order
fw_pwm: | # default dependencies, will be built first fw_pwm: | # default dependencies, will be built first
fw_spektrum: | fw_pwm # ordered build fw_dsm2: | fw_pwm # ordered build
fw_ppm: | fw_spektrum # ordered build fw_sbus: | fw_dsm2 # ordered build
fw_tools: | fw_spektrum # ordered build, replace fw_spektrum by fw_ppm if uncommented below fw_ppm: | fw_sbus # ordered build
package_fw: | fw_common fw_pwm fw_spektrum # fw_ppm fw_tools: | fw_ppm # ordered build
package_fw: | fw_common fw_pwm fw_dsm2 fw_sbus fw_ppm
package_bu: | all_bu package_bu: | all_bu

View File

@ -0,0 +1,11 @@
<xml>
<object name="HwSettings" singleinstance="true" settings="true">
<description>Selection of optional hardware configurations.</description>
<field name="CC_FlexiPort" units="function" type="enum" elements="1" options="Disabled,Telemetry,GPS,Spektrum,ComAux,I2C" defaultvalue="Disabled"/>
<field name="CC_MainPort" units="function" type="enum" elements="1" options="Disabled,Telemetry,S.Bus,GPS,Spektrum,ComAux" defaultvalue="Telemetry"/>
<access gcs="readwrite" flight="readwrite"/>
<telemetrygcs acked="true" updatemode="onchange" period="0"/>
<telemetryflight acked="true" updatemode="onchange" period="0"/>
<logging updatemode="never" period="0"/>
</object>
</xml>

View File

@ -1,7 +1,7 @@
<xml> <xml>
<object name="ManualControlSettings" singleinstance="true" settings="true"> <object name="ManualControlSettings" singleinstance="true" settings="true">
<description>Settings to indicate how to decode receiver input by @ref ManualControlModule.</description> <description>Settings to indicate how to decode receiver input by @ref ManualControlModule.</description>
<field name="InputMode" units="" type="enum" elements="1" options="PWM,PPM,Spektrum" defaultvalue="PWM"/> <field name="InputMode" units="" type="enum" elements="1" options="PWM,PPM,Spektrum,S.Bus" defaultvalue="PWM"/>
<field name="Roll" units="channel" type="enum" elements="1" options="Channel1,Channel2,Channel3,Channel4,Channel5,Channel6,Channel7,Channel8,None" defaultvalue="None"/> <field name="Roll" units="channel" type="enum" elements="1" options="Channel1,Channel2,Channel3,Channel4,Channel5,Channel6,Channel7,Channel8,None" defaultvalue="None"/>
<field name="Pitch" units="channel" type="enum" elements="1" options="Channel1,Channel2,Channel3,Channel4,Channel5,Channel6,Channel7,Channel8,None" defaultvalue="None"/> <field name="Pitch" units="channel" type="enum" elements="1" options="Channel1,Channel2,Channel3,Channel4,Channel5,Channel6,Channel7,Channel8,None" defaultvalue="None"/>
<field name="Yaw" units="channel" type="enum" elements="1" options="Channel1,Channel2,Channel3,Channel4,Channel5,Channel6,Channel7,Channel8,None" defaultvalue="None"/> <field name="Yaw" units="channel" type="enum" elements="1" options="Channel1,Channel2,Channel3,Channel4,Channel5,Channel6,Channel7,Channel8,None" defaultvalue="None"/>

View File

@ -5,7 +5,7 @@
<field name="FeedForward" units="" type="float" elements="1" defaultvalue="0"/> <field name="FeedForward" units="" type="float" elements="1" defaultvalue="0"/>
<field name="AccelTime" units="ms" type="float" elements="1" defaultvalue="0"/> <field name="AccelTime" units="ms" type="float" elements="1" defaultvalue="0"/>
<field name="DecelTime" units="ms" type="float" elements="1" defaultvalue="0"/> <field name="DecelTime" units="ms" type="float" elements="1" defaultvalue="0"/>
<field name="ThrottleCurve1" units="percent" type="float" elements="5" elementnames="0,25,50,75,100" defaultvalue="0,0.25,0.5,0.75,1"/> <field name="ThrottleCurve1" units="percent" type="float" elements="5" elementnames="0,25,50,75,100" defaultvalue="0,0,0,0,0"/>
<field name="Curve2Source" units="" type="enum" elements="1" options="Throttle,Roll,Pitch,Yaw,Accessory0,Accessory1,Accessory2,Accessory3,Accessory4,Accessory5" defaultvalue="Throttle"/> <field name="Curve2Source" units="" type="enum" elements="1" options="Throttle,Roll,Pitch,Yaw,Accessory0,Accessory1,Accessory2,Accessory3,Accessory4,Accessory5" defaultvalue="Throttle"/>
<field name="ThrottleCurve2" units="percent" type="float" elements="5" elementnames="0,25,50,75,100" defaultvalue="0,0.25,0.5,0.75,1"/> <field name="ThrottleCurve2" units="percent" type="float" elements="5" elementnames="0,25,50,75,100" defaultvalue="0,0.25,0.5,0.75,1"/>
<field name="Mixer1Type" units="" type="enum" elements="1" options="Disabled,Motor,Servo,Accessory0,Accessory1,Accessory2,Accessory3,Accessory4,Accessory5" defaultvalue="Disabled"/> <field name="Mixer1Type" units="" type="enum" elements="1" options="Disabled,Motor,Servo,Accessory0,Accessory1,Accessory2,Accessory3,Accessory4,Accessory5" defaultvalue="Disabled"/>

View File

@ -1,10 +1,11 @@
<xml> <xml>
<object name="SystemSettings" singleinstance="true" settings="true"> <object name="SystemSettings" singleinstance="true" settings="true">
<description>Select airframe type. Currently used by @ref ActuatorModule to choose mixing from @ref ActuatorDesired to @ref ActuatorCommand</description> <description>Select airframe type. Currently used by @ref ActuatorModule to choose mixing from @ref ActuatorDesired to @ref ActuatorCommand</description>
<field name="AirframeType" units="" type="enum" elements="1" options="FixedWing,FixedWingElevon,FixedWingVtail,VTOL,HeliCP,QuadX,QuadP,Hexa,Octo,Custom,HexaX,OctoV,OctoCoaxP,OctoCoaxX,HexaCoax,Tri" defaultvalue="FixedWing"/> <field name="AirframeType" units="" type="enum" elements="1" options="FixedWing,FixedWingElevon,FixedWingVtail,VTOL,HeliCP,QuadX,QuadP,Hexa,Octo,Custom,HexaX,OctoV,OctoCoaxP,OctoCoaxX,HexaCoax,Tri" defaultvalue="FixedWing"/>
<access gcs="readwrite" flight="readwrite"/> <field name="GUIConfigData" units="bits" type="uint32" elements="2" defaultvalue="0"/>
<telemetrygcs acked="true" updatemode="onchange" period="0"/> <access gcs="readwrite" flight="readwrite"/>
<telemetryflight acked="true" updatemode="onchange" period="0"/> <telemetrygcs acked="true" updatemode="onchange" period="0"/>
<logging updatemode="never" period="0"/> <telemetryflight acked="true" updatemode="onchange" period="0"/>
</object> <logging updatemode="never" period="0"/>
</xml> </object>
</xml>