mirror of
https://bitbucket.org/librepilot/librepilot.git
synced 2024-12-02 10:24:11 +01:00
Merge branch 'next' into ins
Conflicts: flight/Libraries/inc/fifo_buffer.h flight/PiOS/STM32F10x/link_STM3210E_INS_sections.ld flight/Project/OpenPilotOSX/OpenPilotOSX.xcodeproj/project.pbxproj
This commit is contained in:
commit
e1afc9a19a
13
HISTORY.txt
13
HISTORY.txt
@ -1,5 +1,18 @@
|
||||
Short summary of changes. For a complete list see the git log.
|
||||
|
||||
2011-08-10
|
||||
Added Camera Stabilization and a gui to configure this. This is a software
|
||||
selectable module from the GUI. However, a restart is required to make it
|
||||
active. The GUI does not currently expose the configuration for using the
|
||||
transmitter to change the view angle but this is supported by the hardware.
|
||||
|
||||
2011-08-10
|
||||
By default a lot of diagnostic objects that were enabled by default are now
|
||||
disabled in the build. This include TaskInfo (and all the FreeRTOS options
|
||||
that provide that debugging information). Also MixerStatus, I2CStatus,
|
||||
WatchdogStatus and RateDesired. These can be reenabled for debugging with
|
||||
-DDIAGNOSTICS.
|
||||
|
||||
2011-08-04
|
||||
Fixed packaging aesthetic issues. Also avoid runtime issues on OSX Lion by
|
||||
disabling the ModelView and Notify plugins for now (sorry).
|
||||
|
@ -137,6 +137,16 @@ C: Mat Wellington
|
||||
D: July 2011
|
||||
V: http://www.youtube.com/watch?v=YE4Fd9vdg1I
|
||||
|
||||
M: First CopterControl Flybared Heli inverted flight (2:33)
|
||||
C: Maxim Izergin (Maximus43)
|
||||
D: August 2011
|
||||
V: http://www.youtube.com/watch?v=8SrfIS7OkB4
|
||||
|
||||
M: First CopterControl Flybared Heli funnel (4:18), loop (5:35)
|
||||
C: Sergey Solodennikov (alconaft43)
|
||||
D: August 2011
|
||||
V: http://www.youtube.com/watch?v=8SrfIS7OkB4
|
||||
|
||||
M: First Altitude Hold using Sonar
|
||||
C:
|
||||
D:
|
||||
|
@ -37,6 +37,9 @@ OUTDIR := $(TOP)/build/$(TARGET)
|
||||
# Set to YES to compile for debugging
|
||||
DEBUG ?= NO
|
||||
|
||||
# Include objects that are just nice information to show
|
||||
DIAGNOSTICS ?= NO
|
||||
|
||||
# Set to YES to build a FW version that will erase all flash memory
|
||||
ERASE_FLASH ?= NO
|
||||
# Set to YES to use the Servo output pins for debugging via scope or logic analyser
|
||||
@ -62,7 +65,9 @@ endif
|
||||
FLASH_TOOL = OPENOCD
|
||||
|
||||
# List of modules to include
|
||||
MODULES = Telemetry Attitude Stabilization Actuator ManualControl FirmwareIAP
|
||||
MODULES = Attitude Stabilization Actuator ManualControl FirmwareIAP CameraStab
|
||||
# Telemetry must be last to grab the optional modules
|
||||
MODULES += Telemetry
|
||||
|
||||
# Paths
|
||||
OPSYSTEM = ./System
|
||||
@ -125,7 +130,6 @@ SRC += $(OPSYSTEM)/taskmonitor.c
|
||||
SRC += $(OPUAVTALK)/uavtalk.c
|
||||
SRC += $(OPUAVOBJ)/uavobjectmanager.c
|
||||
SRC += $(OPUAVOBJ)/eventdispatcher.c
|
||||
SRC += $(OPUAVOBJ)/uavobjectsinit_linker.c
|
||||
SRC += $(OPSYSTEM)/pios_usb_hid_desc.c
|
||||
else
|
||||
## TESTCODE
|
||||
@ -153,21 +157,21 @@ SRC += $(OPUAVSYNTHDIR)/actuatorsettings.c
|
||||
SRC += $(OPUAVSYNTHDIR)/attituderaw.c
|
||||
SRC += $(OPUAVSYNTHDIR)/attitudeactual.c
|
||||
SRC += $(OPUAVSYNTHDIR)/manualcontrolcommand.c
|
||||
SRC += $(OPUAVSYNTHDIR)/taskinfo.c
|
||||
SRC += $(OPUAVSYNTHDIR)/i2cstats.c
|
||||
SRC += $(OPUAVSYNTHDIR)/watchdogstatus.c
|
||||
SRC += $(OPUAVSYNTHDIR)/telemetrysettings.c
|
||||
SRC += $(OPUAVSYNTHDIR)/ratedesired.c
|
||||
SRC += $(OPUAVSYNTHDIR)/manualcontrolsettings.c
|
||||
SRC += $(OPUAVSYNTHDIR)/mixersettings.c
|
||||
SRC += $(OPUAVSYNTHDIR)/mixerstatus.c
|
||||
SRC += $(OPUAVSYNTHDIR)/firmwareiapobj.c
|
||||
SRC += $(OPUAVSYNTHDIR)/attitudesettings.c
|
||||
SRC += $(OPUAVSYNTHDIR)/camerastabsettings.c
|
||||
SRC += $(OPUAVSYNTHDIR)/cameradesired.c
|
||||
SRC += $(OPUAVSYNTHDIR)/hwsettings.c
|
||||
#${wildcard ${OBJ}/$(shell echo $(VAR) | tr A-Z a-z)/*.c}
|
||||
#SRC += ${foreach OBJ, ${UAVOBJECTS}, $(UAVOBJECTS)/$(OBJ).c}
|
||||
# Cant use until i can automatically generate list of UAVObjects
|
||||
#SRC += ${OUTDIR}/InitObjects.c
|
||||
|
||||
SRC += $(OPUAVSYNTHDIR)/taskinfo.c
|
||||
SRC += $(OPUAVSYNTHDIR)/mixerstatus.c
|
||||
SRC += $(OPUAVSYNTHDIR)/ratedesired.c
|
||||
|
||||
endif
|
||||
|
||||
## PIOS Hardware (STM32F10x)
|
||||
@ -417,6 +421,10 @@ ifeq ($(DEBUG),YES)
|
||||
CFLAGS = -DDEBUG
|
||||
endif
|
||||
|
||||
ifeq ($(DIAGNOSTICS),YES)
|
||||
CFLAGS = -DDIAGNOSTICS
|
||||
endif
|
||||
|
||||
CFLAGS += -g$(DEBUGF)
|
||||
CFLAGS += -O$(OPT)
|
||||
CFLAGS += -mcpu=$(MCU)
|
||||
@ -425,7 +433,7 @@ CFLAGS += $(patsubst %,-I%,$(EXTRAINCDIRS)) -I.
|
||||
|
||||
#CFLAGS += -fno-cprop-registers -fno-defer-pop -fno-guess-branch-probability -fno-section-anchors
|
||||
#CFLAGS += -fno-if-conversion -fno-if-conversion2 -fno-ipa-pure-const -fno-ipa-reference -fno-merge-constants
|
||||
#CFLAGS += -fno-split-wide-types -fno-tree-ccp -fno-tree-ch -fno-tree-copy-prop -fno-tree-copyrename
|
||||
#CFLAGS += -fno-split-wide-types -fno-tree-ccp -fno-tree-ch -fno-tree-copy-prop -fno-tree-copyrename
|
||||
#CFLAGS += -fno-tree-dce -fno-tree-dominator-opts -fno-tree-dse -fno-tree-fre -fno-tree-sink -fno-tree-sra
|
||||
#CFLAGS += -fno-tree-ter
|
||||
#CFLAGS += -g$(DEBUGF) -DDEBUG
|
||||
@ -504,7 +512,7 @@ endif
|
||||
endif
|
||||
|
||||
# Generate code for PyMite
|
||||
#$(OUTDIR)/pmlib_img.c $(OUTDIR)/pmlib_nat.c $(OUTDIR)/pmlibusr_img.c $(OUTDIR)/pmlibusr_nat.c $(OUTDIR)/pmfeatures.h: $(wildcard $(PYMITELIB)/*.py) $(wildcard $(PYMITEPLAT)/*.py) $(wildcard $(FLIGHTPLANLIB)/*.py) $(wildcard $(FLIGHTPLANS)/*.py)
|
||||
#$(OUTDIR)/pmlib_img.c $(OUTDIR)/pmlib_nat.c $(OUTDIR)/pmlibusr_img.c $(OUTDIR)/pmlibusr_nat.c $(OUTDIR)/pmfeatures.h: $(wildcard $(PYMITELIB)/*.py) $(wildcard $(PYMITEPLAT)/*.py) $(wildcard $(FLIGHTPLANLIB)/*.py) $(wildcard $(FLIGHTPLANS)/*.py)
|
||||
# @echo $(MSG_PYMITEINIT) $(call toprel, $@)
|
||||
# @$(PYTHON) $(PYMITETOOLS)/pmImgCreator.py -f $(PYMITEPLAT)/pmfeatures.py -c -s --memspace=flash -o $(OUTDIR)/pmlib_img.c --native-file=$(OUTDIR)/pmlib_nat.c $(PYMITELIB)/list.py $(PYMITELIB)/dict.py $(PYMITELIB)/__bi.py $(PYMITELIB)/sys.py $(PYMITELIB)/string.py $(wildcard $(FLIGHTPLANLIB)/*.py)
|
||||
# @$(PYTHON) $(PYMITETOOLS)/pmGenPmFeatures.py $(PYMITEPLAT)/pmfeatures.py > $(OUTDIR)/pmfeatures.h
|
||||
|
@ -41,10 +41,12 @@ static xSemaphoreHandle lock;
|
||||
static int32_t hasSeverity(SystemAlarmsAlarmOptions severity);
|
||||
|
||||
/**
|
||||
* Initialize the alarms library
|
||||
* Initialize the alarms library
|
||||
*/
|
||||
int32_t AlarmsInitialize(void)
|
||||
{
|
||||
SystemAlarmsInitialize();
|
||||
|
||||
lock = xSemaphoreCreateRecursiveMutex();
|
||||
//do not change the default states of the alarms, let the init code generated by the uavobjectgenerator handle that
|
||||
//AlarmsClearAll();
|
||||
@ -56,7 +58,7 @@ int32_t AlarmsInitialize(void)
|
||||
* Set an alarm
|
||||
* @param alarm The system alarm to be modified
|
||||
* @param severity The alarm severity
|
||||
* @return 0 if success, -1 if an error
|
||||
* @return 0 if success, -1 if an error
|
||||
*/
|
||||
int32_t AlarmsSet(SystemAlarmsAlarmElem alarm, SystemAlarmsAlarmOptions severity)
|
||||
{
|
||||
@ -151,7 +153,7 @@ void AlarmsClearAll()
|
||||
|
||||
/**
|
||||
* Check if there are any alarms with the given or higher severity
|
||||
* @return 0 if no alarms are found, 1 if at least one alarm is found
|
||||
* @return 0 if no alarms are found, 1 if at least one alarm is found
|
||||
*/
|
||||
int32_t AlarmsHasWarnings()
|
||||
{
|
||||
@ -208,5 +210,5 @@ static int32_t hasSeverity(SystemAlarmsAlarmOptions severity)
|
||||
/**
|
||||
* @}
|
||||
* @}
|
||||
*/
|
||||
*/
|
||||
|
||||
|
@ -1,97 +1,107 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @addtogroup OpenPilotSystem OpenPilot System
|
||||
* @brief These files are the core system files of OpenPilot.
|
||||
* They are the ground layer just above PiOS. In practice, OpenPilot actually starts
|
||||
* in the main() function of openpilot.c
|
||||
* @{
|
||||
* @addtogroup OpenPilotCore OpenPilot Core
|
||||
* @brief This is where the OP firmware starts. Those files also define the compile-time
|
||||
* options of the firmware.
|
||||
* @{
|
||||
* @file openpilot.c
|
||||
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
|
||||
* @brief Sets up and runs main OpenPilot tasks.
|
||||
* @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
|
||||
*/
|
||||
|
||||
|
||||
/* OpenPilot Includes */
|
||||
#include "openpilot.h"
|
||||
#include "uavobjectsinit.h"
|
||||
#include "systemmod.h"
|
||||
|
||||
/* Task Priorities */
|
||||
#define PRIORITY_TASK_HOOKS (tskIDLE_PRIORITY + 3)
|
||||
|
||||
/* Global Variables */
|
||||
|
||||
/* Prototype of PIOS_Board_Init() function */
|
||||
extern void PIOS_Board_Init(void);
|
||||
extern void Stack_Change(void);
|
||||
|
||||
/**
|
||||
* OpenPilot Main function:
|
||||
*
|
||||
* Initialize PiOS<BR>
|
||||
* Create the "System" task (SystemModInitializein Modules/System/systemmod.c) <BR>
|
||||
* Start FreeRTOS Scheduler (vTaskStartScheduler) (Now handled by caller)
|
||||
* If something goes wrong, blink LED1 and LED2 every 100ms
|
||||
*
|
||||
*/
|
||||
int main()
|
||||
{
|
||||
/* NOTE: Do NOT modify the following start-up sequence */
|
||||
/* Any new initialization functions should be added in OpenPilotInit() */
|
||||
|
||||
/* Brings up System using CMSIS functions, enables the LEDs. */
|
||||
PIOS_SYS_Init();
|
||||
|
||||
/* Architecture dependant Hardware and
|
||||
* core subsystem initialisation
|
||||
* (see pios_board.c for your arch)
|
||||
* */
|
||||
PIOS_Board_Init();
|
||||
|
||||
/* Initialize modules */
|
||||
MODULE_INITIALISE_ALL
|
||||
|
||||
/* swap the stack to use the IRQ stack */
|
||||
Stack_Change();
|
||||
|
||||
/* Start the FreeRTOS scheduler which should never returns.*/
|
||||
vTaskStartScheduler();
|
||||
|
||||
/* If all is well we will never reach here as the scheduler will now be running. */
|
||||
|
||||
/* Do some indication to user that something bad just happened */
|
||||
PIOS_LED_Off(LED1); \
|
||||
for(;;) { \
|
||||
PIOS_LED_Toggle(LED1); \
|
||||
PIOS_DELAY_WaitmS(100); \
|
||||
};
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @}
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
******************************************************************************
|
||||
* @addtogroup OpenPilotSystem OpenPilot System
|
||||
* @brief These files are the core system files of OpenPilot.
|
||||
* They are the ground layer just above PiOS. In practice, OpenPilot actually starts
|
||||
* in the main() function of openpilot.c
|
||||
* @{
|
||||
* @addtogroup OpenPilotCore OpenPilot Core
|
||||
* @brief This is where the OP firmware starts. Those files also define the compile-time
|
||||
* options of the firmware.
|
||||
* @{
|
||||
* @file openpilot.c
|
||||
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
|
||||
* @brief Sets up and runs main OpenPilot tasks.
|
||||
* @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
|
||||
*/
|
||||
|
||||
|
||||
/* OpenPilot Includes */
|
||||
#include "openpilot.h"
|
||||
#include "uavobjectsinit.h"
|
||||
#include "hwsettings.h"
|
||||
#include "camerastab.h"
|
||||
#include "systemmod.h"
|
||||
|
||||
/* Task Priorities */
|
||||
#define PRIORITY_TASK_HOOKS (tskIDLE_PRIORITY + 3)
|
||||
|
||||
/* Global Variables */
|
||||
|
||||
/* Prototype of PIOS_Board_Init() function */
|
||||
extern void PIOS_Board_Init(void);
|
||||
extern void Stack_Change(void);
|
||||
|
||||
/**
|
||||
* OpenPilot Main function:
|
||||
*
|
||||
* Initialize PiOS<BR>
|
||||
* Create the "System" task (SystemModInitializein Modules/System/systemmod.c) <BR>
|
||||
* Start FreeRTOS Scheduler (vTaskStartScheduler) (Now handled by caller)
|
||||
* If something goes wrong, blink LED1 and LED2 every 100ms
|
||||
*
|
||||
*/
|
||||
int main()
|
||||
{
|
||||
/* NOTE: Do NOT modify the following start-up sequence */
|
||||
/* Any new initialization functions should be added in OpenPilotInit() */
|
||||
|
||||
/* Brings up System using CMSIS functions, enables the LEDs. */
|
||||
PIOS_SYS_Init();
|
||||
|
||||
/* Architecture dependant Hardware and
|
||||
* core subsystem initialisation
|
||||
* (see pios_board.c for your arch)
|
||||
* */
|
||||
PIOS_Board_Init();
|
||||
|
||||
/* Initialize modules */
|
||||
MODULE_INITIALISE_ALL
|
||||
|
||||
/* Optional module initialization. This code might want to go somewhere else as
|
||||
* it grows */
|
||||
uint8_t optionalModules[HWSETTINGS_OPTIONALMODULES_NUMELEM];
|
||||
HwSettingsOptionalModulesGet(optionalModules);
|
||||
if(optionalModules[HWSETTINGS_OPTIONALMODULES_CAMERASTABILIZATION] == HWSETTINGS_OPTIONALMODULES_ENABLED) {
|
||||
CameraStabInitialize();
|
||||
}
|
||||
|
||||
/* swap the stack to use the IRQ stack */
|
||||
Stack_Change();
|
||||
|
||||
/* Start the FreeRTOS scheduler which should never returns.*/
|
||||
vTaskStartScheduler();
|
||||
|
||||
/* If all is well we will never reach here as the scheduler will now be running. */
|
||||
|
||||
/* Do some indication to user that something bad just happened */
|
||||
PIOS_LED_Off(LED1); \
|
||||
for(;;) { \
|
||||
PIOS_LED_Toggle(LED1); \
|
||||
PIOS_DELAY_WaitmS(100); \
|
||||
};
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @}
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
@ -39,7 +39,6 @@
|
||||
#define configUSE_RECURSIVE_MUTEXES 1
|
||||
#define configUSE_COUNTING_SEMAPHORES 0
|
||||
#define configUSE_ALTERNATIVE_API 0
|
||||
#define configCHECK_FOR_STACK_OVERFLOW 2
|
||||
#define configQUEUE_REGISTRY_SIZE 10
|
||||
|
||||
/* Co-routine definitions. */
|
||||
@ -76,7 +75,9 @@ NVIC value of 255. */
|
||||
#endif
|
||||
|
||||
/* Enable run time stats collection */
|
||||
//#if defined(DEBUG)
|
||||
#if defined(DIAGNOSTICS)
|
||||
#define configCHECK_FOR_STACK_OVERFLOW 2
|
||||
|
||||
#define configGENERATE_RUN_TIME_STATS 1
|
||||
#define INCLUDE_uxTaskGetRunTime 1
|
||||
#define portCONFIGURE_TIMER_FOR_RUN_TIME_STATS()\
|
||||
@ -85,7 +86,9 @@ do {\
|
||||
(*(unsigned long *)0xe0001000) |= 1; /* DWT_CTRL |= DWT_CYCCNT_ENA */\
|
||||
} while(0)
|
||||
#define portGET_RUN_TIME_COUNTER_VALUE() (*(unsigned long *)0xe0001004)/* DWT_CYCCNT */
|
||||
//#endif
|
||||
#else
|
||||
#define configCHECK_FOR_STACK_OVERFLOW 1
|
||||
#endif
|
||||
|
||||
|
||||
/**
|
||||
|
@ -99,10 +99,13 @@
|
||||
#define PIOS_SYSTEM_STACK_SIZE 460
|
||||
#define PIOS_STABILIZATION_STACK_SIZE 524
|
||||
#define PIOS_TELEM_STACK_SIZE 500
|
||||
#define PIOS_EVENTDISPATCHER_STACK_SIZE 96
|
||||
#define PIOS_EVENTDISPATCHER_STACK_SIZE 130
|
||||
#define IDLE_COUNTS_PER_SEC_AT_NO_LOAD 1995998
|
||||
//#define PIOS_QUATERNION_STABILIZATION
|
||||
|
||||
// This can't be too high to stop eventdispatcher thread overflowing
|
||||
#define PIOS_EVENTDISAPTCHER_QUEUE 10
|
||||
|
||||
#endif /* PIOS_CONFIG_H */
|
||||
/**
|
||||
* @}
|
||||
|
@ -907,8 +907,10 @@ void PIOS_Board_Init(void) {
|
||||
/* Initialize UAVObject libraries */
|
||||
EventDispatcherInitialize();
|
||||
UAVObjInitialize();
|
||||
UAVObjectsInitializeAll();
|
||||
|
||||
HwSettingsInitialize();
|
||||
ManualControlSettingsInitialize();
|
||||
|
||||
#if defined(PIOS_INCLUDE_RTC)
|
||||
/* Initialize the real-time clock and its associated tick */
|
||||
PIOS_RTC_Init(&pios_rtc_main_cfg);
|
||||
|
@ -42,7 +42,6 @@ void PIOS_Board_Init(void) {
|
||||
/* Initialize UAVObject libraries */
|
||||
EventDispatcherInitialize();
|
||||
UAVObjInitialize();
|
||||
UAVObjectsInitializeAll();
|
||||
|
||||
/* Initialize the alarms library */
|
||||
AlarmsInitialize();
|
||||
|
@ -46,7 +46,10 @@ int32_t TaskMonitorInitialize(void)
|
||||
{
|
||||
lock = xSemaphoreCreateRecursiveMutex();
|
||||
memset(handles, 0, sizeof(xTaskHandle)*TASKINFO_RUNNING_NUMELEM);
|
||||
lastMonitorTime = 0;
|
||||
#if defined(DIAGNOSTICS)
|
||||
lastMonitorTime = portGET_RUN_TIME_COUNTER_VALUE();
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -73,6 +76,7 @@ int32_t TaskMonitorAdd(TaskInfoRunningElem task, xTaskHandle handle)
|
||||
*/
|
||||
void TaskMonitorUpdateAll(void)
|
||||
{
|
||||
#if defined(DIAGNOSTICS)
|
||||
TaskInfoData data;
|
||||
int n;
|
||||
|
||||
@ -123,4 +127,5 @@ void TaskMonitorUpdateAll(void)
|
||||
|
||||
// Done
|
||||
xSemaphoreGiveRecursive(lock);
|
||||
#endif
|
||||
}
|
||||
|
@ -52,6 +52,8 @@
|
||||
|
||||
#include "ahrs_comms.h"
|
||||
#include "ahrs_spi_comm.h"
|
||||
#include "ahrsstatus.h"
|
||||
#include "ahrscalibration.h"
|
||||
|
||||
// Private constants
|
||||
#define STACK_SIZE configMINIMAL_STACK_SIZE-128
|
||||
@ -71,7 +73,7 @@ static void ahrscommsTask(void *parameters);
|
||||
*/
|
||||
int32_t AHRSCommsStart(void)
|
||||
{
|
||||
// Start main task
|
||||
// Start main task
|
||||
xTaskCreate(ahrscommsTask, (signed char *)"AHRSComms", STACK_SIZE, NULL, TASK_PRIORITY, &taskHandle);
|
||||
TaskMonitorAdd(TASKINFO_RUNNING_AHRSCOMMS, taskHandle);
|
||||
PIOS_WDG_RegisterFlag(PIOS_WDG_AHRS);
|
||||
@ -85,6 +87,11 @@ int32_t AHRSCommsStart(void)
|
||||
*/
|
||||
int32_t AHRSCommsInitialize(void)
|
||||
{
|
||||
AhrsStatusInitialize();
|
||||
AHRSCalibrationInitialize();
|
||||
AttitudeRawInitialize();
|
||||
VelocityActualInitialize();
|
||||
PositionActualInitialize();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -41,6 +41,7 @@
|
||||
#include "flightstatus.h"
|
||||
#include "mixersettings.h"
|
||||
#include "mixerstatus.h"
|
||||
#include "cameradesired.h"
|
||||
|
||||
|
||||
// Private constants
|
||||
@ -108,9 +109,17 @@ int32_t ActuatorInitialize()
|
||||
// Create object queue
|
||||
queue = xQueueCreate(MAX_QUEUE_SIZE, sizeof(UAVObjEvent));
|
||||
|
||||
ActuatorSettingsInitialize();
|
||||
ActuatorDesiredInitialize();
|
||||
MixerSettingsInitialize();
|
||||
ActuatorCommandInitialize();
|
||||
#if defined(DIAGNOSTICS)
|
||||
MixerStatusInitialize();
|
||||
#endif
|
||||
|
||||
// Listen for ExampleObject1 updates
|
||||
ActuatorDesiredConnectQueue(queue);
|
||||
|
||||
|
||||
// If settings change, update the output rate
|
||||
ActuatorSettingsConnectCallback(actuator_update_rate);
|
||||
|
||||
@ -160,7 +169,7 @@ static void actuatorTask(void* parameters)
|
||||
// Main task loop
|
||||
lastSysTime = xTaskGetTickCount();
|
||||
while (1)
|
||||
{
|
||||
{
|
||||
PIOS_WDG_UpdateFlag(PIOS_WDG_ACTUATOR);
|
||||
|
||||
// Wait until the ActuatorDesired object is updated, if a timeout then go to failsafe
|
||||
@ -177,11 +186,13 @@ static void actuatorTask(void* parameters)
|
||||
lastSysTime = thisSysTime;
|
||||
|
||||
FlightStatusGet(&flightStatus);
|
||||
MixerStatusGet(&mixerStatus);
|
||||
MixerSettingsGet (&mixerSettings);
|
||||
ActuatorDesiredGet(&desired);
|
||||
ActuatorCommandGet(&command);
|
||||
|
||||
#if defined(DIAGNOSTICS)
|
||||
MixerStatusGet(&mixerStatus);
|
||||
#endif
|
||||
ActuatorSettingsMotorsSpinWhileArmedGet(&MotorsSpinWhileArmed);
|
||||
ActuatorSettingsChannelMaxGet(ChannelMax);
|
||||
ActuatorSettingsChannelMinGet(ChannelMin);
|
||||
@ -196,7 +207,7 @@ static void actuatorTask(void* parameters)
|
||||
nMixers ++;
|
||||
}
|
||||
}
|
||||
if((nMixers < 2) && !ActuatorCommandReadOnly(dummy)) //Nothing can fly with less than two mixers.
|
||||
if((nMixers < 2) && !ActuatorCommandReadOnly(dummy)) //Nothing can fly with less than two mixers.
|
||||
{
|
||||
setFailsafe(); // So that channels like PWM buzzer keep working
|
||||
continue;
|
||||
@ -207,7 +218,7 @@ static void actuatorTask(void* parameters)
|
||||
bool armed = flightStatus.Armed == FLIGHTSTATUS_ARMED_ARMED;
|
||||
bool positiveThrottle = desired.Throttle >= 0.00;
|
||||
bool spinWhileArmed = MotorsSpinWhileArmed == ACTUATORSETTINGS_MOTORSSPINWHILEARMED_TRUE;
|
||||
|
||||
|
||||
float curve1 = MixerCurve(desired.Throttle,mixerSettings.ThrottleCurve1);
|
||||
//The source for the secondary curve is selectable
|
||||
float curve2 = 0;
|
||||
@ -233,11 +244,11 @@ static void actuatorTask(void* parameters)
|
||||
case MIXERSETTINGS_CURVE2SOURCE_ACCESSORY5:
|
||||
if(AccessoryDesiredInstGet(mixerSettings.Curve2Source - MIXERSETTINGS_CURVE2SOURCE_ACCESSORY0,&accessory) == 0)
|
||||
curve2 = MixerCurve(accessory.AccessoryVal,mixerSettings.ThrottleCurve2);
|
||||
else
|
||||
curve2 = 0;
|
||||
else
|
||||
curve2 = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
for(int ct=0; ct < MAX_MIX_ACTUATORS; ct++)
|
||||
{
|
||||
if(mixers[ct].type == MIXERSETTINGS_MIXER1TYPE_DISABLED) {
|
||||
@ -246,53 +257,82 @@ static void actuatorTask(void* parameters)
|
||||
command.Channel[ct] = 0;
|
||||
continue;
|
||||
}
|
||||
|
||||
status[ct] = ProcessMixer(ct, curve1, curve2, &mixerSettings, &desired, dT);
|
||||
|
||||
|
||||
if((mixers[ct].type == MIXERSETTINGS_MIXER1TYPE_MOTOR) || (mixers[ct].type == MIXERSETTINGS_MIXER1TYPE_SERVO))
|
||||
status[ct] = ProcessMixer(ct, curve1, curve2, &mixerSettings, &desired, dT);
|
||||
else
|
||||
status[ct] = -1;
|
||||
|
||||
|
||||
|
||||
// Motors have additional protection for when to be on
|
||||
if(mixers[ct].type == MIXERSETTINGS_MIXER1TYPE_MOTOR) {
|
||||
if(mixers[ct].type == MIXERSETTINGS_MIXER1TYPE_MOTOR) {
|
||||
|
||||
// If not armed or motors aren't meant to spin all the time
|
||||
if( !armed ||
|
||||
(!spinWhileArmed && !positiveThrottle))
|
||||
{
|
||||
filterAccumulator[ct] = 0;
|
||||
lastResult[ct] = 0;
|
||||
lastResult[ct] = 0;
|
||||
status[ct] = -1; //force min throttle
|
||||
}
|
||||
// If armed meant to keep spinning,
|
||||
}
|
||||
// If armed meant to keep spinning,
|
||||
else if ((spinWhileArmed && !positiveThrottle) ||
|
||||
(status[ct] < 0) )
|
||||
status[ct] = 0;
|
||||
status[ct] = 0;
|
||||
}
|
||||
|
||||
|
||||
// If an accessory channel is selected for direct bypass mode
|
||||
// In this configuration the accessory channel is scaled and mapped
|
||||
// directly to output. Note: THERE IS NO SAFETY CHECK HERE FOR ARMING
|
||||
// these also will not be updated in failsafe mode. I'm not sure what
|
||||
// these also will not be updated in failsafe mode. I'm not sure what
|
||||
// the correct behavior is since it seems domain specific. I don't love
|
||||
// this code
|
||||
if( (mixers[ct].type >= MIXERSETTINGS_MIXER1TYPE_ACCESSORY0) &&
|
||||
(mixers[ct].type <= MIXERSETTINGS_MIXER1TYPE_ACCESSORY2))
|
||||
if( (mixers[ct].type >= MIXERSETTINGS_MIXER1TYPE_ACCESSORY0) &&
|
||||
(mixers[ct].type <= MIXERSETTINGS_MIXER1TYPE_ACCESSORY5))
|
||||
{
|
||||
if(AccessoryDesiredInstGet(mixers[ct].type - MIXERSETTINGS_MIXER1TYPE_ACCESSORY0,&accessory) == 0)
|
||||
status[ct] = accessory.AccessoryVal;
|
||||
else
|
||||
status[ct] = -1;
|
||||
}
|
||||
|
||||
if( (mixers[ct].type >= MIXERSETTINGS_MIXER1TYPE_CAMERAROLL) &&
|
||||
(mixers[ct].type <= MIXERSETTINGS_MIXER1TYPE_CAMERAYAW))
|
||||
{
|
||||
CameraDesiredData cameraDesired;
|
||||
if( CameraDesiredGet(&cameraDesired) == 0 ) {
|
||||
switch(mixers[ct].type) {
|
||||
case MIXERSETTINGS_MIXER1TYPE_CAMERAROLL:
|
||||
status[ct] = cameraDesired.Roll;
|
||||
break;
|
||||
case MIXERSETTINGS_MIXER1TYPE_CAMERAPITCH:
|
||||
status[ct] = cameraDesired.Pitch;
|
||||
break;
|
||||
case MIXERSETTINGS_MIXER1TYPE_CAMERAYAW:
|
||||
status[ct] = cameraDesired.Yaw;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
status[ct] = -1;
|
||||
}
|
||||
|
||||
command.Channel[ct] = scaleChannel(status[ct],
|
||||
ChannelMax[ct],
|
||||
ChannelMin[ct],
|
||||
ChannelNeutral[ct]);
|
||||
}
|
||||
#if defined(DIAGNOSTICS)
|
||||
MixerStatusSet(&mixerStatus);
|
||||
#endif
|
||||
|
||||
// Store update time
|
||||
command.UpdateTime = 1000*dT;
|
||||
if(1000*dT > command.MaxUpdateTime)
|
||||
command.MaxUpdateTime = 1000*dT;
|
||||
|
||||
|
||||
// Update output object
|
||||
ActuatorCommandSet(&command);
|
||||
// Update in case read only (eg. during servo configuration)
|
||||
@ -300,7 +340,7 @@ static void actuatorTask(void* parameters)
|
||||
|
||||
// Update servo outputs
|
||||
bool success = true;
|
||||
|
||||
|
||||
for (int n = 0; n < ACTUATORCOMMAND_CHANNEL_NUMELEM; ++n)
|
||||
{
|
||||
success &= set_channel(n, command.Channel[n]);
|
||||
@ -309,7 +349,7 @@ static void actuatorTask(void* parameters)
|
||||
if(!success) {
|
||||
command.NumFailedUpdates++;
|
||||
ActuatorCommandSet(&command);
|
||||
AlarmsSet(SYSTEMALARMS_ALARM_ACTUATOR, SYSTEMALARMS_ALARM_CRITICAL);
|
||||
AlarmsSet(SYSTEMALARMS_ALARM_ACTUATOR, SYSTEMALARMS_ALARM_CRITICAL);
|
||||
}
|
||||
|
||||
}
|
||||
@ -463,7 +503,7 @@ static void setFailsafe()
|
||||
// Reset ActuatorCommand to safe values
|
||||
for (int n = 0; n < ACTUATORCOMMAND_CHANNEL_NUMELEM; ++n)
|
||||
{
|
||||
|
||||
|
||||
if(mixers[n].type == MIXERSETTINGS_MIXER1TYPE_MOTOR)
|
||||
{
|
||||
Channel[n] = ChannelMin[n];
|
||||
@ -510,10 +550,10 @@ static bool set_channel(uint8_t mixer_channel, uint16_t value) {
|
||||
}
|
||||
#else
|
||||
static bool set_channel(uint8_t mixer_channel, uint16_t value) {
|
||||
|
||||
|
||||
ActuatorSettingsData settings;
|
||||
ActuatorSettingsGet(&settings);
|
||||
|
||||
|
||||
switch(settings.ChannelType[mixer_channel]) {
|
||||
case ACTUATORSETTINGS_CHANNELTYPE_PWMALARMBUZZER: {
|
||||
// This is for buzzers that take a PWM input
|
||||
@ -565,7 +605,7 @@ static bool set_channel(uint8_t mixer_channel, uint16_t value) {
|
||||
PIOS_Servo_Set(settings.ChannelAddr[mixer_channel], value);
|
||||
return true;
|
||||
#if defined(PIOS_INCLUDE_I2C_ESC)
|
||||
case ACTUATORSETTINGS_CHANNELTYPE_MK:
|
||||
case ACTUATORSETTINGS_CHANNELTYPE_MK:
|
||||
return PIOS_SetMKSpeed(settings.ChannelAddr[mixer_channel],value);
|
||||
case ACTUATORSETTINGS_CHANNELTYPE_ASTEC4:
|
||||
return PIOS_SetAstec4Speed(settings.ChannelAddr[mixer_channel],value);
|
||||
@ -573,10 +613,10 @@ static bool set_channel(uint8_t mixer_channel, uint16_t value) {
|
||||
#endif
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -69,6 +69,12 @@ static void altitudeTask(void *parameters);
|
||||
*/
|
||||
int32_t AltitudeStart()
|
||||
{
|
||||
|
||||
BaroAltitudeInitialize();
|
||||
#if defined(PIOS_INCLUDE_HCSR04)
|
||||
SonarAltitudeInitialze();
|
||||
#endif
|
||||
|
||||
// Start main task
|
||||
xTaskCreate(altitudeTask, (signed char *)"Altitude", STACK_SIZE_BYTES/4, NULL, TASK_PRIORITY, &taskHandle);
|
||||
TaskMonitorAdd(TASKINFO_RUNNING_ALTITUDE, taskHandle);
|
||||
|
@ -76,7 +76,7 @@ static void AttitudeTask(void *parameters);
|
||||
static float gyro_correct_int[3] = {0,0,0};
|
||||
static xQueueHandle gyro_queue;
|
||||
|
||||
static void updateSensors(AttitudeRawData *);
|
||||
static int8_t updateSensors(AttitudeRawData *);
|
||||
static void updateAttitude(AttitudeRawData *);
|
||||
static void settingsUpdatedCb(UAVObjEvent * objEv);
|
||||
|
||||
@ -112,6 +112,10 @@ int32_t AttitudeStart(void)
|
||||
*/
|
||||
int32_t AttitudeInitialize(void)
|
||||
{
|
||||
AttitudeActualInitialize();
|
||||
AttitudeRawInitialize();
|
||||
AttitudeSettingsInitialize();
|
||||
|
||||
// Initialize quaternion
|
||||
AttitudeActualData attitude;
|
||||
AttitudeActualGet(&attitude);
|
||||
@ -162,14 +166,19 @@ static void AttitudeTask(void *parameters)
|
||||
// Keep flash CS pin high while talking accel
|
||||
PIOS_FLASH_DISABLE;
|
||||
PIOS_ADXL345_Init();
|
||||
|
||||
|
||||
|
||||
// Set critical error and wait until the accel is producing data
|
||||
while(PIOS_ADXL345_FifoElements() == 0) {
|
||||
AlarmsSet(SYSTEMALARMS_ALARM_ATTITUDE, SYSTEMALARMS_ALARM_CRITICAL);
|
||||
PIOS_WDG_UpdateFlag(PIOS_WDG_ATTITUDE);
|
||||
}
|
||||
|
||||
// Force settings update to make sure rotation loaded
|
||||
settingsUpdatedCb(AttitudeSettingsHandle());
|
||||
|
||||
// Main task loop
|
||||
while (1) {
|
||||
|
||||
|
||||
FlightStatusData flightStatus;
|
||||
FlightStatusGet(&flightStatus);
|
||||
|
||||
@ -197,14 +206,24 @@ static void AttitudeTask(void *parameters)
|
||||
|
||||
AttitudeRawData attitudeRaw;
|
||||
AttitudeRawGet(&attitudeRaw);
|
||||
updateSensors(&attitudeRaw);
|
||||
updateAttitude(&attitudeRaw);
|
||||
AttitudeRawSet(&attitudeRaw);
|
||||
if(updateSensors(&attitudeRaw) != 0)
|
||||
AlarmsSet(SYSTEMALARMS_ALARM_ATTITUDE, SYSTEMALARMS_ALARM_ERROR);
|
||||
else {
|
||||
// Only update attitude when sensor data is good
|
||||
updateAttitude(&attitudeRaw);
|
||||
AttitudeRawSet(&attitudeRaw);
|
||||
AlarmsClear(SYSTEMALARMS_ALARM_ATTITUDE);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
static void updateSensors(AttitudeRawData * attitudeRaw)
|
||||
/**
|
||||
* Get an update from the sensors
|
||||
* @param[in] attitudeRaw Populate the UAVO instead of saving right here
|
||||
* @return 0 if successfull, -1 if not
|
||||
*/
|
||||
static int8_t updateSensors(AttitudeRawData * attitudeRaw)
|
||||
{
|
||||
struct pios_adxl345_data accel_data;
|
||||
float gyro[4];
|
||||
@ -212,9 +231,12 @@ static void updateSensors(AttitudeRawData * attitudeRaw)
|
||||
// Only wait the time for two nominal updates before setting an alarm
|
||||
if(xQueueReceive(gyro_queue, (void * const) gyro, UPDATE_RATE * 2) == errQUEUE_EMPTY) {
|
||||
AlarmsSet(SYSTEMALARMS_ALARM_ATTITUDE, SYSTEMALARMS_ALARM_ERROR);
|
||||
return;
|
||||
return -1;
|
||||
}
|
||||
|
||||
// No accel data available
|
||||
if(PIOS_ADXL345_FifoElements() == 0)
|
||||
return -1;
|
||||
|
||||
// First sample is temperature
|
||||
attitudeRaw->gyros[ATTITUDERAW_GYROS_X] = -(gyro[1] - GYRO_NEUTRAL) * gyroGain;
|
||||
@ -270,6 +292,8 @@ static void updateSensors(AttitudeRawData * attitudeRaw)
|
||||
// Because most crafts wont get enough information from gravity to zero yaw gyro, we try
|
||||
// and make it average zero (weakly)
|
||||
gyro_correct_int[2] += - attitudeRaw->gyros[ATTITUDERAW_GYROS_Z] * yawBiasRate;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void updateAttitude(AttitudeRawData * attitudeRaw)
|
||||
@ -307,6 +331,7 @@ static void updateAttitude(AttitudeRawData * attitudeRaw)
|
||||
// Accumulate integral of error. Scale here so that units are (deg/s) but Ki has units of s
|
||||
gyro_correct_int[0] += accel_err[0] * accelKi;
|
||||
gyro_correct_int[1] += accel_err[1] * accelKi;
|
||||
|
||||
//gyro_correct_int[2] += accel_err[2] * settings.AccelKI * dT;
|
||||
|
||||
// Correct rates based on error, integral component dealt with in updateSensors
|
||||
|
@ -79,6 +79,9 @@ MODULE_INITCALL(BatteryInitialize, 0)
|
||||
|
||||
int32_t BatteryInitialize(void)
|
||||
{
|
||||
BatteryStateInitialze();
|
||||
BatterySettingsInitialize();
|
||||
|
||||
static UAVObjEvent ev;
|
||||
|
||||
memset(&ev,0,sizeof(UAVObjEvent));
|
||||
|
141
flight/Modules/CameraStab/camerastab.c
Normal file
141
flight/Modules/CameraStab/camerastab.c
Normal file
@ -0,0 +1,141 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @addtogroup OpenPilotModules OpenPilot Modules
|
||||
* @{
|
||||
* @addtogroup CameraStab Camera Stabilization Module
|
||||
* @brief Camera stabilization module
|
||||
* Updates accessory outputs with values appropriate for camera stabilization
|
||||
* @{
|
||||
*
|
||||
* @file camerastab.c
|
||||
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
|
||||
* @brief Stabilize camera against the roll pitch and yaw of aircraft
|
||||
*
|
||||
* @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
|
||||
*/
|
||||
|
||||
/**
|
||||
* Output object: Accessory
|
||||
*
|
||||
* This module will periodically calculate the output values for stabilizing the camera
|
||||
*
|
||||
* UAVObjects are automatically generated by the UAVObjectGenerator from
|
||||
* the object definition XML file.
|
||||
*
|
||||
* Modules have no API, all communication to other modules is done through UAVObjects.
|
||||
* However modules may use the API exposed by shared libraries.
|
||||
* See the OpenPilot wiki for more details.
|
||||
* http://www.openpilot.org/OpenPilot_Application_Architecture
|
||||
*
|
||||
*/
|
||||
|
||||
#include "openpilot.h"
|
||||
|
||||
#include "accessorydesired.h"
|
||||
#include "attitudeactual.h"
|
||||
#include "camerastabsettings.h"
|
||||
#include "cameradesired.h"
|
||||
|
||||
//
|
||||
// Configuration
|
||||
//
|
||||
#define SAMPLE_PERIOD_MS 10
|
||||
|
||||
// Private types
|
||||
|
||||
// Private variables
|
||||
|
||||
// Private functions
|
||||
static void attitudeUpdated(UAVObjEvent* ev);
|
||||
static float bound(float val);
|
||||
|
||||
/**
|
||||
* Initialise the module, called on startup
|
||||
* \returns 0 on success or -1 if initialisation failed
|
||||
*/
|
||||
int32_t CameraStabInitialize(void)
|
||||
{
|
||||
static UAVObjEvent ev;
|
||||
ev.obj = AttitudeActualHandle();
|
||||
ev.instId = 0;
|
||||
ev.event = 0;
|
||||
|
||||
CameraStabSettingsInitialize();
|
||||
CameraDesiredInitialize();
|
||||
|
||||
EventPeriodicCallbackCreate(&ev, attitudeUpdated, SAMPLE_PERIOD_MS / portTICK_RATE_MS);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void attitudeUpdated(UAVObjEvent* ev)
|
||||
{
|
||||
if (ev->obj != AttitudeActualHandle())
|
||||
return;
|
||||
|
||||
float attitude;
|
||||
float output;
|
||||
AccessoryDesiredData accessory;
|
||||
|
||||
CameraStabSettingsData cameraStab;
|
||||
CameraStabSettingsGet(&cameraStab);
|
||||
|
||||
// Read any input channels
|
||||
float inputs[3] = {0,0,0};
|
||||
if(cameraStab.Inputs[CAMERASTABSETTINGS_INPUTS_ROLL] != CAMERASTABSETTINGS_INPUTS_NONE) {
|
||||
if(AccessoryDesiredInstGet(cameraStab.Inputs[CAMERASTABSETTINGS_INPUTS_ROLL] - CAMERASTABSETTINGS_INPUTS_ACCESSORY0, &accessory) == 0)
|
||||
inputs[0] = accessory.AccessoryVal * cameraStab.InputRange[CAMERASTABSETTINGS_INPUTRANGE_ROLL];
|
||||
}
|
||||
if(cameraStab.Inputs[CAMERASTABSETTINGS_INPUTS_PITCH] != CAMERASTABSETTINGS_INPUTS_NONE) {
|
||||
if(AccessoryDesiredInstGet(cameraStab.Inputs[CAMERASTABSETTINGS_INPUTS_PITCH] - CAMERASTABSETTINGS_INPUTS_ACCESSORY0, &accessory) == 0)
|
||||
inputs[1] = accessory.AccessoryVal * cameraStab.InputRange[CAMERASTABSETTINGS_INPUTRANGE_PITCH];
|
||||
}
|
||||
if(cameraStab.Inputs[CAMERASTABSETTINGS_INPUTS_YAW] != CAMERASTABSETTINGS_INPUTS_NONE) {
|
||||
if(AccessoryDesiredInstGet(cameraStab.Inputs[CAMERASTABSETTINGS_INPUTS_YAW] - CAMERASTABSETTINGS_INPUTS_ACCESSORY0, &accessory) == 0)
|
||||
inputs[2] = accessory.AccessoryVal * cameraStab.InputRange[CAMERASTABSETTINGS_INPUTRANGE_YAW];
|
||||
}
|
||||
|
||||
// Set output channels
|
||||
AttitudeActualRollGet(&attitude);
|
||||
output = bound((attitude + inputs[0]) / cameraStab.OutputRange[CAMERASTABSETTINGS_OUTPUTRANGE_ROLL]);
|
||||
CameraDesiredRollSet(&output);
|
||||
|
||||
AttitudeActualPitchGet(&attitude);
|
||||
output = bound((attitude + inputs[1]) / cameraStab.OutputRange[CAMERASTABSETTINGS_OUTPUTRANGE_PITCH]);
|
||||
CameraDesiredPitchSet(&output);
|
||||
|
||||
AttitudeActualYawGet(&attitude);
|
||||
output = bound((attitude + inputs[2]) / cameraStab.OutputRange[CAMERASTABSETTINGS_OUTPUTRANGE_YAW]);
|
||||
CameraDesiredYawSet(&output);
|
||||
|
||||
}
|
||||
|
||||
float bound(float val)
|
||||
{
|
||||
return (val > 1) ? 1 :
|
||||
(val < -1) ? -1 :
|
||||
val;
|
||||
}
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
@ -1,45 +1,42 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
*
|
||||
* @file uavobjectsinit.c
|
||||
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
|
||||
* @brief Initialize all objects.
|
||||
* Automatically generated by the UAVObjectGenerator.
|
||||
*
|
||||
* @note This is an automatically generated file.
|
||||
* DO NOT modify manually.
|
||||
* @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
|
||||
*/
|
||||
|
||||
#include "openpilot.h"
|
||||
|
||||
/**
|
||||
* Function used to initialize the first instance of each object.
|
||||
* This file is automatically updated by the UAVObjectGenerator.
|
||||
*/
|
||||
extern initcall_t __uavobj_initcall_start[], __uavobj_initcall_end[];
|
||||
|
||||
void UAVObjectsInitializeAll()
|
||||
{
|
||||
initcall_t *fn;
|
||||
int32_t ret;
|
||||
|
||||
for (fn = __uavobj_initcall_start; fn < __uavobj_initcall_end; fn++)
|
||||
ret = (*fn)();
|
||||
}
|
||||
/**
|
||||
******************************************************************************
|
||||
* @addtogroup OpenPilotModules OpenPilot Modules
|
||||
* @{
|
||||
* @addtogroup BatteryModule Battery Module
|
||||
* @{
|
||||
*
|
||||
* @file battery.h
|
||||
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
|
||||
* @brief Module to read the battery Voltage and Current periodically and set alarms appropriately.
|
||||
*
|
||||
* @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 BATTERY_H
|
||||
#define BATTERY_H
|
||||
|
||||
#include "openpilot.h"
|
||||
|
||||
int32_t CameraStabInitialize(void);
|
||||
|
||||
#endif // BATTERY_H
|
||||
|
||||
/**
|
||||
* @}
|
||||
* @}
|
||||
*/
|
@ -91,6 +91,9 @@ static void resetTask(UAVObjEvent *);
|
||||
MODULE_INITCALL(FirmwareIAPInitialize, 0)
|
||||
int32_t FirmwareIAPInitialize()
|
||||
{
|
||||
|
||||
FirmwareIAPObjInitialize();
|
||||
|
||||
const struct pios_board_info * bdinfo = &pios_board_info_blob;
|
||||
|
||||
data.BoardType= bdinfo->board_type;
|
||||
|
@ -74,7 +74,11 @@ int32_t FlightPlanStart()
|
||||
int32_t FlightPlanInitialize()
|
||||
{
|
||||
taskHandle = NULL;
|
||||
|
||||
|
||||
FlightPlanStatusInitialize();
|
||||
FlightPlanControlInitialize();
|
||||
FlightPlanSettingsInitialize();
|
||||
|
||||
// Listen for object updates
|
||||
FlightPlanControlConnectCallback(&objectUpdatedCb);
|
||||
|
||||
|
@ -124,6 +124,10 @@ int32_t GPSStart(void)
|
||||
*/
|
||||
int32_t GPSInitialize(void)
|
||||
{
|
||||
GPSPositionInitialize();
|
||||
GPSTimeInitialize();
|
||||
HomeLocationInitialize();
|
||||
|
||||
// TODO: Get gps settings object
|
||||
gpsPort = PIOS_COM_GPS;
|
||||
|
||||
|
@ -97,6 +97,14 @@ int32_t GuidanceStart()
|
||||
*/
|
||||
int32_t GuidanceInitialize()
|
||||
{
|
||||
|
||||
GuidanceSettingsInitialize();
|
||||
PositionDesiredInitialize();
|
||||
ManualControlCommandInitialize();
|
||||
FlightStatusInitialize();
|
||||
NedAccelInitialize();
|
||||
VelocityDesiredInitialize();
|
||||
|
||||
// Create object queue
|
||||
queue = xQueueCreate(MAX_QUEUE_SIZE, sizeof(UAVObjEvent));
|
||||
|
||||
|
@ -90,17 +90,15 @@ static bool validInputRange(int16_t min, int16_t max, uint16_t value);
|
||||
#define assumptions (assumptions1 && assumptions3 && assumptions5 && assumptions7 && assumptions8 && assumptions_flightmode)
|
||||
|
||||
/**
|
||||
* Module initialization
|
||||
* Module starting
|
||||
*/
|
||||
int32_t ManualControlStart()
|
||||
{
|
||||
/* Check the assumptions about uavobject enum's are correct */
|
||||
if(!assumptions)
|
||||
return -1;
|
||||
// Start main task
|
||||
xTaskCreate(manualControlTask, (signed char *)"ManualControl", STACK_SIZE_BYTES/4, NULL, TASK_PRIORITY, &taskHandle);
|
||||
TaskMonitorAdd(TASKINFO_RUNNING_MANUALCONTROL, taskHandle);
|
||||
PIOS_WDG_RegisterFlag(PIOS_WDG_MANUAL);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -110,6 +108,18 @@ int32_t ManualControlStart()
|
||||
int32_t ManualControlInitialize()
|
||||
{
|
||||
|
||||
/* Check the assumptions about uavobject enum's are correct */
|
||||
if(!assumptions)
|
||||
return -1;
|
||||
|
||||
AccessoryDesiredInitialize();
|
||||
ManualControlCommandInitialize();
|
||||
FlightStatusInitialize();
|
||||
StabilizationDesiredInitialize();
|
||||
|
||||
// ManualControlSettingsInitialize(); // this is initialized in
|
||||
// pios_board.c
|
||||
|
||||
return 0;
|
||||
}
|
||||
MODULE_INITCALL(ManualControlInitialize, ManualControlStart)
|
||||
@ -584,4 +594,3 @@ bool validInputRange(int16_t min, int16_t max, uint16_t value)
|
||||
* @}
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
@ -40,8 +40,6 @@
|
||||
#include "attitudeactual.h"
|
||||
#include "attituderaw.h"
|
||||
#include "flightstatus.h"
|
||||
#include "systemsettings.h"
|
||||
#include "ahrssettings.h"
|
||||
#include "manualcontrol.h" // Just to get a macro
|
||||
#include "CoordinateConversions.h"
|
||||
|
||||
@ -115,6 +113,11 @@ int32_t StabilizationStart()
|
||||
int32_t StabilizationInitialize()
|
||||
{
|
||||
// Initialize variables
|
||||
StabilizationSettingsInitialize();
|
||||
ActuatorDesiredInitialize();
|
||||
#if defined(DIAGNOSTICS)
|
||||
RateDesiredInitialize();
|
||||
#endif
|
||||
|
||||
// Create object queue
|
||||
queue = xQueueCreate(MAX_QUEUE_SIZE, sizeof(UAVObjEvent));
|
||||
@ -147,7 +150,6 @@ static void stabilizationTask(void* parameters)
|
||||
RateDesiredData rateDesired;
|
||||
AttitudeActualData attitudeActual;
|
||||
AttitudeRawData attitudeRaw;
|
||||
SystemSettingsData systemSettings;
|
||||
FlightStatusData flightStatus;
|
||||
|
||||
SettingsUpdatedCb((UAVObjEvent *) NULL);
|
||||
@ -175,8 +177,10 @@ static void stabilizationTask(void* parameters)
|
||||
StabilizationDesiredGet(&stabDesired);
|
||||
AttitudeActualGet(&attitudeActual);
|
||||
AttitudeRawGet(&attitudeRaw);
|
||||
|
||||
#if defined(DIAGNOSTICS)
|
||||
RateDesiredGet(&rateDesired);
|
||||
SystemSettingsGet(&systemSettings);
|
||||
#endif
|
||||
|
||||
#if defined(PIOS_QUATERNION_STABILIZATION)
|
||||
// Quaternion calculation of error in each axis. Uses more memory.
|
||||
@ -273,7 +277,9 @@ static void stabilizationTask(void* parameters)
|
||||
}
|
||||
|
||||
uint8_t shouldUpdate = 1;
|
||||
#if defined(DIAGNOSTICS)
|
||||
RateDesiredSet(&rateDesired);
|
||||
#endif
|
||||
ActuatorDesiredGet(&actuatorDesired);
|
||||
//Calculate desired command
|
||||
for(int8_t ct=0; ct< MAX_AXES; ct++)
|
||||
|
@ -43,7 +43,9 @@
|
||||
#include "objectpersistence.h"
|
||||
#include "flightstatus.h"
|
||||
#include "systemstats.h"
|
||||
#include "systemsettings.h"
|
||||
#include "i2cstats.h"
|
||||
#include "taskinfo.h"
|
||||
#include "watchdogstatus.h"
|
||||
#include "taskmonitor.h"
|
||||
#include "pios_config.h"
|
||||
@ -78,11 +80,12 @@ static int32_t stackOverflow;
|
||||
// Private functions
|
||||
static void objectUpdatedCb(UAVObjEvent * ev);
|
||||
static void updateStats();
|
||||
static void updateI2Cstats();
|
||||
static void updateWDGstats();
|
||||
static void updateSystemAlarms();
|
||||
static void systemTask(void *parameters);
|
||||
|
||||
#if defined(DIAGNOSTICS)
|
||||
static void updateI2Cstats();
|
||||
static void updateWDGstats();
|
||||
#endif
|
||||
/**
|
||||
* Create the module task.
|
||||
* \returns 0 on success or -1 if initialization failed
|
||||
@ -106,6 +109,16 @@ int32_t SystemModStart(void)
|
||||
int32_t SystemModInitialize(void)
|
||||
{
|
||||
|
||||
// Must registers objects here for system thread because ObjectManager started in OpenPilotInit
|
||||
SystemSettingsInitialize();
|
||||
SystemStatsInitialize();
|
||||
ObjectPersistenceInitialize();
|
||||
#if defined(DIAGNOSTICS)
|
||||
TaskInfoInitialize();
|
||||
I2CStatsInitialize();
|
||||
WatchdogStatusInitialize();
|
||||
#endif
|
||||
|
||||
SystemModStart();
|
||||
|
||||
return 0;
|
||||
@ -137,9 +150,10 @@ static void systemTask(void *parameters)
|
||||
|
||||
// Update the system alarms
|
||||
updateSystemAlarms();
|
||||
#if defined(DIAGNOSTICS)
|
||||
updateI2Cstats();
|
||||
updateWDGstats();
|
||||
|
||||
#endif
|
||||
// Update the task status object
|
||||
TaskMonitorUpdateAll();
|
||||
|
||||
@ -241,9 +255,7 @@ static void objectUpdatedCb(UAVObjEvent * ev)
|
||||
/**
|
||||
* Called periodically to update the I2C statistics
|
||||
*/
|
||||
#if defined(ARCH_POSIX) || defined(ARCH_WIN32)
|
||||
static void updateI2Cstats() {} //Posix and win32 don't have I2C
|
||||
#else
|
||||
#if defined(DIAGNOSTICS)
|
||||
static void updateI2Cstats()
|
||||
{
|
||||
#if defined(PIOS_INCLUDE_I2C)
|
||||
@ -263,7 +275,6 @@ static void updateI2Cstats()
|
||||
I2CStatsSet(&i2cStats);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
static void updateWDGstats()
|
||||
{
|
||||
@ -272,6 +283,8 @@ static void updateWDGstats()
|
||||
watchdogStatus.ActiveFlags = PIOS_WDG_GetActiveFlags();
|
||||
WatchdogStatusSet(&watchdogStatus);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/**
|
||||
* Called periodically to update the system stats
|
||||
|
@ -67,6 +67,7 @@ static uint32_t txErrors;
|
||||
static uint32_t txRetries;
|
||||
static TelemetrySettingsData settings;
|
||||
static uint32_t timeOfLastObjectUpdate;
|
||||
static UAVTalkConnection uavTalkCon;
|
||||
|
||||
// Private functions
|
||||
static void telemetryTxTask(void *parameters);
|
||||
@ -88,7 +89,13 @@ static void updateSettings();
|
||||
*/
|
||||
int32_t TelemetryStart(void)
|
||||
{
|
||||
|
||||
// Process all registered objects and connect queue for updates
|
||||
UAVObjIterate(®isterObject);
|
||||
|
||||
// Listen to objects of interest
|
||||
GCSTelemetryStatsConnectQueue(priorityQueue);
|
||||
TelemetrySettingsConnectQueue(priorityQueue);
|
||||
|
||||
// Start telemetry tasks
|
||||
xTaskCreate(telemetryTxTask, (signed char *)"TelTx", STACK_SIZE_BYTES/4, NULL, TASK_PRIORITY_TX, &telemetryTxTaskHandle);
|
||||
xTaskCreate(telemetryRxTask, (signed char *)"TelRx", STACK_SIZE_BYTES/4, NULL, TASK_PRIORITY_RX, &telemetryRxTaskHandle);
|
||||
@ -111,6 +118,10 @@ int32_t TelemetryStart(void)
|
||||
int32_t TelemetryInitialize(void)
|
||||
{
|
||||
UAVObjEvent ev;
|
||||
|
||||
FlightTelemetryStatsInitialize();
|
||||
GCSTelemetryStatsInitialize();
|
||||
TelemetrySettingsInitialize();
|
||||
|
||||
// Initialize vars
|
||||
timeOfLastObjectUpdate = 0;
|
||||
@ -120,25 +131,19 @@ int32_t TelemetryInitialize(void)
|
||||
#if defined(PIOS_TELEM_PRIORITY_QUEUE)
|
||||
priorityQueue = xQueueCreate(MAX_QUEUE_SIZE, sizeof(UAVObjEvent));
|
||||
#endif
|
||||
|
||||
// Get telemetry settings object
|
||||
|
||||
// Get telemetry settings object
|
||||
updateSettings();
|
||||
|
||||
|
||||
// Initialise UAVTalk
|
||||
UAVTalkInitialize(&transmitData);
|
||||
|
||||
// Process all registered objects and connect queue for updates
|
||||
UAVObjIterate(®isterObject);
|
||||
|
||||
uavTalkCon = UAVTalkInitialize(&transmitData,256);
|
||||
|
||||
// Create periodic event that will be used to update the telemetry stats
|
||||
txErrors = 0;
|
||||
txRetries = 0;
|
||||
memset(&ev, 0, sizeof(UAVObjEvent));
|
||||
EventPeriodicQueueCreate(&ev, priorityQueue, STATS_UPDATE_PERIOD_MS);
|
||||
|
||||
// Listen to objects of interest
|
||||
GCSTelemetryStatsConnectQueue(priorityQueue);
|
||||
TelemetrySettingsConnectQueue(priorityQueue);
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -235,7 +240,7 @@ static void processObjEvent(UAVObjEvent * ev)
|
||||
if (ev->event == EV_UPDATED || ev->event == EV_UPDATED_MANUAL) {
|
||||
// Send update to GCS (with retries)
|
||||
while (retries < MAX_RETRIES && success == -1) {
|
||||
success = UAVTalkSendObject(ev->obj, ev->instId, metadata.telemetryAcked, REQ_TIMEOUT_MS); // call blocks until ack is received or timeout
|
||||
success = UAVTalkSendObject(uavTalkCon, ev->obj, ev->instId, metadata.telemetryAcked, REQ_TIMEOUT_MS); // call blocks until ack is received or timeout
|
||||
++retries;
|
||||
}
|
||||
// Update stats
|
||||
@ -246,7 +251,7 @@ static void processObjEvent(UAVObjEvent * ev)
|
||||
} else if (ev->event == EV_UPDATE_REQ) {
|
||||
// Request object update from GCS (with retries)
|
||||
while (retries < MAX_RETRIES && success == -1) {
|
||||
success = UAVTalkSendObjectRequest(ev->obj, ev->instId, REQ_TIMEOUT_MS); // call blocks until update is received or timeout
|
||||
success = UAVTalkSendObjectRequest(uavTalkCon, ev->obj, ev->instId, REQ_TIMEOUT_MS); // call blocks until update is received or timeout
|
||||
++retries;
|
||||
}
|
||||
// Update stats
|
||||
@ -326,7 +331,7 @@ static void telemetryRxTask(void *parameters)
|
||||
bytes_to_process = PIOS_COM_ReceiveBuffer(inputPort, serial_data, sizeof(serial_data), 500);
|
||||
if (bytes_to_process > 0) {
|
||||
for (uint8_t i = 0; i < bytes_to_process; i++) {
|
||||
UAVTalkProcessInputStream(serial_data[i]);
|
||||
UAVTalkProcessInputStream(uavTalkCon,serial_data[i]);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@ -426,8 +431,8 @@ static void updateTelemetryStats()
|
||||
uint32_t timeNow;
|
||||
|
||||
// Get stats
|
||||
UAVTalkGetStats(&utalkStats);
|
||||
UAVTalkResetStats();
|
||||
UAVTalkGetStats(uavTalkCon, &utalkStats);
|
||||
UAVTalkResetStats(uavTalkCon);
|
||||
|
||||
// Get object data
|
||||
FlightTelemetryStatsGet(&flightStats);
|
||||
|
@ -135,7 +135,6 @@ SRC += $(OPSYSTEM)/taskmonitor.c
|
||||
SRC += $(OPUAVTALK)/uavtalk.c
|
||||
SRC += $(OPUAVOBJ)/uavobjectmanager.c
|
||||
SRC += $(OPUAVOBJ)/eventdispatcher.c
|
||||
SRC += $(OPUAVOBJ)/uavobjectsinit_linker.c
|
||||
else
|
||||
## TESTCODE
|
||||
SRC += $(OPTESTS)/test_common.c
|
||||
@ -388,6 +387,9 @@ ifeq ($(DEBUG),YES)
|
||||
CFLAGS = -g$(DEBUGF) -DDEBUG
|
||||
endif
|
||||
|
||||
# OP has enough memory to always enable optional objects
|
||||
CFLAGS += -DDIAGNOSTICS
|
||||
|
||||
CFLAGS += -O$(OPT)
|
||||
CFLAGS += -mcpu=$(MCU)
|
||||
CFLAGS += $(CDEFS)
|
||||
|
@ -165,6 +165,7 @@ endif
|
||||
SRC += $(PIOSPOSIX)/pios_crc.c
|
||||
SRC += $(PIOSPOSIX)/pios_sys.c
|
||||
SRC += $(PIOSPOSIX)/pios_led.c
|
||||
SRC += $(PIOSPOSIX)/pios_irq.c
|
||||
SRC += $(PIOSPOSIX)/pios_delay.c
|
||||
SRC += $(PIOSPOSIX)/pios_sdcard.c
|
||||
SRC += $(PIOSPOSIX)/pios_udp.c
|
||||
@ -176,7 +177,7 @@ SRC += $(PIOSPOSIX)/pios_debug.c
|
||||
SRC += $(PIOSPOSIX)/pios_rcvr.c
|
||||
|
||||
## Libraries for flight calculations
|
||||
#SRC += $(FLIGHTLIB)/fifo_buffer.c
|
||||
SRC += $(FLIGHTLIB)/fifo_buffer.c
|
||||
SRC += $(FLIGHTLIB)/WorldMagModel.c
|
||||
SRC += $(FLIGHTLIB)/CoordinateConversions.c
|
||||
## RTOS and RTOS Portable
|
||||
|
@ -41,14 +41,12 @@ static xSemaphoreHandle lock;
|
||||
static int32_t hasSeverity(SystemAlarmsAlarmOptions severity);
|
||||
|
||||
/**
|
||||
* Initialize the alarms library
|
||||
* Initialize the alarms library
|
||||
*/
|
||||
int32_t AlarmsInitialize(void)
|
||||
{
|
||||
SystemAlarmsInitialize();
|
||||
lock = xSemaphoreCreateRecursiveMutex();
|
||||
//do not change the default states of the alarms, let the init code generated by the uavobjectgenerator handle that
|
||||
//AlarmsClearAll();
|
||||
//AlarmsDefaultAll();
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -56,7 +54,7 @@ int32_t AlarmsInitialize(void)
|
||||
* Set an alarm
|
||||
* @param alarm The system alarm to be modified
|
||||
* @param severity The alarm severity
|
||||
* @return 0 if success, -1 if an error
|
||||
* @return 0 if success, -1 if an error
|
||||
*/
|
||||
int32_t AlarmsSet(SystemAlarmsAlarmElem alarm, SystemAlarmsAlarmOptions severity)
|
||||
{
|
||||
@ -151,7 +149,7 @@ void AlarmsClearAll()
|
||||
|
||||
/**
|
||||
* Check if there are any alarms with the given or higher severity
|
||||
* @return 0 if no alarms are found, 1 if at least one alarm is found
|
||||
* @return 0 if no alarms are found, 1 if at least one alarm is found
|
||||
*/
|
||||
int32_t AlarmsHasWarnings()
|
||||
{
|
||||
@ -208,5 +206,5 @@ static int32_t hasSeverity(SystemAlarmsAlarmOptions severity)
|
||||
/**
|
||||
* @}
|
||||
* @}
|
||||
*/
|
||||
*/
|
||||
|
||||
|
@ -39,7 +39,7 @@
|
||||
#define configUSE_RECURSIVE_MUTEXES 1
|
||||
#define configUSE_COUNTING_SEMAPHORES 0
|
||||
#define configUSE_ALTERNATIVE_API 0
|
||||
#define configCHECK_FOR_STACK_OVERFLOW 2
|
||||
//#define configCHECK_FOR_STACK_OVERFLOW 2
|
||||
#define configQUEUE_REGISTRY_SIZE 10
|
||||
|
||||
/* Co-routine definitions. */
|
||||
@ -72,7 +72,9 @@ NVIC value of 255. */
|
||||
#define configLIBRARY_KERNEL_INTERRUPT_PRIORITY 15
|
||||
|
||||
/* Enable run time stats collection */
|
||||
#if defined(DEBUG)
|
||||
#if defined(DIAGNOSTICS)
|
||||
#define configCHECK_FOR_STACK_OVERFLOW 2
|
||||
|
||||
#define configGENERATE_RUN_TIME_STATS 1
|
||||
#define INCLUDE_uxTaskGetRunTime 1
|
||||
#define portCONFIGURE_TIMER_FOR_RUN_TIME_STATS()\
|
||||
@ -81,6 +83,8 @@ do {\
|
||||
(*(unsigned long *)0xe0001000) |= 1; /* DWT_CTRL |= DWT_CYCCNT_ENA */\
|
||||
} while(0)
|
||||
#define portGET_RUN_TIME_COUNTER_VALUE() (*(unsigned long *)0xe0001004)/* DWT_CYCCNT */
|
||||
#else
|
||||
#define configCHECK_FOR_STACK_OVERFLOW 1
|
||||
#endif
|
||||
|
||||
#if !defined(ARCH_POSIX) && !defined(ARCH_WIN32)
|
||||
|
@ -52,15 +52,22 @@
|
||||
//-------------------------
|
||||
//#define PIOS_USART_TX_BUFFER_SIZE 256
|
||||
#define PIOS_COM_BUFFER_SIZE 1024
|
||||
#define PIOS_COM_MAX_DEVS 256
|
||||
#define PIOS_UDP_RX_BUFFER_SIZE PIOS_COM_BUFFER_SIZE
|
||||
|
||||
#define PIOS_COM_TELEM_RF 0
|
||||
#define PIOS_COM_GPS 1
|
||||
#define PIOS_COM_TELEM_USB 2
|
||||
extern uint32_t pios_com_telem_rf_id;
|
||||
extern uint32_t pios_com_telem_usb_id;
|
||||
extern uint32_t pios_com_gps_id;
|
||||
extern uint32_t pios_com_aux_id;
|
||||
extern uint32_t pios_com_spectrum_id;
|
||||
|
||||
#define PIOS_COM_TELEM_RF (pios_com_telem_rf_id)
|
||||
#define PIOS_COM_TELEM_USB (pios_com_telem_usb_id)
|
||||
#define PIOS_COM_GPS (pios_com_gps_id)
|
||||
|
||||
#ifdef PIOS_ENABLE_AUX_UART
|
||||
#define PIOS_COM_AUX 3
|
||||
#define PIOS_COM_DEBUG PIOS_COM_AUX
|
||||
#define PIOS_COM_AUX (pios_com_aux_id)
|
||||
#define PIOS_COM_DEBUG (PIOS_COM_AUX
|
||||
#endif
|
||||
|
||||
/**
|
||||
|
@ -36,6 +36,9 @@
|
||||
#define PIOS_INCLUDE_SDCARD
|
||||
#define PIOS_INCLUDE_FREERTOS
|
||||
#define PIOS_INCLUDE_COM
|
||||
#define PIOS_INCLUDE_GPS
|
||||
#define PIOS_INCLUDE_IRQ
|
||||
#define PIOS_INCLUDE_TELEMETRY_RF
|
||||
#define PIOS_INCLUDE_UDP
|
||||
#define PIOS_INCLUDE_SERVO
|
||||
#define PIOS_INCLUDE_RCVR
|
||||
|
@ -1023,7 +1023,6 @@ void PIOS_Board_Init(void) {
|
||||
/* Initialize UAVObject libraries */
|
||||
EventDispatcherInitialize();
|
||||
UAVObjInitialize();
|
||||
UAVObjectsInitializeAll();
|
||||
|
||||
#if defined(PIOS_INCLUDE_RTC)
|
||||
/* Initialize the real-time clock and its associated tick */
|
||||
|
@ -29,6 +29,10 @@
|
||||
#include <openpilot.h>
|
||||
#include <uavobjectsinit.h>
|
||||
|
||||
#include "attituderaw.h"
|
||||
#include "positionactual.h"
|
||||
#include "velocityactual.h"
|
||||
|
||||
#include "pios_rcvr_priv.h"
|
||||
|
||||
struct pios_rcvr_channel_map pios_rcvr_channel_to_id_map[PIOS_RCVR_MAX_CHANNELS];
|
||||
@ -40,42 +44,16 @@ void Stack_Change() {
|
||||
void Stack_Change_Weak() {
|
||||
}
|
||||
|
||||
/**
|
||||
* PIOS_Board_Init()
|
||||
* initializes all the core systems on this specific hardware
|
||||
* called from System/openpilot.c
|
||||
*/
|
||||
void PIOS_Board_Init(void) {
|
||||
|
||||
/* Delay system */
|
||||
PIOS_DELAY_Init();
|
||||
|
||||
/* Initialize UAVObject libraries */
|
||||
EventDispatcherInitialize();
|
||||
UAVObjInitialize();
|
||||
UAVObjectsInitializeAll();
|
||||
|
||||
/* Initialize the alarms library */
|
||||
AlarmsInitialize();
|
||||
|
||||
/* Initialize the task monitor library */
|
||||
TaskMonitorInitialize();
|
||||
|
||||
/* Initialize the PiOS library */
|
||||
PIOS_COM_Init();
|
||||
|
||||
}
|
||||
|
||||
|
||||
const struct pios_udp_cfg pios_udp0_cfg = {
|
||||
const struct pios_udp_cfg pios_udp_telem_cfg = {
|
||||
.ip = "0.0.0.0",
|
||||
.port = 9000,
|
||||
};
|
||||
const struct pios_udp_cfg pios_udp1_cfg = {
|
||||
const struct pios_udp_cfg pios_udp_gps_cfg = {
|
||||
.ip = "0.0.0.0",
|
||||
.port = 9001,
|
||||
};
|
||||
const struct pios_udp_cfg pios_udp2_cfg = {
|
||||
const struct pios_udp_cfg pios_udp_debug_cfg = {
|
||||
.ip = "0.0.0.0",
|
||||
.port = 9002,
|
||||
};
|
||||
@ -84,15 +62,20 @@ const struct pios_udp_cfg pios_udp2_cfg = {
|
||||
/*
|
||||
* AUX USART
|
||||
*/
|
||||
const struct pios_udp_cfg pios_udp3_cfg = {
|
||||
const struct pios_udp_cfg pios_udp_aux_cfg = {
|
||||
.ip = "0.0.0.0",
|
||||
.port = 9003,
|
||||
};
|
||||
#endif
|
||||
|
||||
#define PIOS_COM_TELEM_RF_RX_BUF_LEN 192
|
||||
#define PIOS_COM_TELEM_RF_TX_BUF_LEN 192
|
||||
#define PIOS_COM_GPS_RX_BUF_LEN 192
|
||||
|
||||
/*
|
||||
* Board specific number of devices.
|
||||
*/
|
||||
/*
|
||||
struct pios_udp_dev pios_udp_devs[] = {
|
||||
#define PIOS_UDP_TELEM 0
|
||||
{
|
||||
@ -115,7 +98,7 @@ struct pios_udp_dev pios_udp_devs[] = {
|
||||
};
|
||||
|
||||
uint8_t pios_udp_num_devices = NELEMENTS(pios_udp_devs);
|
||||
|
||||
*/
|
||||
/*
|
||||
* COM devices
|
||||
*/
|
||||
@ -126,28 +109,78 @@ uint8_t pios_udp_num_devices = NELEMENTS(pios_udp_devs);
|
||||
extern const struct pios_com_driver pios_serial_com_driver;
|
||||
extern const struct pios_com_driver pios_udp_com_driver;
|
||||
|
||||
struct pios_com_dev pios_com_devs[] = {
|
||||
{
|
||||
.id = PIOS_UDP_TELEM,
|
||||
.driver = &pios_udp_com_driver,
|
||||
},
|
||||
{
|
||||
.id = PIOS_UDP_GPS,
|
||||
.driver = &pios_udp_com_driver,
|
||||
},
|
||||
{
|
||||
.id = PIOS_UDP_LOCAL,
|
||||
.driver = &pios_udp_com_driver,
|
||||
},
|
||||
#ifdef PIOS_COM_AUX
|
||||
{
|
||||
.id = PIOS_UDP_AUX,
|
||||
.driver = &pios_udp_com_driver,
|
||||
},
|
||||
#endif
|
||||
};
|
||||
uint32_t pios_com_telem_rf_id;
|
||||
uint32_t pios_com_telem_usb_id;
|
||||
uint32_t pios_com_gps_id;
|
||||
uint32_t pios_com_aux_id;
|
||||
uint32_t pios_com_spectrum_id;
|
||||
|
||||
const uint8_t pios_com_num_devices = NELEMENTS(pios_com_devs);
|
||||
/**
|
||||
* PIOS_Board_Init()
|
||||
* initializes all the core systems on this specific hardware
|
||||
* called from System/openpilot.c
|
||||
*/
|
||||
void PIOS_Board_Init(void) {
|
||||
|
||||
/* Delay system */
|
||||
PIOS_DELAY_Init();
|
||||
|
||||
/* Initialize UAVObject libraries */
|
||||
EventDispatcherInitialize();
|
||||
UAVObjInitialize();
|
||||
UAVObjectsInitializeAll();
|
||||
|
||||
/* Initialize the alarms library */
|
||||
AlarmsInitialize();
|
||||
|
||||
/* Initialize the task monitor library */
|
||||
TaskMonitorInitialize();
|
||||
|
||||
#if defined(PIOS_INCLUDE_COM)
|
||||
#if defined(PIOS_INCLUDE_TELEMETRY_RF)
|
||||
{
|
||||
uint32_t pios_udp_telem_rf_id;
|
||||
if (PIOS_UDP_Init(&pios_udp_telem_rf_id, &pios_udp_telem_cfg)) {
|
||||
PIOS_Assert(0);
|
||||
}
|
||||
|
||||
uint8_t * rx_buffer = (uint8_t *) pvPortMalloc(PIOS_COM_TELEM_RF_RX_BUF_LEN);
|
||||
uint8_t * tx_buffer = (uint8_t *) pvPortMalloc(PIOS_COM_TELEM_RF_TX_BUF_LEN);
|
||||
PIOS_Assert(rx_buffer);
|
||||
PIOS_Assert(tx_buffer);
|
||||
if (PIOS_COM_Init(&pios_com_telem_rf_id, &pios_udp_com_driver, pios_udp_telem_rf_id,
|
||||
rx_buffer, PIOS_COM_TELEM_RF_RX_BUF_LEN,
|
||||
tx_buffer, PIOS_COM_TELEM_RF_TX_BUF_LEN)) {
|
||||
PIOS_Assert(0);
|
||||
}
|
||||
}
|
||||
#endif /* PIOS_INCLUDE_TELEMETRY_RF */
|
||||
|
||||
#if defined(PIOS_INCLUDE_GPS)
|
||||
{
|
||||
uint32_t pios_udp_gps_id;
|
||||
if (PIOS_UDP_Init(&pios_udp_gps_id, &pios_udp_gps_cfg)) {
|
||||
PIOS_Assert(0);
|
||||
}
|
||||
uint8_t * rx_buffer = (uint8_t *) pvPortMalloc(PIOS_COM_GPS_RX_BUF_LEN);
|
||||
uint8_t * tx_buffer = (uint8_t *) pvPortMalloc(PIOS_COM_GPS_RX_BUF_LEN);
|
||||
PIOS_Assert(rx_buffer);
|
||||
PIOS_Assert(tx_buffer);
|
||||
if (PIOS_COM_Init(&pios_com_gps_id, &pios_udp_com_driver, pios_udp_gps_id,
|
||||
rx_buffer, PIOS_COM_GPS_RX_BUF_LEN,
|
||||
tx_buffer, PIOS_COM_GPS_RX_BUF_LEN)) {
|
||||
PIOS_Assert(0);
|
||||
}
|
||||
}
|
||||
#endif /* PIOS_INCLUDE_GPS */
|
||||
#endif
|
||||
|
||||
// Initialize these here as posix has no AHRSComms
|
||||
AttitudeRawInitialize();
|
||||
VelocityActualInitialize();
|
||||
PositionActualInitialize();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @}
|
||||
|
@ -46,7 +46,10 @@ int32_t TaskMonitorInitialize(void)
|
||||
{
|
||||
lock = xSemaphoreCreateRecursiveMutex();
|
||||
memset(handles, 0, sizeof(xTaskHandle)*TASKINFO_RUNNING_NUMELEM);
|
||||
lastMonitorTime = 0;
|
||||
#if defined(DIAGNOSTICS)
|
||||
lastMonitorTime = portGET_RUN_TIME_COUNTER_VALUE();
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -91,6 +94,7 @@ int32_t TaskMonitorRemove(TaskInfoRunningElem task)
|
||||
*/
|
||||
void TaskMonitorUpdateAll(void)
|
||||
{
|
||||
#if defined(DIAGNOSTICS)
|
||||
TaskInfoData data;
|
||||
int n;
|
||||
|
||||
@ -142,4 +146,5 @@ void TaskMonitorUpdateAll(void)
|
||||
|
||||
// Done
|
||||
xSemaphoreGiveRecursive(lock);
|
||||
#endif
|
||||
}
|
||||
|
@ -69,6 +69,8 @@ UAVOBJSRCFILENAMES += velocityactual
|
||||
UAVOBJSRCFILENAMES += velocitydesired
|
||||
UAVOBJSRCFILENAMES += watchdogstatus
|
||||
UAVOBJSRCFILENAMES += flightstatus
|
||||
UAVOBJSRCFILENAMES += cameradesired
|
||||
UAVOBJSRCFILENAMES += camerastabsettings
|
||||
|
||||
UAVOBJSRC = $(foreach UAVOBJSRCFILE,$(UAVOBJSRCFILENAMES),$(UAVOBJSYNTHDIR)/$(UAVOBJSRCFILE).c )
|
||||
UAVOBJDEFINE = $(foreach UAVOBJSRCFILE,$(UAVOBJSRCFILENAMES),-DUAVOBJ_INIT_$(UAVOBJSRCFILE) )
|
||||
|
@ -1,55 +1,65 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
*
|
||||
* @file pios_com.h
|
||||
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
|
||||
* Parts by Thorsten Klose (tk@midibox.org)
|
||||
* @brief COM 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_COM_H
|
||||
#define PIOS_COM_H
|
||||
|
||||
/* Public Functions */
|
||||
extern int32_t PIOS_COM_Init(void);
|
||||
extern int32_t PIOS_COM_ChangeBaud(uint8_t port, uint32_t baud);
|
||||
extern int32_t PIOS_COM_SendCharNonBlocking(uint8_t port, char c);
|
||||
extern int32_t PIOS_COM_SendChar(uint8_t port, char c);
|
||||
extern int32_t PIOS_COM_SendBufferNonBlocking(uint8_t port, uint8_t *buffer, uint16_t len);
|
||||
extern int32_t PIOS_COM_SendBuffer(uint8_t port, uint8_t *buffer, uint16_t len);
|
||||
extern int32_t PIOS_COM_SendStringNonBlocking(uint8_t port, char *str);
|
||||
extern int32_t PIOS_COM_SendString(uint8_t port, char *str);
|
||||
extern int32_t PIOS_COM_SendFormattedStringNonBlocking(uint8_t port, char *format, ...);
|
||||
extern int32_t PIOS_COM_SendFormattedString(uint8_t port, char *format, ...);
|
||||
extern uint8_t PIOS_COM_ReceiveBuffer(uint8_t port);
|
||||
extern int32_t PIOS_COM_ReceiveBufferUsed(uint8_t port);
|
||||
|
||||
extern int32_t PIOS_COM_ReceiveHandler(void);
|
||||
|
||||
struct pios_com_driver {
|
||||
void (*init)(uint8_t id);
|
||||
void (*set_baud)(uint8_t id, uint32_t baud);
|
||||
int32_t (*tx_nb)(uint8_t id, uint8_t *buffer, uint16_t len);
|
||||
int32_t (*tx)(uint8_t id, uint8_t *buffer, uint16_t len);
|
||||
int32_t (*rx)(uint8_t id);
|
||||
int32_t (*rx_avail)(uint8_t id);
|
||||
};
|
||||
|
||||
#endif /* PIOS_COM_H */
|
||||
/**
|
||||
******************************************************************************
|
||||
* @addtogroup PIOS PIOS Core hardware abstraction layer
|
||||
* @{
|
||||
* @addtogroup PIOS_COM COM layer functions
|
||||
* @brief Hardware communication layer
|
||||
* @{
|
||||
*
|
||||
* @file pios_com.h
|
||||
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
|
||||
* Parts by Thorsten Klose (tk@midibox.org)
|
||||
* @brief COM 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_COM_H
|
||||
#define PIOS_COM_H
|
||||
|
||||
typedef uint16_t (*pios_com_callback)(uint32_t context, uint8_t * buf, uint16_t buf_len, uint16_t * headroom, bool * task_woken);
|
||||
|
||||
struct pios_com_driver {
|
||||
void (*init)(uint32_t id);
|
||||
void (*set_baud)(uint32_t id, uint32_t baud);
|
||||
void (*tx_start)(uint32_t id, uint16_t tx_bytes_avail);
|
||||
void (*rx_start)(uint32_t id, uint16_t rx_bytes_avail);
|
||||
void (*bind_rx_cb)(uint32_t id, pios_com_callback rx_in_cb, uint32_t context);
|
||||
void (*bind_tx_cb)(uint32_t id, pios_com_callback tx_out_cb, uint32_t context);
|
||||
};
|
||||
|
||||
/* Public Functions */
|
||||
extern int32_t PIOS_COM_Init(uint32_t * com_id, const struct pios_com_driver * driver, uint32_t lower_id, uint8_t * rx_buffer, uint16_t rx_buffer_len, uint8_t * tx_buffer, uint16_t tx_buffer_len);
|
||||
extern int32_t PIOS_COM_ChangeBaud(uint32_t com_id, uint32_t baud);
|
||||
extern int32_t PIOS_COM_SendCharNonBlocking(uint32_t com_id, char c);
|
||||
extern int32_t PIOS_COM_SendChar(uint32_t com_id, char c);
|
||||
extern int32_t PIOS_COM_SendBufferNonBlocking(uint32_t com_id, const uint8_t *buffer, uint16_t len);
|
||||
extern int32_t PIOS_COM_SendBuffer(uint32_t com_id, const uint8_t *buffer, uint16_t len);
|
||||
extern int32_t PIOS_COM_SendStringNonBlocking(uint32_t com_id, const char *str);
|
||||
extern int32_t PIOS_COM_SendString(uint32_t com_id, const char *str);
|
||||
extern int32_t PIOS_COM_SendFormattedStringNonBlocking(uint32_t com_id, const char *format, ...);
|
||||
extern int32_t PIOS_COM_SendFormattedString(uint32_t com_id, const char *format, ...);
|
||||
extern uint16_t PIOS_COM_ReceiveBuffer(uint32_t com_id, uint8_t * buf, uint16_t buf_len, uint32_t timeout_ms);
|
||||
extern int32_t PIOS_COM_ReceiveBufferUsed(uint32_t com_id);
|
||||
|
||||
#endif /* PIOS_COM_H */
|
||||
|
||||
/**
|
||||
* @}
|
||||
* @}
|
||||
*/
|
||||
|
@ -1,5 +1,10 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @addtogroup PIOS PIOS Core hardware abstraction layer
|
||||
* @{
|
||||
* @addtogroup PIOS_COM COM layer functions
|
||||
* @brief Hardware communication layer
|
||||
* @{
|
||||
*
|
||||
* @file pios_com_priv.h
|
||||
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
|
||||
@ -29,13 +34,11 @@
|
||||
|
||||
#include <pios.h>
|
||||
|
||||
struct pios_com_dev {
|
||||
uint8_t id;
|
||||
const struct pios_com_driver * const driver;
|
||||
};
|
||||
|
||||
extern struct pios_com_dev pios_com_devs[];
|
||||
extern const uint8_t pios_com_num_devices;
|
||||
extern int32_t PIOS_COM_ReceiveHandler(uint32_t com_id);
|
||||
|
||||
#endif /* PIOS_COM_PRIV_H */
|
||||
|
||||
/**
|
||||
* @}
|
||||
* @}
|
||||
*/
|
||||
|
@ -51,7 +51,6 @@ extern initmodule_t __module_initcall_start[], __module_initcall_end[];
|
||||
extern void InitModules();
|
||||
extern void StartModules();
|
||||
|
||||
#define UAVOBJ_INITCALL(fn)
|
||||
#define MODULE_INITCALL(ifn, sfn)
|
||||
|
||||
#define MODULE_TASKCREATE_ALL { \
|
||||
|
38
flight/PiOS.posix/inc/pios_irq.h
Normal file
38
flight/PiOS.posix/inc/pios_irq.h
Normal file
@ -0,0 +1,38 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @addtogroup PIOS PIOS Core hardware abstraction layer
|
||||
* @{
|
||||
* @addtogroup PIOS_IRQ IRQ Setup Functions
|
||||
* @{
|
||||
*
|
||||
* @file pios_irq.h
|
||||
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
|
||||
* Parts by Thorsten Klose (tk@midibox.org)
|
||||
* @brief IRQ 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_IRQ_H
|
||||
#define PIOS_IRQ_H
|
||||
|
||||
/* Public Functions */
|
||||
extern int32_t PIOS_IRQ_Disable(void);
|
||||
extern int32_t PIOS_IRQ_Enable(void);
|
||||
|
||||
#endif /* PIOS_IRQ_H */
|
@ -31,21 +31,5 @@
|
||||
/* Global Types */
|
||||
|
||||
/* Public Functions */
|
||||
//extern void PIOS_UDP_Init(void);
|
||||
void PIOS_UDP_Init(void);
|
||||
extern void PIOS_UDP_ChangeBaud(uint8_t usart, uint32_t baud);
|
||||
|
||||
extern int32_t PIOS_UDP_RxBufferFree(uint8_t usart);
|
||||
extern int32_t PIOS_UDP_RxBufferUsed(uint8_t usart);
|
||||
extern int32_t PIOS_UDP_RxBufferGet(uint8_t usart);
|
||||
extern int32_t PIOS_UDP_RxBufferPeek(uint8_t usart);
|
||||
extern int32_t PIOS_UDP_RxBufferPut(uint8_t usart, uint8_t b);
|
||||
|
||||
extern int32_t PIOS_UDP_TxBufferFree(uint8_t usart);
|
||||
extern int32_t PIOS_UDP_TxBufferGet(uint8_t usart);
|
||||
extern int32_t PIOS_UDP_TxBufferPutMoreNonBlocking(uint8_t usart, uint8_t *buffer, uint16_t len);
|
||||
extern int32_t PIOS_UDP_TxBufferPutMore(uint8_t usart, uint8_t *buffer, uint16_t len);
|
||||
extern int32_t PIOS_UDP_TxBufferPutNonBlocking(uint8_t usart, uint8_t b);
|
||||
extern int32_t PIOS_UDP_TxBufferPut(uint8_t usart, uint8_t b);
|
||||
|
||||
#endif /* PIOS_UDP_H */
|
||||
|
@ -29,6 +29,7 @@
|
||||
|
||||
#include <pios.h>
|
||||
#include <stdio.h>
|
||||
#include <pthread.h>
|
||||
#include <sys/socket.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <stdlib.h>
|
||||
@ -37,30 +38,34 @@
|
||||
#include <fcntl.h>
|
||||
#include <netinet/in.h>
|
||||
|
||||
|
||||
|
||||
struct pios_udp_cfg {
|
||||
const char * ip;
|
||||
uint16_t port;
|
||||
};
|
||||
|
||||
struct pios_udp_buffer {
|
||||
uint8_t buf[PIOS_UDP_RX_BUFFER_SIZE];
|
||||
uint16_t head;
|
||||
uint16_t tail;
|
||||
uint16_t size;
|
||||
};
|
||||
typedef struct {
|
||||
const struct pios_udp_cfg * cfg;
|
||||
pthread_t rxThread;
|
||||
|
||||
struct pios_udp_dev {
|
||||
const struct pios_udp_cfg * const cfg;
|
||||
struct pios_udp_buffer rx;
|
||||
int socket;
|
||||
struct sockaddr_in server;
|
||||
struct sockaddr_in client;
|
||||
uint32_t clientLength;
|
||||
};
|
||||
|
||||
extern struct pios_udp_dev pios_udp_devs[];
|
||||
extern uint8_t pios_udp_num_devices;
|
||||
pthread_cond_t cond;
|
||||
pthread_mutex_t mutex;
|
||||
|
||||
pios_com_callback tx_out_cb;
|
||||
uint32_t tx_out_context;
|
||||
pios_com_callback rx_in_cb;
|
||||
uint32_t rx_in_context;
|
||||
|
||||
uint8_t rx_buffer[PIOS_UDP_RX_BUFFER_SIZE];
|
||||
uint8_t tx_buffer[PIOS_UDP_RX_BUFFER_SIZE];
|
||||
} pios_udp_dev;
|
||||
|
||||
extern int32_t PIOS_UDP_Init(uint32_t * udp_id, const struct pios_udp_cfg * cfg);
|
||||
|
||||
|
||||
|
||||
#endif /* PIOS_UDP_PRIV_H */
|
||||
|
@ -58,6 +58,7 @@
|
||||
#include <pios_sys.h>
|
||||
#include <pios_delay.h>
|
||||
#include <pios_led.h>
|
||||
#include <pios_irq.h>
|
||||
#include <pios_sdcard.h>
|
||||
#include <pios_udp.h>
|
||||
#include <pios_com.h>
|
||||
|
@ -1,285 +1,522 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
*
|
||||
* @file pios_com.c
|
||||
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
|
||||
* Parts by Thorsten Klose (tk@midibox.org)
|
||||
* @brief COM layer functions
|
||||
* @see The GNU Public License (GPL) Version 3
|
||||
* @defgroup PIOS_COM COM layer functions
|
||||
* @{
|
||||
*
|
||||
*****************************************************************************/
|
||||
/*
|
||||
* 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 */
|
||||
/**
|
||||
******************************************************************************
|
||||
* @addtogroup PIOS PIOS Core hardware abstraction layer
|
||||
* @{
|
||||
* @addtogroup PIOS_COM COM layer functions
|
||||
* @brief Hardware communication layer
|
||||
* @{
|
||||
*
|
||||
* @file pios_com.c
|
||||
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
|
||||
* Parts by Thorsten Klose (tk@midibox.org)
|
||||
* @brief COM layer functions
|
||||
* @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"
|
||||
|
||||
#if defined(PIOS_INCLUDE_COM)
|
||||
|
||||
#include "fifo_buffer.h"
|
||||
#include <pios_com_priv.h>
|
||||
|
||||
static struct pios_com_dev * find_com_dev_by_id (uint8_t port)
|
||||
{
|
||||
if (port >= pios_com_num_devices) {
|
||||
/* Undefined COM port for this board (see pios_board.c) */
|
||||
return NULL;
|
||||
}
|
||||
#if !defined(PIOS_INCLUDE_FREERTOS)
|
||||
#include "pios_delay.h" /* PIOS_DELAY_WaitmS */
|
||||
#endif
|
||||
|
||||
/* Get a handle for the device configuration */
|
||||
return &(pios_com_devs[port]);
|
||||
enum pios_com_dev_magic {
|
||||
PIOS_COM_DEV_MAGIC = 0xaa55aa55,
|
||||
};
|
||||
|
||||
struct pios_com_dev {
|
||||
enum pios_com_dev_magic magic;
|
||||
uint32_t lower_id;
|
||||
const struct pios_com_driver * driver;
|
||||
|
||||
#if defined(PIOS_INCLUDE_FREERTOS)
|
||||
xSemaphoreHandle tx_sem;
|
||||
xSemaphoreHandle rx_sem;
|
||||
#endif
|
||||
|
||||
bool has_rx;
|
||||
bool has_tx;
|
||||
|
||||
t_fifo_buffer rx;
|
||||
t_fifo_buffer tx;
|
||||
};
|
||||
|
||||
static bool PIOS_COM_validate(struct pios_com_dev * com_dev)
|
||||
{
|
||||
return (com_dev && (com_dev->magic == PIOS_COM_DEV_MAGIC));
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialises COM layer
|
||||
* \param[in] mode currently only mode 0 supported
|
||||
* \return < 0 if initialisation failed
|
||||
*/
|
||||
int32_t PIOS_COM_Init(void)
|
||||
{
|
||||
int32_t ret = 0;
|
||||
|
||||
/* If any COM assignment: */
|
||||
#if defined(PIOS_INCLUDE_SERIAL)
|
||||
PIOS_SERIAL_Init();
|
||||
#endif
|
||||
|
||||
#if defined(PIOS_INCLUDE_UDP)
|
||||
PIOS_UDP_Init();
|
||||
#endif
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Change the port speed without re-initializing
|
||||
* \param[in] port COM port
|
||||
* \param[in] baud Requested baud rate
|
||||
* \return -1 if port not available
|
||||
* \return 0 on success
|
||||
*/
|
||||
int32_t PIOS_COM_ChangeBaud(uint8_t port, uint32_t baud)
|
||||
#if defined(PIOS_INCLUDE_FREERTOS) && 0
|
||||
// static struct pios_com_dev * PIOS_COM_alloc(void)
|
||||
//{
|
||||
// struct pios_com_dev * com_dev;
|
||||
//
|
||||
// com_dev = (struct pios_com_dev *)malloc(sizeof(*com_dev));
|
||||
// if (!com_dev) return (NULL);
|
||||
//
|
||||
// com_dev->magic = PIOS_COM_DEV_MAGIC;
|
||||
// return(com_dev);
|
||||
//}
|
||||
#else
|
||||
static struct pios_com_dev pios_com_devs[PIOS_COM_MAX_DEVS];
|
||||
static uint8_t pios_com_num_devs;
|
||||
static uint32_t PIOS_COM_create(void)
|
||||
{
|
||||
struct pios_com_dev * com_dev;
|
||||
struct pios_com_dev * com_dev;
|
||||
|
||||
com_dev = find_com_dev_by_id (port);
|
||||
if (pios_com_num_devs >= PIOS_COM_MAX_DEVS) {
|
||||
return (PIOS_COM_MAX_DEVS+1);
|
||||
}
|
||||
|
||||
if (!com_dev) {
|
||||
/* Undefined COM port for this board (see pios_board.c) */
|
||||
return -1;
|
||||
}
|
||||
com_dev = &pios_com_devs[pios_com_num_devs++];
|
||||
com_dev->magic = PIOS_COM_DEV_MAGIC;
|
||||
|
||||
/* Invoke the driver function if it exists */
|
||||
if (com_dev->driver->set_baud) {
|
||||
com_dev->driver->set_baud(com_dev->id, baud);
|
||||
}
|
||||
|
||||
return 0;
|
||||
return (pios_com_num_devs);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends a package over given port
|
||||
* \param[in] port COM port
|
||||
* \param[in] buffer character buffer
|
||||
* \param[in] len buffer length
|
||||
* \return -1 if port not available
|
||||
* \return -2 if non-blocking mode activated: buffer is full
|
||||
* caller should retry until buffer is free again
|
||||
* \return 0 on success
|
||||
*/
|
||||
int32_t PIOS_COM_SendBufferNonBlocking(uint8_t port, uint8_t *buffer, uint16_t len)
|
||||
static struct pios_com_dev * PIOS_COM_find_dev(uint32_t com_dev_id)
|
||||
{
|
||||
struct pios_com_dev * com_dev;
|
||||
if (!com_dev_id) return NULL;
|
||||
if (com_dev_id>pios_com_num_devs+1) return NULL;
|
||||
return &pios_com_devs[com_dev_id-1];
|
||||
}
|
||||
#endif
|
||||
|
||||
com_dev = find_com_dev_by_id (port);
|
||||
static uint16_t PIOS_COM_TxOutCallback(uint32_t context, uint8_t * buf, uint16_t buf_len, uint16_t * headroom, bool * need_yield);
|
||||
static uint16_t PIOS_COM_RxInCallback(uint32_t context, uint8_t * buf, uint16_t buf_len, uint16_t * headroom, bool * need_yield);
|
||||
static void PIOS_COM_UnblockRx(struct pios_com_dev * com_dev, bool * need_yield);
|
||||
static void PIOS_COM_UnblockTx(struct pios_com_dev * com_dev, bool * need_yield);
|
||||
|
||||
if (!com_dev) {
|
||||
/* Undefined COM port for this board (see pios_board.c) */
|
||||
return -1;
|
||||
}
|
||||
/**
|
||||
* Initialises COM layer
|
||||
* \param[out] handle
|
||||
* \param[in] driver
|
||||
* \param[in] id
|
||||
* \return < 0 if initialisation failed
|
||||
*/
|
||||
int32_t PIOS_COM_Init(uint32_t * com_id, const struct pios_com_driver * driver, uint32_t lower_id, uint8_t * rx_buffer, uint16_t rx_buffer_len, uint8_t * tx_buffer, uint16_t tx_buffer_len)
|
||||
{
|
||||
PIOS_Assert(com_id);
|
||||
PIOS_Assert(driver);
|
||||
|
||||
/* Invoke the driver function if it exists */
|
||||
if (com_dev->driver->tx_nb) {
|
||||
return com_dev->driver->tx_nb(com_dev->id, buffer, len);
|
||||
}
|
||||
bool has_rx = (rx_buffer && rx_buffer_len > 0);
|
||||
bool has_tx = (tx_buffer && tx_buffer_len > 0);
|
||||
PIOS_Assert(has_rx || has_tx);
|
||||
PIOS_Assert(driver->bind_tx_cb || !has_tx);
|
||||
PIOS_Assert(driver->bind_rx_cb || !has_rx);
|
||||
|
||||
return 0;
|
||||
uint32_t com_dev_id;
|
||||
struct pios_com_dev * com_dev;
|
||||
|
||||
com_dev_id = PIOS_COM_create();
|
||||
com_dev = PIOS_COM_find_dev(com_dev_id);
|
||||
if (!com_dev) goto out_fail;
|
||||
|
||||
com_dev->driver = driver;
|
||||
com_dev->lower_id = lower_id;
|
||||
|
||||
com_dev->has_rx = has_rx;
|
||||
com_dev->has_tx = has_tx;
|
||||
|
||||
if (has_rx) {
|
||||
fifoBuf_init(&com_dev->rx, rx_buffer, rx_buffer_len);
|
||||
#if defined(PIOS_INCLUDE_FREERTOS)
|
||||
vSemaphoreCreateBinary(com_dev->rx_sem);
|
||||
#endif /* PIOS_INCLUDE_FREERTOS */
|
||||
(com_dev->driver->bind_rx_cb)(lower_id, PIOS_COM_RxInCallback, com_dev_id);
|
||||
if (com_dev->driver->rx_start) {
|
||||
/* Start the receiver */
|
||||
(com_dev->driver->rx_start)(com_dev->lower_id,
|
||||
fifoBuf_getFree(&com_dev->rx));
|
||||
}
|
||||
}
|
||||
|
||||
if (has_tx) {
|
||||
fifoBuf_init(&com_dev->tx, tx_buffer, tx_buffer_len);
|
||||
#if defined(PIOS_INCLUDE_FREERTOS)
|
||||
vSemaphoreCreateBinary(com_dev->tx_sem);
|
||||
#endif /* PIOS_INCLUDE_FREERTOS */
|
||||
(com_dev->driver->bind_tx_cb)(lower_id, PIOS_COM_TxOutCallback, com_dev_id);
|
||||
}
|
||||
|
||||
*com_id = com_dev_id;
|
||||
return(0);
|
||||
|
||||
out_fail:
|
||||
return(-1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends a package over given port
|
||||
* (blocking function)
|
||||
* \param[in] port COM port
|
||||
* \param[in] buffer character buffer
|
||||
* \param[in] len buffer length
|
||||
* \return -1 if port not available
|
||||
* \return 0 on success
|
||||
*/
|
||||
int32_t PIOS_COM_SendBuffer(uint8_t port, uint8_t *buffer, uint16_t len)
|
||||
static void PIOS_COM_UnblockRx(struct pios_com_dev * com_dev, bool * need_yield)
|
||||
{
|
||||
struct pios_com_dev * com_dev;
|
||||
#if defined(PIOS_INCLUDE_FREERTOS)
|
||||
static signed portBASE_TYPE xHigherPriorityTaskWoken;
|
||||
xSemaphoreGiveFromISR(com_dev->rx_sem, &xHigherPriorityTaskWoken);
|
||||
|
||||
com_dev = find_com_dev_by_id (port);
|
||||
|
||||
if (!com_dev) {
|
||||
/* Undefined COM port for this board (see pios_board.c) */
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Invoke the driver function if it exists */
|
||||
if (com_dev->driver->tx) {
|
||||
return com_dev->driver->tx(com_dev->id, buffer, len);
|
||||
}
|
||||
|
||||
return 0;
|
||||
if (xHigherPriorityTaskWoken != pdFALSE) {
|
||||
*need_yield = true;
|
||||
} else {
|
||||
*need_yield = false;
|
||||
}
|
||||
#else
|
||||
*need_yield = false;
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends a single character over given port
|
||||
* \param[in] port COM port
|
||||
* \param[in] c character
|
||||
* \return -1 if port not available
|
||||
* \return -2 buffer is full
|
||||
* caller should retry until buffer is free again
|
||||
* \return 0 on success
|
||||
*/
|
||||
int32_t PIOS_COM_SendCharNonBlocking(uint8_t port, char c)
|
||||
{
|
||||
return PIOS_COM_SendBufferNonBlocking(port, (uint8_t *)&c, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends a single character over given port
|
||||
* (blocking function)
|
||||
* \param[in] port COM port
|
||||
* \param[in] c character
|
||||
* \return -1 if port not available
|
||||
* \return 0 on success
|
||||
*/
|
||||
int32_t PIOS_COM_SendChar(uint8_t port, char c)
|
||||
{
|
||||
return PIOS_COM_SendBuffer(port, (uint8_t *)&c, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends a string over given port
|
||||
* \param[in] port COM port
|
||||
* \param[in] str zero-terminated string
|
||||
* \return -1 if port not available
|
||||
* \return -2 buffer is full
|
||||
* caller should retry until buffer is free again
|
||||
* \return 0 on success
|
||||
*/
|
||||
int32_t PIOS_COM_SendStringNonBlocking(uint8_t port, char *str)
|
||||
{
|
||||
return PIOS_COM_SendBufferNonBlocking(port, (uint8_t *)str, (uint16_t)strlen(str));
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends a string over given port
|
||||
* (blocking function)
|
||||
* \param[in] port COM port
|
||||
* \param[in] str zero-terminated string
|
||||
* \return -1 if port not available
|
||||
* \return 0 on success
|
||||
*/
|
||||
int32_t PIOS_COM_SendString(uint8_t port, char *str)
|
||||
{
|
||||
return PIOS_COM_SendBuffer(port, (uint8_t *)str, strlen(str));
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends a formatted string (-> printf) over given port
|
||||
* \param[in] port COM port
|
||||
* \param[in] *format zero-terminated format string - 128 characters supported maximum!
|
||||
* \param[in] ... optional arguments,
|
||||
* 128 characters supported maximum!
|
||||
* \return -2 if non-blocking mode activated: buffer is full
|
||||
* caller should retry until buffer is free again
|
||||
* \return 0 on success
|
||||
*/
|
||||
int32_t PIOS_COM_SendFormattedStringNonBlocking(uint8_t port, char *format, ...)
|
||||
{
|
||||
uint8_t buffer[128]; // TODO: tmp!!! Provide a streamed COM method later!
|
||||
|
||||
va_list args;
|
||||
|
||||
va_start(args, format);
|
||||
vsprintf((char *)buffer, format, args);
|
||||
return PIOS_COM_SendBufferNonBlocking(port, buffer, (uint16_t)strlen((char *)buffer));
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends a formatted string (-> printf) over given port
|
||||
* (blocking function)
|
||||
* \param[in] port COM port
|
||||
* \param[in] *format zero-terminated format string - 128 characters supported maximum!
|
||||
* \param[in] ... optional arguments,
|
||||
* \return -1 if port not available
|
||||
* \return 0 on success
|
||||
*/
|
||||
int32_t PIOS_COM_SendFormattedString(uint8_t port, char *format, ...)
|
||||
{
|
||||
uint8_t buffer[128]; // TODO: tmp!!! Provide a streamed COM method later!
|
||||
va_list args;
|
||||
|
||||
va_start(args, format);
|
||||
vsprintf((char *)buffer, format, args);
|
||||
return PIOS_COM_SendBuffer(port, buffer, (uint16_t)strlen((char *)buffer));
|
||||
}
|
||||
|
||||
/**
|
||||
* Transfer bytes from port buffers into another buffer
|
||||
* \param[in] port COM port
|
||||
static void PIOS_COM_UnblockTx(struct pios_com_dev * com_dev, bool * need_yield)
|
||||
{
|
||||
#if defined(PIOS_INCLUDE_FREERTOS)
|
||||
static signed portBASE_TYPE xHigherPriorityTaskWoken;
|
||||
xSemaphoreGiveFromISR(com_dev->tx_sem, &xHigherPriorityTaskWoken);
|
||||
|
||||
if (xHigherPriorityTaskWoken != pdFALSE) {
|
||||
*need_yield = true;
|
||||
} else {
|
||||
*need_yield = false;
|
||||
}
|
||||
#else
|
||||
*need_yield = false;
|
||||
#endif
|
||||
}
|
||||
|
||||
static uint16_t PIOS_COM_RxInCallback(uint32_t context, uint8_t * buf, uint16_t buf_len, uint16_t * headroom, bool * need_yield)
|
||||
{
|
||||
struct pios_com_dev * com_dev = PIOS_COM_find_dev(context);
|
||||
|
||||
bool valid = PIOS_COM_validate(com_dev);
|
||||
PIOS_Assert(valid);
|
||||
PIOS_Assert(com_dev->has_rx);
|
||||
|
||||
PIOS_IRQ_Disable();
|
||||
uint16_t bytes_into_fifo = fifoBuf_putData(&com_dev->rx, buf, buf_len);
|
||||
PIOS_IRQ_Enable();
|
||||
|
||||
if (bytes_into_fifo > 0) {
|
||||
/* Data has been added to the buffer */
|
||||
PIOS_COM_UnblockRx(com_dev, need_yield);
|
||||
}
|
||||
|
||||
if (headroom) {
|
||||
*headroom = fifoBuf_getFree(&com_dev->rx);
|
||||
}
|
||||
|
||||
return (bytes_into_fifo);
|
||||
}
|
||||
|
||||
static uint16_t PIOS_COM_TxOutCallback(uint32_t context, uint8_t * buf, uint16_t buf_len, uint16_t * headroom, bool * need_yield)
|
||||
{
|
||||
struct pios_com_dev * com_dev = PIOS_COM_find_dev(context);
|
||||
|
||||
bool valid = PIOS_COM_validate(com_dev);
|
||||
PIOS_Assert(valid);
|
||||
PIOS_Assert(buf);
|
||||
PIOS_Assert(buf_len);
|
||||
PIOS_Assert(com_dev->has_tx);
|
||||
|
||||
PIOS_IRQ_Disable();
|
||||
uint16_t bytes_from_fifo = fifoBuf_getData(&com_dev->tx, buf, buf_len);
|
||||
PIOS_IRQ_Enable();
|
||||
|
||||
if (bytes_from_fifo > 0) {
|
||||
/* More space has been made in the buffer */
|
||||
PIOS_COM_UnblockTx(com_dev, need_yield);
|
||||
}
|
||||
|
||||
if (headroom) {
|
||||
*headroom = fifoBuf_getUsed(&com_dev->tx);
|
||||
}
|
||||
|
||||
return (bytes_from_fifo);
|
||||
}
|
||||
|
||||
/**
|
||||
* Change the port speed without re-initializing
|
||||
* \param[in] port COM port
|
||||
* \param[in] baud Requested baud rate
|
||||
* \return -1 if port not available
|
||||
* \return 0 on success
|
||||
*/
|
||||
int32_t PIOS_COM_ChangeBaud(uint32_t com_id, uint32_t baud)
|
||||
{
|
||||
struct pios_com_dev * com_dev = PIOS_COM_find_dev(com_id);
|
||||
|
||||
if (!PIOS_COM_validate(com_dev)) {
|
||||
/* Undefined COM port for this board (see pios_board.c) */
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Invoke the driver function if it exists */
|
||||
if (com_dev->driver->set_baud) {
|
||||
com_dev->driver->set_baud(com_dev->lower_id, baud);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends a package over given port
|
||||
* \param[in] port COM port
|
||||
* \param[in] buffer character buffer
|
||||
* \param[in] len buffer length
|
||||
* \return -1 if port not available
|
||||
* \return -2 if non-blocking mode activated: buffer is full
|
||||
* caller should retry until buffer is free again
|
||||
* \return 0 on success
|
||||
*/
|
||||
int32_t PIOS_COM_SendBufferNonBlocking(uint32_t com_id, const uint8_t *buffer, uint16_t len)
|
||||
{
|
||||
struct pios_com_dev * com_dev = PIOS_COM_find_dev(com_id);
|
||||
|
||||
if (!PIOS_COM_validate(com_dev)) {
|
||||
/* Undefined COM port for this board (see pios_board.c) */
|
||||
return -1;
|
||||
}
|
||||
|
||||
PIOS_Assert(com_dev->has_tx);
|
||||
|
||||
if (len >= fifoBuf_getFree(&com_dev->tx)) {
|
||||
/* Buffer cannot accept all requested bytes (retry) */
|
||||
return -2;
|
||||
}
|
||||
|
||||
PIOS_IRQ_Disable();
|
||||
uint16_t bytes_into_fifo = fifoBuf_putData(&com_dev->tx, buffer, len);
|
||||
PIOS_IRQ_Enable();
|
||||
|
||||
if (bytes_into_fifo > 0) {
|
||||
/* More data has been put in the tx buffer, make sure the tx is started */
|
||||
if (com_dev->driver->tx_start) {
|
||||
com_dev->driver->tx_start(com_dev->lower_id,
|
||||
fifoBuf_getUsed(&com_dev->tx));
|
||||
}
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends a package over given port
|
||||
* (blocking function)
|
||||
* \param[in] port COM port
|
||||
* \param[in] buffer character buffer
|
||||
* \param[in] len buffer length
|
||||
* \return -1 if port not available
|
||||
* \return 0 on success
|
||||
*/
|
||||
int32_t PIOS_COM_SendBuffer(uint32_t com_id, const uint8_t *buffer, uint16_t len)
|
||||
{
|
||||
struct pios_com_dev * com_dev = PIOS_COM_find_dev(com_id);
|
||||
|
||||
if (!PIOS_COM_validate(com_dev)) {
|
||||
/* Undefined COM port for this board (see pios_board.c) */
|
||||
return -1;
|
||||
}
|
||||
|
||||
PIOS_Assert(com_dev->has_tx);
|
||||
|
||||
int32_t rc;
|
||||
do {
|
||||
rc = PIOS_COM_SendBufferNonBlocking(com_id, buffer, len);
|
||||
|
||||
#if defined(PIOS_INCLUDE_FREERTOS)
|
||||
if (rc == -2) {
|
||||
/* Make sure the transmitter is running while we wait */
|
||||
if (com_dev->driver->tx_start) {
|
||||
(com_dev->driver->tx_start)(com_dev->lower_id,
|
||||
fifoBuf_getUsed(&com_dev->tx));
|
||||
}
|
||||
if (xSemaphoreTake(com_dev->tx_sem, portMAX_DELAY) != pdTRUE) {
|
||||
return -3;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
} while (rc == -2);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends a single character over given port
|
||||
* \param[in] port COM port
|
||||
* \param[in] c character
|
||||
* \return -1 if port not available
|
||||
* \return -2 buffer is full
|
||||
* caller should retry until buffer is free again
|
||||
* \return 0 on success
|
||||
*/
|
||||
int32_t PIOS_COM_SendCharNonBlocking(uint32_t com_id, char c)
|
||||
{
|
||||
return PIOS_COM_SendBufferNonBlocking(com_id, (uint8_t *)&c, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends a single character over given port
|
||||
* (blocking function)
|
||||
* \param[in] port COM port
|
||||
* \param[in] c character
|
||||
* \return -1 if port not available
|
||||
* \return 0 on success
|
||||
*/
|
||||
int32_t PIOS_COM_SendChar(uint32_t com_id, char c)
|
||||
{
|
||||
return PIOS_COM_SendBuffer(com_id, (uint8_t *)&c, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends a string over given port
|
||||
* \param[in] port COM port
|
||||
* \param[in] str zero-terminated string
|
||||
* \return -1 if port not available
|
||||
* \return -2 buffer is full
|
||||
* caller should retry until buffer is free again
|
||||
* \return 0 on success
|
||||
*/
|
||||
int32_t PIOS_COM_SendStringNonBlocking(uint32_t com_id, const char *str)
|
||||
{
|
||||
return PIOS_COM_SendBufferNonBlocking(com_id, (uint8_t *)str, (uint16_t)strlen(str));
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends a string over given port
|
||||
* (blocking function)
|
||||
* \param[in] port COM port
|
||||
* \param[in] str zero-terminated string
|
||||
* \return -1 if port not available
|
||||
* \return 0 on success
|
||||
*/
|
||||
int32_t PIOS_COM_SendString(uint32_t com_id, const char *str)
|
||||
{
|
||||
return PIOS_COM_SendBuffer(com_id, (uint8_t *)str, strlen(str));
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends a formatted string (-> printf) over given port
|
||||
* \param[in] port COM port
|
||||
* \param[in] *format zero-terminated format string - 128 characters supported maximum!
|
||||
* \param[in] ... optional arguments,
|
||||
* 128 characters supported maximum!
|
||||
* \return -2 if non-blocking mode activated: buffer is full
|
||||
* caller should retry until buffer is free again
|
||||
* \return 0 on success
|
||||
*/
|
||||
int32_t PIOS_COM_SendFormattedStringNonBlocking(uint32_t com_id, const char *format, ...)
|
||||
{
|
||||
uint8_t buffer[128]; // TODO: tmp!!! Provide a streamed COM method later!
|
||||
|
||||
va_list args;
|
||||
|
||||
va_start(args, format);
|
||||
vsprintf((char *)buffer, format, args);
|
||||
return PIOS_COM_SendBufferNonBlocking(com_id, buffer, (uint16_t)strlen((char *)buffer));
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends a formatted string (-> printf) over given port
|
||||
* (blocking function)
|
||||
* \param[in] port COM port
|
||||
* \param[in] *format zero-terminated format string - 128 characters supported maximum!
|
||||
* \param[in] ... optional arguments,
|
||||
* \return -1 if port not available
|
||||
* \return 0 on success
|
||||
*/
|
||||
int32_t PIOS_COM_SendFormattedString(uint32_t com_id, const char *format, ...)
|
||||
{
|
||||
uint8_t buffer[128]; // TODO: tmp!!! Provide a streamed COM method later!
|
||||
va_list args;
|
||||
|
||||
va_start(args, format);
|
||||
vsprintf((char *)buffer, format, args);
|
||||
return PIOS_COM_SendBuffer(com_id, buffer, (uint16_t)strlen((char *)buffer));
|
||||
}
|
||||
|
||||
/**
|
||||
* Transfer bytes from port buffers into another buffer
|
||||
* \param[in] port COM port
|
||||
* \returns Byte from buffer
|
||||
*/
|
||||
uint8_t PIOS_COM_ReceiveBuffer(uint8_t port)
|
||||
{
|
||||
struct pios_com_dev * com_dev;
|
||||
|
||||
com_dev = find_com_dev_by_id (port);
|
||||
//PIOS_DEBUG_Assert(com_dev);
|
||||
//PIOS_DEBUG_Assert(com_dev->driver->rx);
|
||||
|
||||
return com_dev->driver->rx(com_dev->id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the number of bytes waiting in the buffer
|
||||
* \param[in] port COM port
|
||||
* \return Number of bytes used in buffer
|
||||
*/
|
||||
int32_t PIOS_COM_ReceiveBufferUsed(uint8_t port)
|
||||
*/
|
||||
uint16_t PIOS_COM_ReceiveBuffer(uint32_t com_id, uint8_t * buf, uint16_t buf_len, uint32_t timeout_ms)
|
||||
{
|
||||
struct pios_com_dev * com_dev;
|
||||
PIOS_Assert(buf);
|
||||
PIOS_Assert(buf_len);
|
||||
|
||||
com_dev = find_com_dev_by_id (port);
|
||||
struct pios_com_dev * com_dev = PIOS_COM_find_dev(com_id);
|
||||
|
||||
if (!com_dev) {
|
||||
/* Undefined COM port for this board (see pios_board.c) */
|
||||
return 0;
|
||||
}
|
||||
if (!PIOS_COM_validate(com_dev)) {
|
||||
/* Undefined COM port for this board (see pios_board.c) */
|
||||
PIOS_Assert(0);
|
||||
}
|
||||
PIOS_Assert(com_dev->has_rx);
|
||||
|
||||
if (!com_dev->driver->rx_avail) {
|
||||
return 0;
|
||||
}
|
||||
check_again:
|
||||
PIOS_IRQ_Disable();
|
||||
uint16_t bytes_from_fifo = fifoBuf_getData(&com_dev->rx, buf, buf_len);
|
||||
PIOS_IRQ_Enable();
|
||||
|
||||
return com_dev->driver->rx_avail(com_dev->id);
|
||||
if (bytes_from_fifo == 0 && timeout_ms > 0) {
|
||||
/* No more bytes in receive buffer */
|
||||
/* Make sure the receiver is running while we wait */
|
||||
if (com_dev->driver->rx_start) {
|
||||
/* Notify the lower layer that there is now room in the rx buffer */
|
||||
(com_dev->driver->rx_start)(com_dev->lower_id,
|
||||
fifoBuf_getFree(&com_dev->rx));
|
||||
}
|
||||
#if defined(PIOS_INCLUDE_FREERTOS)
|
||||
if (xSemaphoreTake(com_dev->rx_sem, timeout_ms / portTICK_RATE_MS) == pdTRUE) {
|
||||
/* Make sure we don't come back here again */
|
||||
timeout_ms = 0;
|
||||
goto check_again;
|
||||
}
|
||||
#else
|
||||
PIOS_DELAY_WaitmS(1);
|
||||
timeout_ms--;
|
||||
goto check_again;
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Return received byte */
|
||||
return (bytes_from_fifo);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Get the number of bytes waiting in the buffer
|
||||
* \param[in] port COM port
|
||||
* \return Number of bytes used in buffer
|
||||
*/
|
||||
int32_t PIOS_COM_ReceiveBufferUsed(uint32_t com_id)
|
||||
{
|
||||
struct pios_com_dev * com_dev = PIOS_COM_find_dev(com_id);
|
||||
|
||||
if (!PIOS_COM_validate(com_dev)) {
|
||||
/* Undefined COM port for this board (see pios_board.c) */
|
||||
PIOS_Assert(0);
|
||||
}
|
||||
|
||||
PIOS_Assert(com_dev->has_rx);
|
||||
return (fifoBuf_getUsed(&com_dev->rx));
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @}
|
||||
* @}
|
||||
*/
|
||||
|
69
flight/PiOS.posix/posix/pios_irq.c
Normal file
69
flight/PiOS.posix/posix/pios_irq.c
Normal file
@ -0,0 +1,69 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @addtogroup PIOS PIOS Core hardware abstraction layer
|
||||
* @{
|
||||
* @addtogroup PIOS_IRQ IRQ Setup Functions
|
||||
* @brief STM32 Hardware code to enable and disable interrupts
|
||||
* @{
|
||||
*
|
||||
* @file pios_irq.c
|
||||
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
|
||||
* Parts by Thorsten Klose (tk@midibox.org) (tk@midibox.org)
|
||||
* @brief IRQ Enable/Disable routines
|
||||
* @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"
|
||||
|
||||
#if defined(PIOS_INCLUDE_IRQ)
|
||||
|
||||
/* Private Function Prototypes */
|
||||
|
||||
/**
|
||||
* Disables all interrupts (nested)
|
||||
* \return < 0 On errors
|
||||
*/
|
||||
int32_t PIOS_IRQ_Disable(void)
|
||||
{
|
||||
#if defined(PIOS_INCLUDE_FREERTOS)
|
||||
taskENTER_CRITICAL();
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Enables all interrupts (nested)
|
||||
* \return < 0 on errors
|
||||
* \return -1 on nesting errors (PIOS_IRQ_Disable() hasn't been called before)
|
||||
*/
|
||||
int32_t PIOS_IRQ_Enable(void)
|
||||
{
|
||||
#if defined(PIOS_INCLUDE_FREERTOS)
|
||||
taskEXIT_CRITICAL();
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @}
|
||||
* @}
|
||||
*/
|
@ -32,429 +32,213 @@
|
||||
|
||||
#if defined(PIOS_INCLUDE_UDP)
|
||||
|
||||
#include <signal.h>
|
||||
#include <pios_udp_priv.h>
|
||||
|
||||
/* We need a list of UDP devices */
|
||||
|
||||
#define PIOS_UDP_MAX_DEV 256
|
||||
static int8_t pios_udp_num_devices = 0;
|
||||
|
||||
static pios_udp_dev pios_udp_devices[PIOS_UDP_MAX_DEV];
|
||||
|
||||
|
||||
|
||||
/* Provide a COM driver */
|
||||
static void PIOS_UDP_ChangeBaud(uint32_t udp_id, uint32_t baud);
|
||||
static void PIOS_UDP_RegisterRxCallback(uint32_t udp_id, pios_com_callback rx_in_cb, uint32_t context);
|
||||
static void PIOS_UDP_RegisterTxCallback(uint32_t udp_id, pios_com_callback tx_out_cb, uint32_t context);
|
||||
static void PIOS_UDP_TxStart(uint32_t udp_id, uint16_t tx_bytes_avail);
|
||||
static void PIOS_UDP_RxStart(uint32_t udp_id, uint16_t rx_bytes_avail);
|
||||
|
||||
const struct pios_com_driver pios_udp_com_driver = {
|
||||
.set_baud = PIOS_UDP_ChangeBaud,
|
||||
.tx_nb = PIOS_UDP_TxBufferPutMoreNonBlocking,
|
||||
.tx = PIOS_UDP_TxBufferPutMore,
|
||||
.rx = PIOS_UDP_RxBufferGet,
|
||||
.rx_avail = PIOS_UDP_RxBufferUsed,
|
||||
.set_baud = PIOS_UDP_ChangeBaud,
|
||||
.tx_start = PIOS_UDP_TxStart,
|
||||
.rx_start = PIOS_UDP_RxStart,
|
||||
.bind_tx_cb = PIOS_UDP_RegisterTxCallback,
|
||||
.bind_rx_cb = PIOS_UDP_RegisterRxCallback,
|
||||
};
|
||||
|
||||
static struct pios_udp_dev * find_udp_dev_by_id (uint8_t udp)
|
||||
|
||||
static pios_udp_dev * find_udp_dev_by_id (uint8_t udp)
|
||||
{
|
||||
if (udp >= pios_udp_num_devices) {
|
||||
/* Undefined UDP port for this board (see pios_board.c) */
|
||||
PIOS_Assert(0);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Get a handle for the device configuration */
|
||||
return &(pios_udp_devs[udp]);
|
||||
return &(pios_udp_devices[udp]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Open some UDP sockets
|
||||
*/
|
||||
void PIOS_UDP_Init(void)
|
||||
{
|
||||
struct pios_udp_dev * udp_dev;
|
||||
uint8_t i;
|
||||
|
||||
for (i = 0; i < pios_udp_num_devices; i++) {
|
||||
/* Get a handle for the device configuration */
|
||||
udp_dev = find_udp_dev_by_id(i);
|
||||
//PIOS_DEBUG_Assert(udp_dev);
|
||||
|
||||
/* Clear buffer counters */
|
||||
udp_dev->rx.head = udp_dev->rx.tail = udp_dev->rx.size = 0;
|
||||
|
||||
/* assign socket */
|
||||
udp_dev->socket = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);
|
||||
memset(&udp_dev->server,0,sizeof(udp_dev->server));
|
||||
memset(&udp_dev->client,0,sizeof(udp_dev->client));
|
||||
udp_dev->server.sin_family = AF_INET;
|
||||
udp_dev->server.sin_addr.s_addr = inet_addr(udp_dev->cfg->ip);
|
||||
udp_dev->server.sin_port = htons(udp_dev->cfg->port);
|
||||
int res= bind(udp_dev->socket, (struct sockaddr *)&udp_dev->server,sizeof(udp_dev->server));
|
||||
/* use nonblocking IO */
|
||||
int flags = fcntl(udp_dev->socket, F_GETFL, 0);
|
||||
fcntl(udp_dev->socket, F_SETFL, flags | O_NONBLOCK);
|
||||
printf("udp dev %i - socket %i opened - result %i\n",i,udp_dev->socket,res);
|
||||
|
||||
/* TODO do some error handling - wait no, we can't - we are void anyway ;) */
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Changes the baud rate of the UDP peripheral without re-initialising.
|
||||
* \param[in] udp UDP name (GPS, TELEM, AUX)
|
||||
* \param[in] baud Requested baud rate
|
||||
*/
|
||||
void PIOS_UDP_ChangeBaud(uint8_t udp, uint32_t baud)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* puts a byte onto the receive buffer
|
||||
* \param[in] UDP UDP name
|
||||
* \param[in] b byte which should be put into Rx buffer
|
||||
* \return 0 if no error
|
||||
* \return -1 if UDP not available
|
||||
* \return -2 if buffer full (retry)
|
||||
* \note Applications shouldn't call these functions directly, instead please use \ref PIOS_COM layer functions
|
||||
*/
|
||||
int32_t PIOS_UDP_RxBufferPut(uint8_t udp, uint8_t b)
|
||||
{
|
||||
struct pios_udp_dev * udp_dev;
|
||||
|
||||
/* Get a handle for the device configuration */
|
||||
udp_dev = find_udp_dev_by_id(udp);
|
||||
|
||||
if (!udp_dev) {
|
||||
/* Undefined UDP port for this board (see pios_board.c) */
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (udp_dev->rx.size >= sizeof(udp_dev->rx.buf)) {
|
||||
/* Buffer full (retry) */
|
||||
return -2;
|
||||
}
|
||||
|
||||
/* Copy received byte into receive buffer */
|
||||
udp_dev->rx.buf[udp_dev->rx.head++] = b;
|
||||
if (udp_dev->rx.head >= sizeof(udp_dev->rx.buf)) {
|
||||
udp_dev->rx.head = 0;
|
||||
}
|
||||
udp_dev->rx.size++;
|
||||
|
||||
/* No error */
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* attempt to receive
|
||||
* RxThread
|
||||
*/
|
||||
void PIOS_UDP_RECV(uint8_t udp) {
|
||||
|
||||
struct pios_udp_dev * udp_dev;
|
||||
unsigned char localbuffer[PIOS_UDP_RX_BUFFER_SIZE];
|
||||
|
||||
/* Get a handle for the device configuration */
|
||||
udp_dev = find_udp_dev_by_id(udp);
|
||||
|
||||
if (!udp_dev) {
|
||||
/* Undefined UDP port for this board (see pios_board.c) */
|
||||
return;
|
||||
}
|
||||
|
||||
/* use nonblocking IO */
|
||||
int flags = fcntl(udp_dev->socket, F_GETFL, 0);
|
||||
fcntl(udp_dev->socket, F_SETFL, flags | O_NONBLOCK);
|
||||
|
||||
/* receive data */
|
||||
int received;
|
||||
udp_dev->clientLength=sizeof(udp_dev->client);
|
||||
if ((received = recvfrom(udp_dev->socket,
|
||||
localbuffer,
|
||||
(PIOS_UDP_RX_BUFFER_SIZE - udp_dev->rx.size),
|
||||
0,
|
||||
(struct sockaddr *) &udp_dev->client,
|
||||
(socklen_t*)&udp_dev->clientLength)) < 0) {
|
||||
|
||||
return;
|
||||
}
|
||||
/* copy received data to buffer */
|
||||
int t;
|
||||
for (t=0;t<received;t++) {
|
||||
PIOS_UDP_RxBufferPut(udp,localbuffer[t]);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns number of free bytes in receive buffer
|
||||
* \param[in] UDP UDP name
|
||||
* \return UDP number of free bytes
|
||||
* \return 1: UDP available
|
||||
* \return 0: UDP not available
|
||||
*/
|
||||
int32_t PIOS_UDP_RxBufferFree(uint8_t udp)
|
||||
void * PIOS_UDP_RxThread(void * udp_dev_n)
|
||||
{
|
||||
struct pios_udp_dev * udp_dev;
|
||||
|
||||
/* Get a handle for the device configuration */
|
||||
udp_dev = find_udp_dev_by_id(udp);
|
||||
/* needed because of FreeRTOS.posix scheduling */
|
||||
sigset_t set;
|
||||
sigfillset(&set);
|
||||
sigprocmask(SIG_BLOCK, &set, NULL);
|
||||
|
||||
if (!udp_dev) {
|
||||
/* Undefined UDP port for this board (see pios_board.c) */
|
||||
return -2;
|
||||
}
|
||||
pios_udp_dev * udp_dev = (pios_udp_dev*) udp_dev_n;
|
||||
|
||||
/* fill buffer */
|
||||
PIOS_UDP_RECV(udp);
|
||||
/**
|
||||
* com devices never get closed except by application "reboot"
|
||||
* we also never give up our mutex except for waiting
|
||||
*/
|
||||
while(1) {
|
||||
|
||||
return (sizeof(udp_dev->rx.buf) - udp_dev->rx.size);
|
||||
}
|
||||
/**
|
||||
* receive
|
||||
*/
|
||||
int received;
|
||||
udp_dev->clientLength=sizeof(udp_dev->client);
|
||||
if ((received = recvfrom(udp_dev->socket,
|
||||
&udp_dev->rx_buffer,
|
||||
PIOS_UDP_RX_BUFFER_SIZE,
|
||||
0,
|
||||
(struct sockaddr *) &udp_dev->client,
|
||||
(socklen_t*)&udp_dev->clientLength)) >= 0)
|
||||
{
|
||||
|
||||
/**
|
||||
* Returns number of used bytes in receive buffer
|
||||
* \param[in] UDP UDP name
|
||||
* \return > 0: number of used bytes
|
||||
* \return 0 if UDP not available
|
||||
* \note Applications shouldn't call these functions directly, instead please use \ref PIOS_COM layer functions
|
||||
*/
|
||||
int32_t PIOS_UDP_RxBufferUsed(uint8_t udp)
|
||||
{
|
||||
struct pios_udp_dev * udp_dev;
|
||||
/* copy received data to buffer if possible */
|
||||
/* we do NOT buffer data locally. If the com buffer can't receive, data is discarded! */
|
||||
/* (thats what the USART driver does too!) */
|
||||
bool rx_need_yield = false;
|
||||
if (udp_dev->rx_in_cb) {
|
||||
(void) (udp_dev->rx_in_cb)(udp_dev->rx_in_context, udp_dev->rx_buffer, received, NULL, &rx_need_yield);
|
||||
}
|
||||
|
||||
/* Get a handle for the device configuration */
|
||||
udp_dev = find_udp_dev_by_id(udp);
|
||||
#if defined(PIOS_INCLUDE_FREERTOS)
|
||||
if (rx_need_yield) {
|
||||
vPortYieldFromISR();
|
||||
}
|
||||
#endif /* PIOS_INCLUDE_FREERTOS */
|
||||
|
||||
if (!udp_dev) {
|
||||
/* Undefined UDP port for this board (see pios_board.c) */
|
||||
return -2;
|
||||
}
|
||||
}
|
||||
|
||||
/* fill buffer */
|
||||
PIOS_UDP_RECV(udp);
|
||||
|
||||
return (udp_dev->rx.size);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a byte from the receive buffer
|
||||
* \param[in] UDP UDP name
|
||||
* \return -1 if UDP not available
|
||||
* \return -2 if no new byte available
|
||||
* \return >= 0: number of received bytes
|
||||
* \note Applications shouldn't call these functions directly, instead please use \ref PIOS_COM layer functions
|
||||
*/
|
||||
int32_t PIOS_UDP_RxBufferGet(uint8_t udp)
|
||||
{
|
||||
struct pios_udp_dev * udp_dev;
|
||||
|
||||
/* Get a handle for the device configuration */
|
||||
udp_dev = find_udp_dev_by_id(udp);
|
||||
|
||||
if (!udp_dev) {
|
||||
/* Undefined UDP port for this board (see pios_board.c) */
|
||||
return -2;
|
||||
}
|
||||
|
||||
/* fill buffer */
|
||||
PIOS_UDP_RECV(udp);
|
||||
|
||||
if (!udp_dev->rx.size) {
|
||||
/* Nothing new in the buffer */
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* get byte */
|
||||
uint8_t b = udp_dev->rx.buf[udp_dev->rx.tail++];
|
||||
if (udp_dev->rx.tail >= sizeof(udp_dev->rx.buf)) {
|
||||
udp_dev->rx.tail = 0;
|
||||
}
|
||||
udp_dev->rx.size--;
|
||||
|
||||
/* Return received byte */
|
||||
return b;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the next byte of the receive buffer without taking it
|
||||
* \param[in] UDP UDP name
|
||||
* \return -1 if UDP not available
|
||||
* \return -2 if no new byte available
|
||||
* \return >= 0: number of received bytes
|
||||
* \note Applications shouldn't call these functions directly, instead please use \ref PIOS_COM layer functions
|
||||
*/
|
||||
int32_t PIOS_UDP_RxBufferPeek(uint8_t udp)
|
||||
{
|
||||
struct pios_udp_dev * udp_dev;
|
||||
|
||||
/* Get a handle for the device configuration */
|
||||
udp_dev = find_udp_dev_by_id(udp);
|
||||
|
||||
if (!udp_dev) {
|
||||
/* Undefined UDP port for this board (see pios_board.c) */
|
||||
return -2;
|
||||
}
|
||||
|
||||
/* fill buffer */
|
||||
PIOS_UDP_RECV(udp);
|
||||
|
||||
if (!udp_dev->rx.size) {
|
||||
/* Nothing new in the buffer */
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* get byte */
|
||||
uint8_t b = udp_dev->rx.buf[udp_dev->rx.tail];
|
||||
|
||||
/* Return received byte */
|
||||
return b;
|
||||
}
|
||||
|
||||
/**
|
||||
* returns number of free bytes in transmit buffer
|
||||
* \param[in] UDP UDP name
|
||||
* \return number of free bytes
|
||||
* \return 0 if UDP not available
|
||||
* \note Applications shouldn't call these functions directly, instead please use \ref PIOS_COM layer functions
|
||||
*/
|
||||
int32_t PIOS_UDP_TxBufferFree(uint8_t udp)
|
||||
{
|
||||
struct pios_udp_dev * udp_dev;
|
||||
|
||||
/* Get a handle for the device configuration */
|
||||
udp_dev = find_udp_dev_by_id(udp);
|
||||
|
||||
if (!udp_dev) {
|
||||
/* Undefined UDP port for this board (see pios_board.c) */
|
||||
return 0;
|
||||
}
|
||||
|
||||
return PIOS_UDP_RX_BUFFER_SIZE;
|
||||
}
|
||||
|
||||
/**
|
||||
* returns number of used bytes in transmit buffer
|
||||
* \param[in] UDP UDP name
|
||||
* \return number of used bytes
|
||||
* \return 0 if UDP not available
|
||||
* \note Applications shouldn't call these functions directly, instead please use \ref PIOS_COM layer functions
|
||||
*/
|
||||
int32_t PIOS_UDP_TxBufferUsed(uint8_t udp)
|
||||
{
|
||||
struct pios_udp_dev * udp_dev;
|
||||
|
||||
/* Get a handle for the device configuration */
|
||||
udp_dev = find_udp_dev_by_id(udp);
|
||||
|
||||
if (!udp_dev) {
|
||||
/* Undefined UDP port for this board (see pios_board.c) */
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* puts more than one byte onto the transmit buffer (used for atomic sends)
|
||||
* \param[in] UDP UDP name
|
||||
* \param[in] *buffer pointer to buffer to be sent
|
||||
* \param[in] len number of bytes to be sent
|
||||
* \return 0 if no error
|
||||
* \return -1 if UDP not available
|
||||
* \return -2 if buffer full or cannot get all requested bytes (retry)
|
||||
* \return -3 if UDP not supported by UDPTxBufferPut Routine
|
||||
* \note Applications shouldn't call these functions directly, instead please use \ref PIOS_COM layer functions
|
||||
* Open UDP socket
|
||||
*/
|
||||
int32_t PIOS_UDP_TxBufferPutMoreNonBlocking(uint8_t udp, uint8_t *buffer, uint16_t len)
|
||||
int32_t PIOS_UDP_Init(uint32_t * udp_id, const struct pios_udp_cfg * cfg)
|
||||
{
|
||||
struct pios_udp_dev * udp_dev;
|
||||
|
||||
/* Get a handle for the device configuration */
|
||||
udp_dev = find_udp_dev_by_id(udp);
|
||||
pios_udp_dev * udp_dev = &pios_udp_devices[pios_udp_num_devices];
|
||||
|
||||
if (!udp_dev) {
|
||||
/* Undefined UDP port for this board (see pios_board.c) */
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (len >= PIOS_UDP_RX_BUFFER_SIZE) {
|
||||
/* Buffer cannot accept all requested bytes (retry) */
|
||||
return -2;
|
||||
}
|
||||
/* send data to client - non blocking*/
|
||||
|
||||
/* use nonblocking IO */
|
||||
int flags = fcntl(udp_dev->socket, F_GETFL, 0);
|
||||
fcntl(udp_dev->socket, F_SETFL, flags | O_NONBLOCK);
|
||||
sendto(udp_dev->socket, buffer, len, 0,
|
||||
(struct sockaddr *) &udp_dev->client,
|
||||
(socklen_t)sizeof(udp_dev->client));
|
||||
pios_udp_num_devices++;
|
||||
|
||||
|
||||
/* No error */
|
||||
return 0;
|
||||
/* initialize */
|
||||
udp_dev->rx_in_cb = NULL;
|
||||
udp_dev->tx_out_cb = NULL;
|
||||
udp_dev->cfg=cfg;
|
||||
|
||||
/* assign socket */
|
||||
udp_dev->socket = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);
|
||||
memset(&udp_dev->server,0,sizeof(udp_dev->server));
|
||||
memset(&udp_dev->client,0,sizeof(udp_dev->client));
|
||||
udp_dev->server.sin_family = AF_INET;
|
||||
udp_dev->server.sin_addr.s_addr = inet_addr(udp_dev->cfg->ip);
|
||||
udp_dev->server.sin_port = htons(udp_dev->cfg->port);
|
||||
int res= bind(udp_dev->socket, (struct sockaddr *)&udp_dev->server,sizeof(udp_dev->server));
|
||||
|
||||
/* Create transmit thread for this connection */
|
||||
pthread_create(&udp_dev->rxThread, NULL, PIOS_UDP_RxThread, (void*)udp_dev);
|
||||
|
||||
printf("udp dev %i - socket %i opened - result %i\n",pios_udp_num_devices-1,udp_dev->socket,res);
|
||||
|
||||
*udp_id = pios_udp_num_devices-1;
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
/**
|
||||
* puts more than one byte onto the transmit buffer (used for atomic sends)<BR>
|
||||
* (blocking function)
|
||||
* \param[in] UDP UDP name
|
||||
* \param[in] *buffer pointer to buffer to be sent
|
||||
* \param[in] len number of bytes to be sent
|
||||
* \return 0 if no error
|
||||
* \return -1 if UDP not available
|
||||
* \return -3 if UDP not supported by UDPTxBufferPut Routine
|
||||
* \note Applications shouldn't call these functions directly, instead please use \ref PIOS_COM layer functions
|
||||
*/
|
||||
int32_t PIOS_UDP_TxBufferPutMore(uint8_t udp, uint8_t *buffer, uint16_t len)
|
||||
|
||||
void PIOS_UDP_ChangeBaud(uint32_t udp_id, uint32_t baud)
|
||||
{
|
||||
struct pios_udp_dev * udp_dev;
|
||||
|
||||
/* Get a handle for the device configuration */
|
||||
udp_dev = find_udp_dev_by_id(udp);
|
||||
|
||||
if (!udp_dev) {
|
||||
/* Undefined UDP port for this board (see pios_board.c) */
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (len >= PIOS_UDP_RX_BUFFER_SIZE) {
|
||||
/* Buffer cannot accept all requested bytes (retry) */
|
||||
return -2;
|
||||
}
|
||||
|
||||
/* send data to client - blocking*/
|
||||
/* use blocking IO */
|
||||
int flags = fcntl(udp_dev->socket, F_GETFL, 0);
|
||||
fcntl(udp_dev->socket, F_SETFL, flags & ~O_NONBLOCK);
|
||||
sendto(udp_dev->socket, buffer, len, 0,
|
||||
(struct sockaddr *) &udp_dev->client,
|
||||
sizeof(udp_dev->client));
|
||||
|
||||
/* No error */
|
||||
return 0;
|
||||
/**
|
||||
* doesn't apply!
|
||||
*/
|
||||
}
|
||||
|
||||
/**
|
||||
* puts a byte onto the transmit buffer
|
||||
* \param[in] UDP UDP name
|
||||
* \param[in] b byte which should be put into Tx buffer
|
||||
* \return 0 if no error
|
||||
* \return -1 if UDP not available
|
||||
* \return -2 if buffer full (retry)
|
||||
* \return -3 if UDP not supported by UDPTxBufferPut Routine
|
||||
* \note Applications shouldn't call these functions directly, instead please use \ref PIOS_COM layer functions
|
||||
*/
|
||||
int32_t PIOS_UDP_TxBufferPut_NonBlocking(uint8_t udp, uint8_t b)
|
||||
|
||||
static void PIOS_UDP_RxStart(uint32_t udp_id, uint16_t rx_bytes_avail)
|
||||
{
|
||||
return PIOS_UDP_TxBufferPutMoreNonBlocking(udp, &b, 1);
|
||||
/**
|
||||
* lazy!
|
||||
*/
|
||||
}
|
||||
|
||||
/**
|
||||
* puts a byte onto the transmit buffer<BR>
|
||||
* (blocking function)
|
||||
* \param[in] UDP UDP name
|
||||
* \param[in] b byte which should be put into Tx buffer
|
||||
* \return 0 if no error
|
||||
* \return -1 if UDP not available
|
||||
* \return -3 if UDP not supported by UDPTxBufferPut Routine
|
||||
* \note Applications shouldn't call these functions directly, instead please use \ref PIOS_COM layer functions
|
||||
*/
|
||||
int32_t PIOS_UDP_TxBufferPut(uint8_t udp, uint8_t b)
|
||||
|
||||
static void PIOS_UDP_TxStart(uint32_t udp_id, uint16_t tx_bytes_avail)
|
||||
{
|
||||
return PIOS_UDP_TxBufferPutMore(udp, &b, 1);
|
||||
pios_udp_dev * udp_dev = find_udp_dev_by_id(udp_id);
|
||||
|
||||
PIOS_Assert(udp_dev);
|
||||
|
||||
int32_t length,len,rem;
|
||||
|
||||
/**
|
||||
* we send everything directly whenever notified of data to send (lazy!)
|
||||
*/
|
||||
if (udp_dev->tx_out_cb) {
|
||||
while (tx_bytes_avail>0) {
|
||||
bool tx_need_yield = false;
|
||||
length = (udp_dev->tx_out_cb)(udp_dev->tx_out_context, udp_dev->tx_buffer, PIOS_UDP_RX_BUFFER_SIZE, NULL, &tx_need_yield);
|
||||
rem = length;
|
||||
while (rem>0) {
|
||||
len = sendto(udp_dev->socket, udp_dev->tx_buffer, length, 0,
|
||||
(struct sockaddr *) &udp_dev->client,
|
||||
sizeof(udp_dev->client));
|
||||
if (len<=0) {
|
||||
rem=0;
|
||||
} else {
|
||||
rem -= len;
|
||||
}
|
||||
}
|
||||
tx_bytes_avail -= length;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static void PIOS_UDP_RegisterRxCallback(uint32_t udp_id, pios_com_callback rx_in_cb, uint32_t context)
|
||||
{
|
||||
pios_udp_dev * udp_dev = find_udp_dev_by_id(udp_id);
|
||||
|
||||
PIOS_Assert(udp_dev);
|
||||
|
||||
/*
|
||||
* Order is important in these assignments since ISR uses _cb
|
||||
* field to determine if it's ok to dereference _cb and _context
|
||||
*/
|
||||
udp_dev->rx_in_context = context;
|
||||
udp_dev->rx_in_cb = rx_in_cb;
|
||||
}
|
||||
|
||||
static void PIOS_UDP_RegisterTxCallback(uint32_t udp_id, pios_com_callback tx_out_cb, uint32_t context)
|
||||
{
|
||||
pios_udp_dev * udp_dev = find_udp_dev_by_id(udp_id);
|
||||
|
||||
PIOS_Assert(udp_dev);
|
||||
|
||||
/*
|
||||
* Order is important in these assignments since ISR uses _cb
|
||||
* field to determine if it's ok to dereference _cb and _context
|
||||
*/
|
||||
udp_dev->tx_out_context = context;
|
||||
udp_dev->tx_out_cb = tx_out_cb;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
|
@ -38,7 +38,6 @@
|
||||
* and we cannot define a linker script for each of them atm
|
||||
*/
|
||||
|
||||
#define UAVOBJ_INITCALL(fn)
|
||||
#define MODULE_INITCALL(ifn, iparam, sfn, sparam, flags)
|
||||
|
||||
#define MODULE_TASKCREATE_ALL
|
||||
|
@ -96,6 +96,22 @@ void PIOS_ADXL345_Init()
|
||||
PIOS_ADXL345_SetMeasure(1);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Return number of entries in the fifo
|
||||
*/
|
||||
uint8_t PIOS_ADXL345_FifoElements()
|
||||
{
|
||||
uint8_t buf[2] = {0,0};
|
||||
uint8_t rec[2] = {0,0};
|
||||
buf[0] = ADXL_FIFOSTATUS_ADDR | ADXL_READ_BIT ; // Read fifo status
|
||||
|
||||
PIOS_ADXL345_ClaimBus();
|
||||
PIOS_SPI_TransferBlock(PIOS_SPI_ACCEL,&buf[0],&rec[0],sizeof(buf),NULL);
|
||||
PIOS_ADXL345_ReleaseBus();
|
||||
|
||||
return rec[1] & 0x3f;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Read a single set of values from the x y z channels
|
||||
* @returns The number of samples remaining in the fifo
|
||||
|
@ -18,16 +18,6 @@ SECTIONS
|
||||
*(.rodata .rodata* .gnu.linkonce.r.*)
|
||||
} > BL_FLASH
|
||||
|
||||
/* init sections */
|
||||
.initcalluavobj.init :
|
||||
{
|
||||
. = ALIGN(4);
|
||||
__uavobj_initcall_start = .;
|
||||
KEEP(*(.initcalluavobj.init))
|
||||
. = ALIGN(4);
|
||||
__uavobj_initcall_end = .;
|
||||
} > BL_FLASH
|
||||
|
||||
.ARM.extab :
|
||||
{
|
||||
*(.ARM.extab* .gnu.linkonce.armextab.*)
|
||||
|
@ -22,16 +22,6 @@ SECTIONS
|
||||
*(.rodata .rodata* .gnu.linkonce.r.*)
|
||||
} > FLASH
|
||||
|
||||
/* init sections */
|
||||
.initcalluavobj.init :
|
||||
{
|
||||
. = ALIGN(4);
|
||||
__uavobj_initcall_start = .;
|
||||
KEEP(*(.initcalluavobj.init))
|
||||
. = ALIGN(4);
|
||||
__uavobj_initcall_end = .;
|
||||
} >FLASH
|
||||
|
||||
/* module sections */
|
||||
.initcallmodule.init :
|
||||
{
|
||||
|
@ -180,16 +180,6 @@ SECTIONS
|
||||
} > BL_FLASH
|
||||
|
||||
|
||||
/* init sections */
|
||||
.initcalluavobj.init :
|
||||
{
|
||||
. = ALIGN(4);
|
||||
__uavobj_initcall_start = .;
|
||||
KEEP(*(.initcalluavobj.init))
|
||||
. = ALIGN(4);
|
||||
__uavobj_initcall_end = .;
|
||||
} > BL_FLASH
|
||||
|
||||
/* the program code is stored in the .text section, which goes to Flash */
|
||||
.text :
|
||||
{
|
||||
|
@ -181,16 +181,7 @@ SECTIONS
|
||||
. = ALIGN(4);
|
||||
} >FLASH
|
||||
|
||||
|
||||
/* init sections */
|
||||
.initcalluavobj.init :
|
||||
{
|
||||
. = ALIGN(4);
|
||||
__uavobj_initcall_start = .;
|
||||
KEEP(*(.initcalluavobj.init))
|
||||
. = ALIGN(4);
|
||||
__uavobj_initcall_end = .;
|
||||
} >FLASH
|
||||
|
||||
|
||||
/* the program code is stored in the .text section, which goes to Flash */
|
||||
.text :
|
||||
|
@ -179,17 +179,6 @@ SECTIONS
|
||||
. = ALIGN(4);
|
||||
} > BL_FLASH
|
||||
|
||||
|
||||
/* init sections */
|
||||
.initcalluavobj.init :
|
||||
{
|
||||
. = ALIGN(4);
|
||||
__uavobj_initcall_start = .;
|
||||
KEEP(*(.initcalluavobj.init))
|
||||
. = ALIGN(4);
|
||||
__uavobj_initcall_end = .;
|
||||
} > BL_FLASH
|
||||
|
||||
/* the program code is stored in the .text section, which goes to Flash */
|
||||
.text :
|
||||
{
|
||||
|
@ -181,17 +181,6 @@ SECTIONS
|
||||
*(.flashtext) /* Startup code */
|
||||
. = ALIGN(4);
|
||||
} >FLASH
|
||||
|
||||
|
||||
/* init sections */
|
||||
.initcalluavobj.init :
|
||||
{
|
||||
. = ALIGN(4);
|
||||
__uavobj_initcall_start = .;
|
||||
KEEP(*(.initcalluavobj.init))
|
||||
. = ALIGN(4);
|
||||
__uavobj_initcall_end = .;
|
||||
} >FLASH
|
||||
|
||||
/* module sections */
|
||||
.initcallmodule.init :
|
||||
|
@ -16,6 +16,7 @@
|
||||
#define ADXL_MULTI_BIT 0x40
|
||||
|
||||
#define ADXL_X0_ADDR 0x32
|
||||
#define ADXL_FIFOSTATUS_ADDR 0x39
|
||||
|
||||
#define ADXL_RATE_ADDR 0x2C
|
||||
#define ADXL_RATE_100 0x0A
|
||||
@ -52,5 +53,6 @@ void PIOS_ADXL345_FifoDepth(uint8_t depth);
|
||||
void PIOS_ADXL345_Attach(uint32_t spi_id);
|
||||
void PIOS_ADXL345_Init();
|
||||
uint8_t PIOS_ADXL345_Read(struct pios_adxl345_data * data);
|
||||
uint8_t PIOS_ADXL345_FifoElements();
|
||||
|
||||
#endif
|
||||
|
@ -67,7 +67,6 @@ extern initmodule_t __module_initcall_start[], __module_initcall_end[];
|
||||
static initmodule_t __initcall_##fn __attribute__((__used__)) \
|
||||
__attribute__((__section__(".initcall" level ".init"))) = { .fn_minit = ifn, .fn_tinit = sfn };
|
||||
|
||||
#define UAVOBJ_INITCALL(fn) __define_initcall("uavobj",fn,1)
|
||||
#define MODULE_INITCALL(ifn, sfn) __define_module_initcall("module", ifn, sfn)
|
||||
|
||||
#define MODULE_INITIALISE_ALL { for (initmodule_t *fn = __module_initcall_start; fn < __module_initcall_end; fn++) \
|
||||
|
@ -27,7 +27,11 @@
|
||||
#include "openpilot.h"
|
||||
|
||||
// Private constants
|
||||
#if defined(PIOS_EVENTDISAPTCHER_QUEUE)
|
||||
#define MAX_QUEUE_SIZE PIOS_EVENTDISAPTCHER_QUEUE
|
||||
#else
|
||||
#define MAX_QUEUE_SIZE 20
|
||||
#endif
|
||||
|
||||
#if defined(PIOS_EVENTDISPATCHER_STACK_SIZE)
|
||||
#define STACK_SIZE PIOS_EVENTDISPATCHER_STACK_SIZE
|
||||
|
@ -29,4 +29,6 @@
|
||||
|
||||
void UAVObjectsInitializeAll();
|
||||
|
||||
#define UAVOBJECTS_LARGEST $(SIZECALCULATION)
|
||||
|
||||
#endif // UAVOBJECTSINIT_H
|
@ -36,5 +36,7 @@ $(OBJINC)
|
||||
*/
|
||||
void UAVObjectsInitializeAll()
|
||||
{
|
||||
return;
|
||||
// This function is no longer used anyway
|
||||
$(OBJINIT)
|
||||
}
|
||||
|
@ -40,15 +40,19 @@
|
||||
#include "$(NAMELC).h"
|
||||
|
||||
// Private variables
|
||||
static UAVObjHandle handle;
|
||||
static UAVObjHandle handle = NULL;
|
||||
|
||||
/**
|
||||
* Initialize object.
|
||||
* \return 0 Success
|
||||
* \return -1 Failure
|
||||
* \return -1 Failure to initialize or -2 for already initialized
|
||||
*/
|
||||
int32_t $(NAME)Initialize(void)
|
||||
{
|
||||
// Don't set the handle to null if already registered
|
||||
if(UAVObjGetByID($(NAMEUC)_OBJID) != NULL)
|
||||
return -2;
|
||||
|
||||
// Register object with the object manager
|
||||
handle = UAVObjRegister($(NAMEUC)_OBJID, $(NAMEUC)_NAME, $(NAMEUC)_METANAME, 0,
|
||||
$(NAMEUC)_ISSINGLEINST, $(NAMEUC)_ISSETTINGS, $(NAMEUC)_NUMBYTES, &$(NAME)SetDefaults);
|
||||
@ -64,8 +68,6 @@ int32_t $(NAME)Initialize(void)
|
||||
}
|
||||
}
|
||||
|
||||
UAVOBJ_INITCALL($(NAME)Initialize);
|
||||
|
||||
/**
|
||||
* Initialize object fields and metadata with the default values.
|
||||
* If a default value is not specified the object fields
|
||||
|
@ -29,10 +29,6 @@
|
||||
#ifndef UAVTALK_H
|
||||
#define UAVTALK_H
|
||||
|
||||
// Public constants
|
||||
#define UAVTALK_WAITFOREVER -1
|
||||
#define UAVTALK_NOWAIT 0
|
||||
|
||||
// Public types
|
||||
typedef int32_t (*UAVTalkOutputStream)(uint8_t* data, int32_t length);
|
||||
|
||||
@ -47,14 +43,17 @@ typedef struct {
|
||||
uint32_t rxErrors;
|
||||
} UAVTalkStats;
|
||||
|
||||
typedef void* UAVTalkConnection;
|
||||
|
||||
// Public functions
|
||||
int32_t UAVTalkInitialize(UAVTalkOutputStream outputStream);
|
||||
int32_t UAVTalkSetOutputStream(UAVTalkOutputStream outputStream);
|
||||
int32_t UAVTalkSendObject(UAVObjHandle obj, uint16_t instId, uint8_t acked, int32_t timeoutMs);
|
||||
int32_t UAVTalkSendObjectRequest(UAVObjHandle obj, uint16_t instId, int32_t timeoutMs);
|
||||
int32_t UAVTalkProcessInputStream(uint8_t rxbyte);
|
||||
void UAVTalkGetStats(UAVTalkStats* stats);
|
||||
void UAVTalkResetStats();
|
||||
UAVTalkConnection UAVTalkInitialize(UAVTalkOutputStream outputStream, uint32_t maxPacketSize);
|
||||
int32_t UAVTalkSetOutputStream(UAVTalkConnection connection, UAVTalkOutputStream outputStream);
|
||||
UAVTalkOutputStream UAVTalkGetOutputStream(UAVTalkConnection connection);
|
||||
int32_t UAVTalkSendObject(UAVTalkConnection connection, UAVObjHandle obj, uint16_t instId, uint8_t acked, int32_t timeoutMs);
|
||||
int32_t UAVTalkSendObjectRequest(UAVTalkConnection connection, UAVObjHandle obj, uint16_t instId, int32_t timeoutMs);
|
||||
int32_t UAVTalkProcessInputStream(UAVTalkConnection connection, uint8_t rxbyte);
|
||||
void UAVTalkGetStats(UAVTalkConnection connection, UAVTalkStats *stats);
|
||||
void UAVTalkResetStats(UAVTalkConnection connection);
|
||||
|
||||
#endif // UAVTALK_H
|
||||
/**
|
||||
|
111
flight/UAVTalk/inc/uavtalk_priv.h
Normal file
111
flight/UAVTalk/inc/uavtalk_priv.h
Normal file
@ -0,0 +1,111 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @addtogroup OpenPilotSystem OpenPilot System
|
||||
* @{
|
||||
* @addtogroup OpenPilotLibraries OpenPilot System Libraries
|
||||
* @{
|
||||
* @file uavtalk.h
|
||||
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
|
||||
* @brief Private include file of the UAVTalk library
|
||||
* @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 UAVTALK_PRIV_H
|
||||
#define UAVTALK_PRIV_H
|
||||
|
||||
#include "uavobjectsinit.h"
|
||||
|
||||
// Private types and constants
|
||||
typedef struct {
|
||||
uint8_t sync;
|
||||
uint8_t type;
|
||||
uint16_t size;
|
||||
uint32_t objId;
|
||||
} uavtalk_min_header;
|
||||
#define UAVTALK_MIN_HEADER_LENGTH sizeof(uavtalk_min_header)
|
||||
|
||||
typedef struct {
|
||||
uint8_t sync;
|
||||
uint8_t type;
|
||||
uint16_t size;
|
||||
uint32_t objId;
|
||||
uint16_t instId;
|
||||
} uavtalk_max_header;
|
||||
#define UAVTALK_MAX_HEADER_LENGTH sizeof(uavtalk_max_header)
|
||||
|
||||
typedef uint8_t uavtalk_checksum;
|
||||
#define UAVTALK_CHECKSUM_LENGTH sizeof(uavtalk_checksum)
|
||||
#define UAVTALK_MAX_PAYLOAD_LENGTH UAVOBJECTS_LARGEST
|
||||
#define UAVTALK_MIN_PACKET_LENGTH UAVTALK_MAX_HEADER_LENGTH + UAVTALK_CHECKSUM_LENGTH
|
||||
#define UAVTALK_MAX_PACKET_LENGTH UAVTALK_MIN_PACKET_LENGTH + UAVTALK_MAX_PAYLOAD_LENGTH
|
||||
|
||||
typedef enum {UAVTALK_STATE_SYNC, UAVTALK_STATE_TYPE, UAVTALK_STATE_SIZE, UAVTALK_STATE_OBJID, UAVTALK_STATE_INSTID, UAVTALK_STATE_DATA, UAVTALK_STATE_CS} UAVTalkRxState;
|
||||
|
||||
typedef struct {
|
||||
UAVObjHandle obj;
|
||||
uint8_t type;
|
||||
uint16_t packet_size;
|
||||
uint32_t objId;
|
||||
uint16_t instId;
|
||||
uint32_t length;
|
||||
uint8_t cs;
|
||||
int32_t rxCount;
|
||||
UAVTalkRxState state;
|
||||
uint16_t rxPacketLength;
|
||||
} UAVTalkInputProcessor;
|
||||
|
||||
typedef struct {
|
||||
uint8_t canari;
|
||||
UAVTalkOutputStream outStream;
|
||||
xSemaphoreHandle lock;
|
||||
xSemaphoreHandle transLock;
|
||||
xSemaphoreHandle respSema;
|
||||
UAVObjHandle respObj;
|
||||
uint16_t respInstId;
|
||||
UAVTalkStats stats;
|
||||
UAVTalkInputProcessor iproc;
|
||||
uint8_t *rxBuffer;
|
||||
uint32_t txSize;
|
||||
uint8_t *txBuffer;
|
||||
} UAVTalkConnectionData;
|
||||
|
||||
#define UAVTALK_CANARI 0xCA
|
||||
#define UAVTALK_WAITFOREVER -1
|
||||
#define UAVTALK_NOWAIT 0
|
||||
#define UAVTALK_SYNC_VAL 0x3C
|
||||
#define UAVTALK_TYPE_MASK 0xF8
|
||||
#define UAVTALK_TYPE_VER 0x20
|
||||
#define UAVTALK_TYPE_OBJ (UAVTALK_TYPE_VER | 0x00)
|
||||
#define UAVTALK_TYPE_OBJ_REQ (UAVTALK_TYPE_VER | 0x01)
|
||||
#define UAVTALK_TYPE_OBJ_ACK (UAVTALK_TYPE_VER | 0x02)
|
||||
#define UAVTALK_TYPE_ACK (UAVTALK_TYPE_VER | 0x03)
|
||||
#define UAVTALK_TYPE_NACK (UAVTALK_TYPE_VER | 0x04)
|
||||
|
||||
//macros
|
||||
#define CHECKCONHANDLE(handle,variable,failcommand) \
|
||||
variable = (UAVTalkConnectionData*) handle; \
|
||||
if (variable == NULL || variable->canari != UAVTALK_CANARI) { \
|
||||
failcommand; \
|
||||
}
|
||||
|
||||
#endif // UAVTALK__PRIV_H
|
||||
/**
|
||||
* @}
|
||||
* @}
|
||||
*/
|
@ -30,113 +30,145 @@
|
||||
*/
|
||||
|
||||
#include "openpilot.h"
|
||||
#include "uavtalk_priv.h"
|
||||
|
||||
// Private constants
|
||||
#define SYNC_VAL 0x3C
|
||||
#define TYPE_MASK 0xF8
|
||||
#define TYPE_VER 0x20
|
||||
#define TYPE_OBJ (TYPE_VER | 0x00)
|
||||
#define TYPE_OBJ_REQ (TYPE_VER | 0x01)
|
||||
#define TYPE_OBJ_ACK (TYPE_VER | 0x02)
|
||||
#define TYPE_ACK (TYPE_VER | 0x03)
|
||||
#define TYPE_NACK (TYPE_VER | 0x04)
|
||||
|
||||
#define MIN_HEADER_LENGTH 8 // sync(1), type (1), size (2), object ID (4)
|
||||
#define MAX_HEADER_LENGTH 10 // sync(1), type (1), size (2), object ID (4), instance ID (2, not used in single objects)
|
||||
|
||||
#define CHECKSUM_LENGTH 1
|
||||
|
||||
#define MAX_PAYLOAD_LENGTH 256
|
||||
|
||||
#define MAX_PACKET_LENGTH (MAX_HEADER_LENGTH + MAX_PAYLOAD_LENGTH + CHECKSUM_LENGTH)
|
||||
|
||||
|
||||
// Private types
|
||||
typedef enum {STATE_SYNC, STATE_TYPE, STATE_SIZE, STATE_OBJID, STATE_INSTID, STATE_DATA, STATE_CS} RxState;
|
||||
|
||||
// Private variables
|
||||
static UAVTalkOutputStream outStream;
|
||||
static xSemaphoreHandle lock;
|
||||
static xSemaphoreHandle transLock;
|
||||
static xSemaphoreHandle respSema;
|
||||
static UAVObjHandle respObj;
|
||||
static uint16_t respInstId;
|
||||
static uint8_t rxBuffer[MAX_PACKET_LENGTH];
|
||||
static uint8_t txBuffer[MAX_PACKET_LENGTH];
|
||||
static UAVTalkStats stats;
|
||||
|
||||
// Private functions
|
||||
static int32_t objectTransaction(UAVObjHandle objectId, uint16_t instId, uint8_t type, int32_t timeout);
|
||||
static int32_t sendObject(UAVObjHandle obj, uint16_t instId, uint8_t type);
|
||||
static int32_t sendSingleObject(UAVObjHandle obj, uint16_t instId, uint8_t type);
|
||||
static int32_t sendNack(uint32_t objId);
|
||||
static int32_t receiveObject(uint8_t type, uint32_t objId, uint16_t instId, uint8_t* data, int32_t length);
|
||||
static void updateAck(UAVObjHandle obj, uint16_t instId);
|
||||
static int32_t objectTransaction(UAVTalkConnectionData *connection, UAVObjHandle objectId, uint16_t instId, uint8_t type, int32_t timeout);
|
||||
static int32_t sendObject(UAVTalkConnectionData *connection, UAVObjHandle obj, uint16_t instId, uint8_t type);
|
||||
static int32_t sendSingleObject(UAVTalkConnectionData *connection, UAVObjHandle obj, uint16_t instId, uint8_t type);
|
||||
static int32_t sendNack(UAVTalkConnectionData *connection, uint32_t objId);
|
||||
static int32_t receiveObject(UAVTalkConnectionData *connection, uint8_t type, uint32_t objId, uint16_t instId, uint8_t* data, int32_t length);
|
||||
static void updateAck(UAVTalkConnectionData *connection, UAVObjHandle obj, uint16_t instId);
|
||||
|
||||
/**
|
||||
* Initialize the UAVTalk library
|
||||
* \param[in] connection UAVTalkConnection to be used
|
||||
* \param[in] outputStream Function pointer that is called to send a data buffer
|
||||
* \return 0 Success
|
||||
* \return -1 Failure
|
||||
*/
|
||||
int32_t UAVTalkInitialize(UAVTalkOutputStream outputStream)
|
||||
UAVTalkConnection UAVTalkInitialize(UAVTalkOutputStream outputStream, uint32_t maxPacketSize)
|
||||
{
|
||||
outStream = outputStream;
|
||||
lock = xSemaphoreCreateRecursiveMutex();
|
||||
transLock = xSemaphoreCreateRecursiveMutex();
|
||||
vSemaphoreCreateBinary(respSema);
|
||||
xSemaphoreTake(respSema, 0); // reset to zero
|
||||
UAVTalkResetStats();
|
||||
if (maxPacketSize<1) return 0;
|
||||
// allocate object
|
||||
UAVTalkConnectionData * connection = pvPortMalloc(sizeof(UAVTalkConnectionData));
|
||||
if (!connection) return 0;
|
||||
connection->canari = UAVTALK_CANARI;
|
||||
connection->iproc.rxPacketLength = 0;
|
||||
connection->iproc.state = UAVTALK_STATE_SYNC;
|
||||
connection->outStream = outputStream;
|
||||
connection->lock = xSemaphoreCreateRecursiveMutex();
|
||||
connection->transLock = xSemaphoreCreateRecursiveMutex();
|
||||
connection->txSize = maxPacketSize;
|
||||
// allocate buffers
|
||||
connection->rxBuffer = pvPortMalloc(UAVTALK_MAX_PACKET_LENGTH);
|
||||
if (!connection->rxBuffer) return 0;
|
||||
connection->txBuffer = pvPortMalloc(UAVTALK_MAX_PACKET_LENGTH);
|
||||
if (!connection->txBuffer) return 0;
|
||||
vSemaphoreCreateBinary(connection->respSema);
|
||||
xSemaphoreTake(connection->respSema, 0); // reset to zero
|
||||
UAVTalkResetStats( (UAVTalkConnection) connection );
|
||||
return (UAVTalkConnection) connection;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the communication output stream
|
||||
* \param[in] connection UAVTalkConnection to be used
|
||||
* \param[in] outputStream Function pointer that is called to send a data buffer
|
||||
* \return 0 Success
|
||||
* \return -1 Failure
|
||||
*/
|
||||
int32_t UAVTalkSetOutputStream(UAVTalkConnection connectionHandle, UAVTalkOutputStream outputStream)
|
||||
{
|
||||
|
||||
UAVTalkConnectionData *connection;
|
||||
CHECKCONHANDLE(connectionHandle,connection,return -1);
|
||||
|
||||
// Lock
|
||||
xSemaphoreTakeRecursive(connection->lock, portMAX_DELAY);
|
||||
|
||||
// set output stream
|
||||
connection->outStream = outputStream;
|
||||
|
||||
// Release lock
|
||||
xSemaphoreGiveRecursive(connection->lock);
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Get current output stream
|
||||
* \param[in] connection UAVTalkConnection to be used
|
||||
* @return UAVTarlkOutputStream the output stream used
|
||||
*/
|
||||
UAVTalkOutputStream UAVTalkGetOutputStream(UAVTalkConnection connectionHandle)
|
||||
{
|
||||
UAVTalkConnectionData *connection;
|
||||
CHECKCONHANDLE(connectionHandle,connection,return NULL);
|
||||
return connection->outStream;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get communication statistics counters
|
||||
* \param[in] connection UAVTalkConnection to be used
|
||||
* @param[out] statsOut Statistics counters
|
||||
*/
|
||||
void UAVTalkGetStats(UAVTalkStats* statsOut)
|
||||
void UAVTalkGetStats(UAVTalkConnection connectionHandle, UAVTalkStats* statsOut)
|
||||
{
|
||||
UAVTalkConnectionData *connection;
|
||||
CHECKCONHANDLE(connectionHandle,connection,return );
|
||||
|
||||
// Lock
|
||||
xSemaphoreTakeRecursive(lock, portMAX_DELAY);
|
||||
xSemaphoreTakeRecursive(connection->lock, portMAX_DELAY);
|
||||
|
||||
// Copy stats
|
||||
memcpy(statsOut, &stats, sizeof(UAVTalkStats));
|
||||
memcpy(statsOut, &connection->stats, sizeof(UAVTalkStats));
|
||||
|
||||
// Release lock
|
||||
xSemaphoreGiveRecursive(lock);
|
||||
xSemaphoreGiveRecursive(connection->lock);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset the statistics counters.
|
||||
* \param[in] connection UAVTalkConnection to be used
|
||||
*/
|
||||
void UAVTalkResetStats()
|
||||
void UAVTalkResetStats(UAVTalkConnection connectionHandle)
|
||||
{
|
||||
UAVTalkConnectionData *connection;
|
||||
CHECKCONHANDLE(connectionHandle,connection,return);
|
||||
|
||||
// Lock
|
||||
xSemaphoreTakeRecursive(lock, portMAX_DELAY);
|
||||
xSemaphoreTakeRecursive(connection->lock, portMAX_DELAY);
|
||||
|
||||
// Clear stats
|
||||
memset(&stats, 0, sizeof(UAVTalkStats));
|
||||
memset(&connection->stats, 0, sizeof(UAVTalkStats));
|
||||
|
||||
// Release lock
|
||||
xSemaphoreGiveRecursive(lock);
|
||||
xSemaphoreGiveRecursive(connection->lock);
|
||||
}
|
||||
|
||||
/**
|
||||
* Request an update for the specified object, on success the object data would have been
|
||||
* updated by the GCS.
|
||||
* \param[in] connection UAVTalkConnection to be used
|
||||
* \param[in] obj Object to update
|
||||
* \param[in] instId The instance ID or UAVOBJ_ALL_INSTANCES for all instances.
|
||||
* \param[in] timeout Time to wait for the response, when zero it will return immediately
|
||||
* \return 0 Success
|
||||
* \return -1 Failure
|
||||
*/
|
||||
int32_t UAVTalkSendObjectRequest(UAVObjHandle obj, uint16_t instId, int32_t timeout)
|
||||
int32_t UAVTalkSendObjectRequest(UAVTalkConnection connectionHandle, UAVObjHandle obj, uint16_t instId, int32_t timeout)
|
||||
{
|
||||
return objectTransaction(obj, instId, TYPE_OBJ_REQ, timeout);
|
||||
UAVTalkConnectionData *connection;
|
||||
CHECKCONHANDLE(connectionHandle,connection,return -1);
|
||||
return objectTransaction(connection, obj, instId, UAVTALK_TYPE_OBJ_REQ, timeout);
|
||||
}
|
||||
|
||||
/**
|
||||
* Send the specified object through the telemetry link.
|
||||
* \param[in] connection UAVTalkConnection to be used
|
||||
* \param[in] obj Object to send
|
||||
* \param[in] instId The instance ID or UAVOBJ_ALL_INSTANCES for all instances.
|
||||
* \param[in] acked Selects if an ack is required (1:ack required, 0: ack not required)
|
||||
@ -144,69 +176,72 @@ int32_t UAVTalkSendObjectRequest(UAVObjHandle obj, uint16_t instId, int32_t time
|
||||
* \return 0 Success
|
||||
* \return -1 Failure
|
||||
*/
|
||||
int32_t UAVTalkSendObject(UAVObjHandle obj, uint16_t instId, uint8_t acked, int32_t timeoutMs)
|
||||
int32_t UAVTalkSendObject(UAVTalkConnection connectionHandle, UAVObjHandle obj, uint16_t instId, uint8_t acked, int32_t timeoutMs)
|
||||
{
|
||||
UAVTalkConnectionData *connection;
|
||||
CHECKCONHANDLE(connectionHandle,connection,return -1);
|
||||
// Send object
|
||||
if (acked == 1)
|
||||
{
|
||||
return objectTransaction(obj, instId, TYPE_OBJ_ACK, timeoutMs);
|
||||
return objectTransaction(connection, obj, instId, UAVTALK_TYPE_OBJ_ACK, timeoutMs);
|
||||
}
|
||||
else
|
||||
{
|
||||
return objectTransaction(obj, instId, TYPE_OBJ, timeoutMs);
|
||||
return objectTransaction(connection, obj, instId, UAVTALK_TYPE_OBJ, timeoutMs);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the requested transaction on an object.
|
||||
* \param[in] connection UAVTalkConnection to be used
|
||||
* \param[in] obj Object
|
||||
* \param[in] instId The instance ID of UAVOBJ_ALL_INSTANCES for all instances.
|
||||
* \param[in] type Transaction type
|
||||
* TYPE_OBJ: send object,
|
||||
* TYPE_OBJ_REQ: request object update
|
||||
* TYPE_OBJ_ACK: send object with an ack
|
||||
* UAVTALK_TYPE_OBJ: send object,
|
||||
* UAVTALK_TYPE_OBJ_REQ: request object update
|
||||
* UAVTALK_TYPE_OBJ_ACK: send object with an ack
|
||||
* \return 0 Success
|
||||
* \return -1 Failure
|
||||
*/
|
||||
static int32_t objectTransaction(UAVObjHandle obj, uint16_t instId, uint8_t type, int32_t timeoutMs)
|
||||
static int32_t objectTransaction(UAVTalkConnectionData *connection, UAVObjHandle obj, uint16_t instId, uint8_t type, int32_t timeoutMs)
|
||||
{
|
||||
int32_t respReceived;
|
||||
|
||||
// Send object depending on if a response is needed
|
||||
if (type == TYPE_OBJ_ACK || type == TYPE_OBJ_REQ)
|
||||
if (type == UAVTALK_TYPE_OBJ_ACK || type == UAVTALK_TYPE_OBJ_REQ)
|
||||
{
|
||||
// Get transaction lock (will block if a transaction is pending)
|
||||
xSemaphoreTakeRecursive(transLock, portMAX_DELAY);
|
||||
xSemaphoreTakeRecursive(connection->transLock, portMAX_DELAY);
|
||||
// Send object
|
||||
xSemaphoreTakeRecursive(lock, portMAX_DELAY);
|
||||
respObj = obj;
|
||||
respInstId = instId;
|
||||
sendObject(obj, instId, type);
|
||||
xSemaphoreGiveRecursive(lock);
|
||||
xSemaphoreTakeRecursive(connection->lock, portMAX_DELAY);
|
||||
connection->respObj = obj;
|
||||
connection->respInstId = instId;
|
||||
sendObject(connection, obj, instId, type);
|
||||
xSemaphoreGiveRecursive(connection->lock);
|
||||
// Wait for response (or timeout)
|
||||
respReceived = xSemaphoreTake(respSema, timeoutMs/portTICK_RATE_MS);
|
||||
respReceived = xSemaphoreTake(connection->respSema, timeoutMs/portTICK_RATE_MS);
|
||||
// Check if a response was received
|
||||
if (respReceived == pdFALSE)
|
||||
{
|
||||
// Cancel transaction
|
||||
xSemaphoreTakeRecursive(lock, portMAX_DELAY);
|
||||
xSemaphoreTake(respSema, 0); // non blocking call to make sure the value is reset to zero (binary sema)
|
||||
respObj = 0;
|
||||
xSemaphoreGiveRecursive(lock);
|
||||
xSemaphoreGiveRecursive(transLock);
|
||||
xSemaphoreTakeRecursive(connection->lock, portMAX_DELAY);
|
||||
xSemaphoreTake(connection->respSema, 0); // non blocking call to make sure the value is reset to zero (binary sema)
|
||||
connection->respObj = 0;
|
||||
xSemaphoreGiveRecursive(connection->lock);
|
||||
xSemaphoreGiveRecursive(connection->transLock);
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
xSemaphoreGiveRecursive(transLock);
|
||||
xSemaphoreGiveRecursive(connection->transLock);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
else if (type == TYPE_OBJ)
|
||||
else if (type == UAVTALK_TYPE_OBJ)
|
||||
{
|
||||
xSemaphoreTakeRecursive(lock, portMAX_DELAY);
|
||||
sendObject(obj, instId, TYPE_OBJ);
|
||||
xSemaphoreGiveRecursive(lock);
|
||||
xSemaphoreTakeRecursive(connection->lock, portMAX_DELAY);
|
||||
sendObject(connection, obj, instId, UAVTALK_TYPE_OBJ);
|
||||
xSemaphoreGiveRecursive(connection->lock);
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
@ -217,222 +252,214 @@ static int32_t objectTransaction(UAVObjHandle obj, uint16_t instId, uint8_t type
|
||||
|
||||
/**
|
||||
* Process an byte from the telemetry stream.
|
||||
* \param[in] connection UAVTalkConnection to be used
|
||||
* \param[in] rxbyte Received byte
|
||||
* \return 0 Success
|
||||
* \return -1 Failure
|
||||
*/
|
||||
int32_t UAVTalkProcessInputStream(uint8_t rxbyte)
|
||||
int32_t UAVTalkProcessInputStream(UAVTalkConnection connectionHandle, uint8_t rxbyte)
|
||||
{
|
||||
static UAVObjHandle obj;
|
||||
static uint8_t type;
|
||||
static uint16_t packet_size;
|
||||
static uint32_t objId;
|
||||
static uint16_t instId;
|
||||
static uint32_t length;
|
||||
static uint8_t cs, csRx;
|
||||
static int32_t rxCount;
|
||||
static RxState state = STATE_SYNC;
|
||||
static uint16_t rxPacketLength = 0;
|
||||
UAVTalkConnectionData *connection;
|
||||
CHECKCONHANDLE(connectionHandle,connection,return -1);
|
||||
|
||||
UAVTalkInputProcessor *iproc = &connection->iproc;
|
||||
++connection->stats.rxBytes;
|
||||
|
||||
++stats.rxBytes;
|
||||
|
||||
if (rxPacketLength < 0xffff)
|
||||
rxPacketLength++; // update packet byte count
|
||||
if (iproc->rxPacketLength < 0xffff)
|
||||
iproc->rxPacketLength++; // update packet byte count
|
||||
|
||||
// Receive state machine
|
||||
switch (state)
|
||||
switch (iproc->state)
|
||||
{
|
||||
case STATE_SYNC:
|
||||
if (rxbyte != SYNC_VAL)
|
||||
case UAVTALK_STATE_SYNC:
|
||||
if (rxbyte != UAVTALK_SYNC_VAL)
|
||||
break;
|
||||
|
||||
// Initialize and update the CRC
|
||||
cs = PIOS_CRC_updateByte(0, rxbyte);
|
||||
iproc->cs = PIOS_CRC_updateByte(0, rxbyte);
|
||||
|
||||
rxPacketLength = 1;
|
||||
iproc->rxPacketLength = 1;
|
||||
|
||||
state = STATE_TYPE;
|
||||
iproc->state = UAVTALK_STATE_TYPE;
|
||||
break;
|
||||
|
||||
case STATE_TYPE:
|
||||
case UAVTALK_STATE_TYPE:
|
||||
|
||||
// update the CRC
|
||||
cs = PIOS_CRC_updateByte(cs, rxbyte);
|
||||
iproc->cs = PIOS_CRC_updateByte(iproc->cs, rxbyte);
|
||||
|
||||
if ((rxbyte & TYPE_MASK) != TYPE_VER)
|
||||
if ((rxbyte & UAVTALK_TYPE_MASK) != UAVTALK_TYPE_VER)
|
||||
{
|
||||
state = STATE_SYNC;
|
||||
iproc->state = UAVTALK_STATE_SYNC;
|
||||
break;
|
||||
}
|
||||
|
||||
type = rxbyte;
|
||||
iproc->type = rxbyte;
|
||||
|
||||
packet_size = 0;
|
||||
iproc->packet_size = 0;
|
||||
|
||||
state = STATE_SIZE;
|
||||
rxCount = 0;
|
||||
iproc->state = UAVTALK_STATE_SIZE;
|
||||
iproc->rxCount = 0;
|
||||
break;
|
||||
|
||||
case STATE_SIZE:
|
||||
case UAVTALK_STATE_SIZE:
|
||||
|
||||
// update the CRC
|
||||
cs = PIOS_CRC_updateByte(cs, rxbyte);
|
||||
iproc->cs = PIOS_CRC_updateByte(iproc->cs, rxbyte);
|
||||
|
||||
if (rxCount == 0)
|
||||
if (iproc->rxCount == 0)
|
||||
{
|
||||
packet_size += rxbyte;
|
||||
rxCount++;
|
||||
iproc->packet_size += rxbyte;
|
||||
iproc->rxCount++;
|
||||
break;
|
||||
}
|
||||
|
||||
packet_size += rxbyte << 8;
|
||||
iproc->packet_size += rxbyte << 8;
|
||||
|
||||
if (packet_size < MIN_HEADER_LENGTH || packet_size > MAX_HEADER_LENGTH + MAX_PAYLOAD_LENGTH)
|
||||
if (iproc->packet_size < UAVTALK_MIN_HEADER_LENGTH || iproc->packet_size > UAVTALK_MAX_HEADER_LENGTH + UAVTALK_MAX_PAYLOAD_LENGTH)
|
||||
{ // incorrect packet size
|
||||
state = STATE_SYNC;
|
||||
iproc->state = UAVTALK_STATE_SYNC;
|
||||
break;
|
||||
}
|
||||
|
||||
rxCount = 0;
|
||||
objId = 0;
|
||||
state = STATE_OBJID;
|
||||
iproc->rxCount = 0;
|
||||
iproc->objId = 0;
|
||||
iproc->state = UAVTALK_STATE_OBJID;
|
||||
break;
|
||||
|
||||
case STATE_OBJID:
|
||||
case UAVTALK_STATE_OBJID:
|
||||
|
||||
// update the CRC
|
||||
cs = PIOS_CRC_updateByte(cs, rxbyte);
|
||||
iproc->cs = PIOS_CRC_updateByte(iproc->cs, rxbyte);
|
||||
|
||||
objId += rxbyte << (8*(rxCount++));
|
||||
iproc->objId += rxbyte << (8*(iproc->rxCount++));
|
||||
|
||||
if (rxCount < 4)
|
||||
if (iproc->rxCount < 4)
|
||||
break;
|
||||
|
||||
// Search for object, if not found reset state machine
|
||||
// except if we got a OBJ_REQ for an object which does not
|
||||
// exist, in which case we'll send a NACK
|
||||
|
||||
obj = UAVObjGetByID(objId);
|
||||
if (obj == 0 && type != TYPE_OBJ_REQ)
|
||||
iproc->obj = UAVObjGetByID(iproc->objId);
|
||||
if (iproc->obj == 0 && iproc->type != UAVTALK_TYPE_OBJ_REQ)
|
||||
{
|
||||
stats.rxErrors++;
|
||||
state = STATE_SYNC;
|
||||
connection->stats.rxErrors++;
|
||||
iproc->state = UAVTALK_STATE_SYNC;
|
||||
break;
|
||||
}
|
||||
|
||||
// Determine data length
|
||||
if (type == TYPE_OBJ_REQ || type == TYPE_ACK || type == TYPE_NACK)
|
||||
length = 0;
|
||||
if (iproc->type == UAVTALK_TYPE_OBJ_REQ || iproc->type == UAVTALK_TYPE_ACK || iproc->type == UAVTALK_TYPE_NACK)
|
||||
iproc->length = 0;
|
||||
else
|
||||
length = UAVObjGetNumBytes(obj);
|
||||
iproc->length = UAVObjGetNumBytes(iproc->obj);
|
||||
|
||||
// Check length and determine next state
|
||||
if (length >= MAX_PAYLOAD_LENGTH)
|
||||
if (iproc->length >= UAVTALK_MAX_PAYLOAD_LENGTH)
|
||||
{
|
||||
stats.rxErrors++;
|
||||
state = STATE_SYNC;
|
||||
connection->stats.rxErrors++;
|
||||
iproc->state = UAVTALK_STATE_SYNC;
|
||||
break;
|
||||
}
|
||||
|
||||
// Check the lengths match
|
||||
if ((rxPacketLength + length) != packet_size)
|
||||
if ((iproc->rxPacketLength + iproc->length) != iproc->packet_size)
|
||||
{ // packet error - mismatched packet size
|
||||
stats.rxErrors++;
|
||||
state = STATE_SYNC;
|
||||
connection->stats.rxErrors++;
|
||||
iproc->state = UAVTALK_STATE_SYNC;
|
||||
break;
|
||||
}
|
||||
|
||||
instId = 0;
|
||||
if (obj == 0)
|
||||
iproc->instId = 0;
|
||||
if (iproc->obj == 0)
|
||||
{
|
||||
// If this is a NACK, we skip to Checksum
|
||||
state = STATE_CS;
|
||||
rxCount = 0;
|
||||
iproc->state = UAVTALK_STATE_CS;
|
||||
iproc->rxCount = 0;
|
||||
|
||||
}
|
||||
// Check if this is a single instance object (i.e. if the instance ID field is coming next)
|
||||
else if (UAVObjIsSingleInstance(obj))
|
||||
else if (UAVObjIsSingleInstance(iproc->obj))
|
||||
{
|
||||
// If there is a payload get it, otherwise receive checksum
|
||||
if (length > 0)
|
||||
state = STATE_DATA;
|
||||
if (iproc->length > 0)
|
||||
iproc->state = UAVTALK_STATE_DATA;
|
||||
else
|
||||
state = STATE_CS;
|
||||
iproc->state = UAVTALK_STATE_CS;
|
||||
|
||||
rxCount = 0;
|
||||
iproc->rxCount = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
state = STATE_INSTID;
|
||||
rxCount = 0;
|
||||
iproc->state = UAVTALK_STATE_INSTID;
|
||||
iproc->rxCount = 0;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case STATE_INSTID:
|
||||
case UAVTALK_STATE_INSTID:
|
||||
|
||||
// update the CRC
|
||||
cs = PIOS_CRC_updateByte(cs, rxbyte);
|
||||
iproc->cs = PIOS_CRC_updateByte(iproc->cs, rxbyte);
|
||||
|
||||
instId += rxbyte << (8*(rxCount++));
|
||||
iproc->instId += rxbyte << (8*(iproc->rxCount++));
|
||||
|
||||
if (rxCount < 2)
|
||||
if (iproc->rxCount < 2)
|
||||
break;
|
||||
|
||||
rxCount = 0;
|
||||
iproc->rxCount = 0;
|
||||
|
||||
// If there is a payload get it, otherwise receive checksum
|
||||
if (length > 0)
|
||||
state = STATE_DATA;
|
||||
if (iproc->length > 0)
|
||||
iproc->state = UAVTALK_STATE_DATA;
|
||||
else
|
||||
state = STATE_CS;
|
||||
iproc->state = UAVTALK_STATE_CS;
|
||||
|
||||
break;
|
||||
|
||||
case STATE_DATA:
|
||||
case UAVTALK_STATE_DATA:
|
||||
|
||||
// update the CRC
|
||||
cs = PIOS_CRC_updateByte(cs, rxbyte);
|
||||
iproc->cs = PIOS_CRC_updateByte(iproc->cs, rxbyte);
|
||||
|
||||
rxBuffer[rxCount++] = rxbyte;
|
||||
if (rxCount < length)
|
||||
connection->rxBuffer[iproc->rxCount++] = rxbyte;
|
||||
if (iproc->rxCount < iproc->length)
|
||||
break;
|
||||
|
||||
state = STATE_CS;
|
||||
rxCount = 0;
|
||||
iproc->state = UAVTALK_STATE_CS;
|
||||
iproc->rxCount = 0;
|
||||
break;
|
||||
|
||||
case STATE_CS:
|
||||
case UAVTALK_STATE_CS:
|
||||
|
||||
// the CRC byte
|
||||
csRx = rxbyte;
|
||||
|
||||
if (csRx != cs)
|
||||
if (rxbyte != iproc->cs)
|
||||
{ // packet error - faulty CRC
|
||||
stats.rxErrors++;
|
||||
state = STATE_SYNC;
|
||||
connection->stats.rxErrors++;
|
||||
iproc->state = UAVTALK_STATE_SYNC;
|
||||
break;
|
||||
}
|
||||
|
||||
if (rxPacketLength != (packet_size + 1))
|
||||
if (iproc->rxPacketLength != (iproc->packet_size + 1))
|
||||
{ // packet error - mismatched packet size
|
||||
stats.rxErrors++;
|
||||
state = STATE_SYNC;
|
||||
connection->stats.rxErrors++;
|
||||
iproc->state = UAVTALK_STATE_SYNC;
|
||||
break;
|
||||
}
|
||||
|
||||
xSemaphoreTakeRecursive(lock, portMAX_DELAY);
|
||||
receiveObject(type, objId, instId, rxBuffer, length);
|
||||
stats.rxObjectBytes += length;
|
||||
stats.rxObjects++;
|
||||
xSemaphoreGiveRecursive(lock);
|
||||
xSemaphoreTakeRecursive(connection->lock, portMAX_DELAY);
|
||||
receiveObject(connection, iproc->type, iproc->objId, iproc->instId, connection->rxBuffer, iproc->length);
|
||||
connection->stats.rxObjectBytes += iproc->length;
|
||||
connection->stats.rxObjects++;
|
||||
xSemaphoreGiveRecursive(connection->lock);
|
||||
|
||||
state = STATE_SYNC;
|
||||
iproc->state = UAVTALK_STATE_SYNC;
|
||||
break;
|
||||
|
||||
default:
|
||||
stats.rxErrors++;
|
||||
state = STATE_SYNC;
|
||||
connection->stats.rxErrors++;
|
||||
iproc->state = UAVTALK_STATE_SYNC;
|
||||
}
|
||||
|
||||
// Done
|
||||
@ -441,7 +468,8 @@ int32_t UAVTalkProcessInputStream(uint8_t rxbyte)
|
||||
|
||||
/**
|
||||
* Receive an object. This function process objects received through the telemetry stream.
|
||||
* \param[in] type Type of received message (TYPE_OBJ, TYPE_OBJ_REQ, TYPE_OBJ_ACK, TYPE_ACK, TYPE_NACK)
|
||||
* \param[in] connection UAVTalkConnection to be used
|
||||
* \param[in] type Type of received message (UAVTALK_TYPE_OBJ, UAVTALK_TYPE_OBJ_REQ, UAVTALK_TYPE_OBJ_ACK, UAVTALK_TYPE_ACK, UAVTALK_TYPE_NACK)
|
||||
* \param[in] objId ID of the object to work on
|
||||
* \param[in] instId The instance ID of UAVOBJ_ALL_INSTANCES for all instances.
|
||||
* \param[in] data Data buffer
|
||||
@ -449,9 +477,9 @@ int32_t UAVTalkProcessInputStream(uint8_t rxbyte)
|
||||
* \return 0 Success
|
||||
* \return -1 Failure
|
||||
*/
|
||||
static int32_t receiveObject(uint8_t type, uint32_t objId, uint16_t instId, uint8_t* data, int32_t length)
|
||||
static int32_t receiveObject(UAVTalkConnectionData *connection, uint8_t type, uint32_t objId, uint16_t instId, uint8_t* data, int32_t length)
|
||||
{
|
||||
static UAVObjHandle obj;
|
||||
UAVObjHandle obj;
|
||||
int32_t ret = 0;
|
||||
|
||||
// Get the handle to the Object. Will be zero
|
||||
@ -460,21 +488,21 @@ static int32_t receiveObject(uint8_t type, uint32_t objId, uint16_t instId, uint
|
||||
|
||||
// Process message type
|
||||
switch (type) {
|
||||
case TYPE_OBJ:
|
||||
case UAVTALK_TYPE_OBJ:
|
||||
// All instances, not allowed for OBJ messages
|
||||
if (instId != UAVOBJ_ALL_INSTANCES)
|
||||
{
|
||||
// Unpack object, if the instance does not exist it will be created!
|
||||
UAVObjUnpack(obj, instId, data);
|
||||
// Check if an ack is pending
|
||||
updateAck(obj, instId);
|
||||
updateAck(connection, obj, instId);
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = -1;
|
||||
}
|
||||
break;
|
||||
case TYPE_OBJ_ACK:
|
||||
case UAVTALK_TYPE_OBJ_ACK:
|
||||
// All instances, not allowed for OBJ_ACK messages
|
||||
if (instId != UAVOBJ_ALL_INSTANCES)
|
||||
{
|
||||
@ -482,7 +510,7 @@ static int32_t receiveObject(uint8_t type, uint32_t objId, uint16_t instId, uint
|
||||
if ( UAVObjUnpack(obj, instId, data) == 0 )
|
||||
{
|
||||
// Transmit ACK
|
||||
sendObject(obj, instId, TYPE_ACK);
|
||||
sendObject(connection, obj, instId, UAVTALK_TYPE_ACK);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -494,22 +522,22 @@ static int32_t receiveObject(uint8_t type, uint32_t objId, uint16_t instId, uint
|
||||
ret = -1;
|
||||
}
|
||||
break;
|
||||
case TYPE_OBJ_REQ:
|
||||
case UAVTALK_TYPE_OBJ_REQ:
|
||||
// Send requested object if message is of type OBJ_REQ
|
||||
if (obj == 0)
|
||||
sendNack(objId);
|
||||
sendNack(connection, objId);
|
||||
else
|
||||
sendObject(obj, instId, TYPE_OBJ);
|
||||
sendObject(connection, obj, instId, UAVTALK_TYPE_OBJ);
|
||||
break;
|
||||
case TYPE_NACK:
|
||||
case UAVTALK_TYPE_NACK:
|
||||
// Do nothing on flight side, let it time out.
|
||||
break;
|
||||
case TYPE_ACK:
|
||||
case UAVTALK_TYPE_ACK:
|
||||
// All instances, not allowed for ACK messages
|
||||
if (instId != UAVOBJ_ALL_INSTANCES)
|
||||
{
|
||||
// Check if an ack is pending
|
||||
updateAck(obj, instId);
|
||||
updateAck(connection, obj, instId);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -525,25 +553,29 @@ static int32_t receiveObject(uint8_t type, uint32_t objId, uint16_t instId, uint
|
||||
|
||||
/**
|
||||
* Check if an ack is pending on an object and give response semaphore
|
||||
* \param[in] connection UAVTalkConnection to be used
|
||||
* \param[in] obj Object
|
||||
* \param[in] instId The instance ID of UAVOBJ_ALL_INSTANCES for all instances.
|
||||
*/
|
||||
static void updateAck(UAVObjHandle obj, uint16_t instId)
|
||||
static void updateAck(UAVTalkConnectionData *connection, UAVObjHandle obj, uint16_t instId)
|
||||
{
|
||||
if (respObj == obj && (respInstId == instId || respInstId == UAVOBJ_ALL_INSTANCES))
|
||||
if (connection->respObj == obj && (connection->respInstId == instId || connection->respInstId == UAVOBJ_ALL_INSTANCES))
|
||||
{
|
||||
xSemaphoreGive(respSema);
|
||||
respObj = 0;
|
||||
xSemaphoreGive(connection->respSema);
|
||||
connection->respObj = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Send an object through the telemetry link.
|
||||
* \param[in] connection UAVTalkConnection to be used
|
||||
* \param[in] obj Object handle to send
|
||||
* \param[in] instId The instance ID or UAVOBJ_ALL_INSTANCES for all instances
|
||||
* \param[in] type Transaction type
|
||||
* \return 0 Success
|
||||
* \return -1 Failure
|
||||
*/
|
||||
static int32_t sendObject(UAVObjHandle obj, uint16_t instId, uint8_t type)
|
||||
static int32_t sendObject(UAVTalkConnectionData *connection, UAVObjHandle obj, uint16_t instId, uint8_t type)
|
||||
{
|
||||
uint32_t numInst;
|
||||
uint32_t n;
|
||||
@ -555,7 +587,7 @@ static int32_t sendObject(UAVObjHandle obj, uint16_t instId, uint8_t type)
|
||||
}
|
||||
|
||||
// Process message type
|
||||
if ( type == TYPE_OBJ || type == TYPE_OBJ_ACK )
|
||||
if ( type == UAVTALK_TYPE_OBJ || type == UAVTALK_TYPE_OBJ_ACK )
|
||||
{
|
||||
if (instId == UAVOBJ_ALL_INSTANCES)
|
||||
{
|
||||
@ -564,24 +596,24 @@ static int32_t sendObject(UAVObjHandle obj, uint16_t instId, uint8_t type)
|
||||
// Send all instances
|
||||
for (n = 0; n < numInst; ++n)
|
||||
{
|
||||
sendSingleObject(obj, n, type);
|
||||
sendSingleObject(connection, obj, n, type);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
return sendSingleObject(obj, instId, type);
|
||||
return sendSingleObject(connection, obj, instId, type);
|
||||
}
|
||||
}
|
||||
else if (type == TYPE_OBJ_REQ)
|
||||
else if (type == UAVTALK_TYPE_OBJ_REQ)
|
||||
{
|
||||
return sendSingleObject(obj, instId, TYPE_OBJ_REQ);
|
||||
return sendSingleObject(connection, obj, instId, UAVTALK_TYPE_OBJ_REQ);
|
||||
}
|
||||
else if (type == TYPE_ACK)
|
||||
else if (type == UAVTALK_TYPE_ACK)
|
||||
{
|
||||
if ( instId != UAVOBJ_ALL_INSTANCES )
|
||||
{
|
||||
return sendSingleObject(obj, instId, TYPE_ACK);
|
||||
return sendSingleObject(connection, obj, instId, UAVTALK_TYPE_ACK);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -596,13 +628,14 @@ static int32_t sendObject(UAVObjHandle obj, uint16_t instId, uint8_t type)
|
||||
|
||||
/**
|
||||
* Send an object through the telemetry link.
|
||||
* \param[in] connection UAVTalkConnection to be used
|
||||
* \param[in] obj Object handle to send
|
||||
* \param[in] instId The instance ID (can NOT be UAVOBJ_ALL_INSTANCES, use sendObject() instead)
|
||||
* \param[in] type Transaction type
|
||||
* \return 0 Success
|
||||
* \return -1 Failure
|
||||
*/
|
||||
static int32_t sendSingleObject(UAVObjHandle obj, uint16_t instId, uint8_t type)
|
||||
static int32_t sendSingleObject(UAVTalkConnectionData *connection, UAVObjHandle obj, uint16_t instId, uint8_t type)
|
||||
{
|
||||
int32_t length;
|
||||
int32_t dataOffset;
|
||||
@ -610,13 +643,13 @@ static int32_t sendSingleObject(UAVObjHandle obj, uint16_t instId, uint8_t type)
|
||||
|
||||
// Setup type and object id fields
|
||||
objId = UAVObjGetID(obj);
|
||||
txBuffer[0] = SYNC_VAL; // sync byte
|
||||
txBuffer[1] = type;
|
||||
connection->txBuffer[0] = UAVTALK_SYNC_VAL; // sync byte
|
||||
connection->txBuffer[1] = type;
|
||||
// data length inserted here below
|
||||
txBuffer[4] = (uint8_t)(objId & 0xFF);
|
||||
txBuffer[5] = (uint8_t)((objId >> 8) & 0xFF);
|
||||
txBuffer[6] = (uint8_t)((objId >> 16) & 0xFF);
|
||||
txBuffer[7] = (uint8_t)((objId >> 24) & 0xFF);
|
||||
connection->txBuffer[4] = (uint8_t)(objId & 0xFF);
|
||||
connection->txBuffer[5] = (uint8_t)((objId >> 8) & 0xFF);
|
||||
connection->txBuffer[6] = (uint8_t)((objId >> 16) & 0xFF);
|
||||
connection->txBuffer[7] = (uint8_t)((objId >> 24) & 0xFF);
|
||||
|
||||
// Setup instance ID if one is required
|
||||
if (UAVObjIsSingleInstance(obj))
|
||||
@ -625,13 +658,13 @@ static int32_t sendSingleObject(UAVObjHandle obj, uint16_t instId, uint8_t type)
|
||||
}
|
||||
else
|
||||
{
|
||||
txBuffer[8] = (uint8_t)(instId & 0xFF);
|
||||
txBuffer[9] = (uint8_t)((instId >> 8) & 0xFF);
|
||||
connection->txBuffer[8] = (uint8_t)(instId & 0xFF);
|
||||
connection->txBuffer[9] = (uint8_t)((instId >> 8) & 0xFF);
|
||||
dataOffset = 10;
|
||||
}
|
||||
|
||||
// Determine data length
|
||||
if (type == TYPE_OBJ_REQ || type == TYPE_ACK)
|
||||
if (type == UAVTALK_TYPE_OBJ_REQ || type == UAVTALK_TYPE_ACK)
|
||||
{
|
||||
length = 0;
|
||||
}
|
||||
@ -641,7 +674,7 @@ static int32_t sendSingleObject(UAVObjHandle obj, uint16_t instId, uint8_t type)
|
||||
}
|
||||
|
||||
// Check length
|
||||
if (length >= MAX_PAYLOAD_LENGTH)
|
||||
if (length >= UAVTALK_MAX_PAYLOAD_LENGTH)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
@ -649,26 +682,34 @@ static int32_t sendSingleObject(UAVObjHandle obj, uint16_t instId, uint8_t type)
|
||||
// Copy data (if any)
|
||||
if (length > 0)
|
||||
{
|
||||
if ( UAVObjPack(obj, instId, &txBuffer[dataOffset]) < 0 )
|
||||
if ( UAVObjPack(obj, instId, &connection->txBuffer[dataOffset]) < 0 )
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
// Store the packet length
|
||||
txBuffer[2] = (uint8_t)((dataOffset+length) & 0xFF);
|
||||
txBuffer[3] = (uint8_t)(((dataOffset+length) >> 8) & 0xFF);
|
||||
connection->txBuffer[2] = (uint8_t)((dataOffset+length) & 0xFF);
|
||||
connection->txBuffer[3] = (uint8_t)(((dataOffset+length) >> 8) & 0xFF);
|
||||
|
||||
// Calculate checksum
|
||||
txBuffer[dataOffset+length] = PIOS_CRC_updateCRC(0, txBuffer, dataOffset+length);
|
||||
|
||||
// Send buffer
|
||||
if (outStream!=NULL) (*outStream)(txBuffer, dataOffset+length+CHECKSUM_LENGTH);
|
||||
connection->txBuffer[dataOffset+length] = PIOS_CRC_updateCRC(0, connection->txBuffer, dataOffset+length);
|
||||
|
||||
// Send buffer (partially if needed)
|
||||
uint32_t sent=0;
|
||||
while (sent < dataOffset+length+UAVTALK_CHECKSUM_LENGTH) {
|
||||
uint32_t sending = dataOffset+length+UAVTALK_CHECKSUM_LENGTH - sent;
|
||||
if ( sending > connection->txSize ) sending = connection->txSize;
|
||||
if ( connection->outStream != NULL ) {
|
||||
(*connection->outStream)(connection->txBuffer+sent, sending);
|
||||
}
|
||||
sent += sending;
|
||||
}
|
||||
|
||||
// Update stats
|
||||
++stats.txObjects;
|
||||
stats.txBytes += dataOffset+length+CHECKSUM_LENGTH;
|
||||
stats.txObjectBytes += length;
|
||||
++connection->stats.txObjects;
|
||||
connection->stats.txBytes += dataOffset+length+UAVTALK_CHECKSUM_LENGTH;
|
||||
connection->stats.txObjectBytes += length;
|
||||
|
||||
// Done
|
||||
return 0;
|
||||
@ -676,36 +717,37 @@ static int32_t sendSingleObject(UAVObjHandle obj, uint16_t instId, uint8_t type)
|
||||
|
||||
/**
|
||||
* Send a NACK through the telemetry link.
|
||||
* \param[in] connection UAVTalkConnection to be used
|
||||
* \param[in] objId Object ID to send a NACK for
|
||||
* \return 0 Success
|
||||
* \return -1 Failure
|
||||
*/
|
||||
static int32_t sendNack(uint32_t objId)
|
||||
static int32_t sendNack(UAVTalkConnectionData *connection, uint32_t objId)
|
||||
{
|
||||
int32_t dataOffset;
|
||||
|
||||
txBuffer[0] = SYNC_VAL; // sync byte
|
||||
txBuffer[1] = TYPE_NACK;
|
||||
connection->txBuffer[0] = UAVTALK_SYNC_VAL; // sync byte
|
||||
connection->txBuffer[1] = UAVTALK_TYPE_NACK;
|
||||
// data length inserted here below
|
||||
txBuffer[4] = (uint8_t)(objId & 0xFF);
|
||||
txBuffer[5] = (uint8_t)((objId >> 8) & 0xFF);
|
||||
txBuffer[6] = (uint8_t)((objId >> 16) & 0xFF);
|
||||
txBuffer[7] = (uint8_t)((objId >> 24) & 0xFF);
|
||||
connection->txBuffer[4] = (uint8_t)(objId & 0xFF);
|
||||
connection->txBuffer[5] = (uint8_t)((objId >> 8) & 0xFF);
|
||||
connection->txBuffer[6] = (uint8_t)((objId >> 16) & 0xFF);
|
||||
connection->txBuffer[7] = (uint8_t)((objId >> 24) & 0xFF);
|
||||
|
||||
dataOffset = 8;
|
||||
|
||||
// Store the packet length
|
||||
txBuffer[2] = (uint8_t)((dataOffset) & 0xFF);
|
||||
txBuffer[3] = (uint8_t)(((dataOffset) >> 8) & 0xFF);
|
||||
connection->txBuffer[2] = (uint8_t)((dataOffset) & 0xFF);
|
||||
connection->txBuffer[3] = (uint8_t)(((dataOffset) >> 8) & 0xFF);
|
||||
|
||||
// Calculate checksum
|
||||
txBuffer[dataOffset] = PIOS_CRC_updateCRC(0, txBuffer, dataOffset);
|
||||
connection->txBuffer[dataOffset] = PIOS_CRC_updateCRC(0, connection->txBuffer, dataOffset);
|
||||
|
||||
// Send buffer
|
||||
if (outStream!=NULL) (*outStream)(txBuffer, dataOffset+CHECKSUM_LENGTH);
|
||||
if (connection->outStream!=NULL) (*connection->outStream)(connection->txBuffer, dataOffset+UAVTALK_CHECKSUM_LENGTH);
|
||||
|
||||
// Update stats
|
||||
stats.txBytes += dataOffset+CHECKSUM_LENGTH;
|
||||
connection->stats.txBytes += dataOffset+UAVTALK_CHECKSUM_LENGTH;
|
||||
|
||||
// Done
|
||||
return 0;
|
||||
|
441
ground/openpilotgcs/src/plugins/config/camerastabilization.ui
Normal file
441
ground/openpilotgcs/src/plugins/config/camerastabilization.ui
Normal file
@ -0,0 +1,441 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>CameraStabilizationWidget</class>
|
||||
<widget class="QWidget" name="CameraStabilizationWidget">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>720</width>
|
||||
<height>567</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Form</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||
<item>
|
||||
<widget class="QCheckBox" name="enableCameraStabilization">
|
||||
<property name="text">
|
||||
<string>Enable CameraStabilization module</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_7">
|
||||
<property name="text">
|
||||
<string>After enabling the module, you must power cycle before using and configuring.</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="Line" name="line">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="groupBox">
|
||||
<property name="title">
|
||||
<string>Channel Ranges (number of degrees full range)</string>
|
||||
</property>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<layout class="QFormLayout" name="formLayout_2">
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="label_2">
|
||||
<property name="text">
|
||||
<string>Pitch</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="QLabel" name="label_3">
|
||||
<property name="text">
|
||||
<string>Yaw</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string>Roll</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QSpinBox" name="rollOutputRange">
|
||||
<property name="maximum">
|
||||
<number>180</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QSpinBox" name="pitchOutputRange">
|
||||
<property name="maximum">
|
||||
<number>180</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="1">
|
||||
<widget class="QSpinBox" name="yawOutputRange">
|
||||
<property name="maximum">
|
||||
<number>180</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_4">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>212</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="groupBox_2">
|
||||
<property name="title">
|
||||
<string>Channel Mapping (select output channel or none to disable)</string>
|
||||
</property>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||
<item>
|
||||
<layout class="QFormLayout" name="formLayout">
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="label_4">
|
||||
<property name="text">
|
||||
<string>Roll</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QComboBox" name="rollChannel">
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>None</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Channel 1</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Channel 2</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Channel 3</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Channel 4</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Channel 5</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Channel 6</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Channel 7</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Channel 8</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="1">
|
||||
<widget class="QComboBox" name="yawChannel">
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>None</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Channel 1</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Channel 2</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Channel 3</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Channel 4</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Channel 5</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Channel 6</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Channel 7</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Channel 8</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="QLabel" name="label_5">
|
||||
<property name="text">
|
||||
<string>Pitch</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="1">
|
||||
<widget class="QComboBox" name="pitchChannel">
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>None</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Channel 1</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Channel 2</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Channel 3</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Channel 4</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Channel 5</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Channel 6</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Channel 7</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Channel 8</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="0">
|
||||
<widget class="QLabel" name="label_6">
|
||||
<property name="text">
|
||||
<string>Yaw</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_5">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_3">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>212</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="verticalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="submitButtons">
|
||||
<item>
|
||||
<widget class="QFrame" name="frame">
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::StyledPanel</enum>
|
||||
</property>
|
||||
<property name="frameShadow">
|
||||
<enum>QFrame::Raised</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="camerastabilizationHelp">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>32</width>
|
||||
<height>32</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<kerning>true</kerning>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../coreplugin/core.qrc">
|
||||
<normaloff>:/core/images/helpicon.svg</normaloff>:/core/images/helpicon.svg</iconset>
|
||||
</property>
|
||||
<property name="iconSize">
|
||||
<size>
|
||||
<width>32</width>
|
||||
<height>32</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="shortcut">
|
||||
<string>Ctrl+S</string>
|
||||
</property>
|
||||
<property name="default">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="flat">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="camerastabilizationSaveRAM">
|
||||
<property name="toolTip">
|
||||
<string>Save settings to the board (RAM only).
|
||||
|
||||
This does not save the calibration settings, this is done using the
|
||||
specific calibration button on top of the screen.</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Apply</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="camerastabilizationSaveSD">
|
||||
<property name="toolTip">
|
||||
<string>Send settings to the board, and save to the non-volatile memory.</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Save</string>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources>
|
||||
<include location="../coreplugin/core.qrc"/>
|
||||
</resources>
|
||||
<connections/>
|
||||
</ui>
|
@ -37,7 +37,8 @@ HEADERS += configplugin.h \
|
||||
calibration.h \
|
||||
defaultattitudewidget.h \
|
||||
smartsavebutton.h \
|
||||
defaulthwsettingswidget.h
|
||||
defaulthwsettingswidget.h \
|
||||
configcamerastabilizationwidget.h
|
||||
|
||||
SOURCES += configplugin.cpp \
|
||||
configgadgetconfiguration.cpp \
|
||||
@ -65,7 +66,8 @@ SOURCES += configplugin.cpp \
|
||||
alignment-calibration.cpp \
|
||||
defaultattitudewidget.cpp \
|
||||
smartsavebutton.cpp \
|
||||
defaulthwsettingswidget.cpp
|
||||
defaulthwsettingswidget.cpp \
|
||||
configcamerastabilizationwidget.cpp
|
||||
|
||||
FORMS += \
|
||||
airframe.ui \
|
||||
@ -78,6 +80,11 @@ FORMS += \
|
||||
output.ui \
|
||||
ccattitude.ui \
|
||||
defaultattitude.ui \
|
||||
defaulthwsettings.ui
|
||||
defaulthwsettings.ui \
|
||||
camerastabilization.ui
|
||||
|
||||
RESOURCES += configgadget.qrc
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -0,0 +1,237 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
*
|
||||
* @file configcamerastabilizationwidget.cpp
|
||||
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
|
||||
* @addtogroup GCSPlugins GCS Plugins
|
||||
* @{
|
||||
* @addtogroup ConfigPlugin Config Plugin
|
||||
* @{
|
||||
* @brief The Configuration Gadget used to update settings in the firmware
|
||||
*****************************************************************************/
|
||||
/*
|
||||
* 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
|
||||
*/
|
||||
#include "configcamerastabilizationwidget.h"
|
||||
|
||||
#include <QDebug>
|
||||
#include <QTimer>
|
||||
#include <QStringList>
|
||||
#include <QtGui/QWidget>
|
||||
#include <QtGui/QTextEdit>
|
||||
#include <QtGui/QVBoxLayout>
|
||||
#include <QtGui/QPushButton>
|
||||
#include <QThread>
|
||||
#include <iostream>
|
||||
#include <QUrl>
|
||||
#include <QDesktopServices>
|
||||
|
||||
#include "camerastabsettings.h"
|
||||
#include "hwsettings.h"
|
||||
#include "mixersettings.h"
|
||||
|
||||
ConfigCameraStabilizationWidget::ConfigCameraStabilizationWidget(QWidget *parent) : ConfigTaskWidget(parent)
|
||||
{
|
||||
m_camerastabilization = new Ui_CameraStabilizationWidget();
|
||||
m_camerastabilization->setupUi(this);
|
||||
|
||||
connectUpdates();
|
||||
|
||||
// Connect buttons
|
||||
connect(m_camerastabilization->camerastabilizationSaveRAM,SIGNAL(clicked()),this,SLOT(applySettings()));
|
||||
connect(m_camerastabilization->camerastabilizationSaveSD,SIGNAL(clicked()),this,SLOT(saveSettings()));
|
||||
connect(m_camerastabilization->camerastabilizationHelp, SIGNAL(clicked()), this, SLOT(openHelp()));
|
||||
}
|
||||
|
||||
ConfigCameraStabilizationWidget::~ConfigCameraStabilizationWidget()
|
||||
{
|
||||
// Do nothing
|
||||
}
|
||||
|
||||
void ConfigCameraStabilizationWidget::connectUpdates()
|
||||
{
|
||||
// Now connect the widget to the StabilizationSettings object
|
||||
connect(MixerSettings::GetInstance(getObjectManager()),SIGNAL(objectUpdated(UAVObject*)),this,SLOT(refreshValues()));
|
||||
connect(CameraStabSettings::GetInstance(getObjectManager()),SIGNAL(objectUpdated(UAVObject*)),this,SLOT(refreshValues()));
|
||||
// TODO: This will need to support both CC and OP later
|
||||
connect(HwSettings::GetInstance(getObjectManager()),SIGNAL(objectUpdated(UAVObject*)),this,SLOT(refreshValues()));
|
||||
}
|
||||
|
||||
void ConfigCameraStabilizationWidget::disconnectUpdates()
|
||||
{
|
||||
// Now connect the widget to the StabilizationSettings object
|
||||
disconnect(MixerSettings::GetInstance(getObjectManager()),SIGNAL(objectUpdated(UAVObject*)),this,SLOT(refreshValues()));
|
||||
disconnect(CameraStabSettings::GetInstance(getObjectManager()),SIGNAL(objectUpdated(UAVObject*)),this,SLOT(refreshValues()));
|
||||
// TODO: This will need to support both CC and OP later
|
||||
disconnect(HwSettings::GetInstance(getObjectManager()),SIGNAL(objectUpdated(UAVObject*)),this,SLOT(refreshValues()));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Populate the gui settings into the appropriate
|
||||
* UAV structures
|
||||
*/
|
||||
void ConfigCameraStabilizationWidget::applySettings()
|
||||
{
|
||||
// Enable or disable the settings
|
||||
HwSettings * hwSettings = HwSettings::GetInstance(getObjectManager());
|
||||
HwSettings::DataFields hwSettingsData = hwSettings->getData();
|
||||
hwSettingsData.OptionalModules[HwSettings::OPTIONALMODULES_CAMERASTABILIZATION] =
|
||||
m_camerastabilization->enableCameraStabilization->isChecked() ?
|
||||
HwSettings::OPTIONALMODULES_ENABLED :
|
||||
HwSettings::OPTIONALMODULES_DISABLED;
|
||||
|
||||
// Update the mixer settings
|
||||
MixerSettings * mixerSettings = MixerSettings::GetInstance(getObjectManager());
|
||||
MixerSettings::DataFields mixerSettingsData = mixerSettings->getData();
|
||||
const int NUM_MIXERS = 8;
|
||||
|
||||
QComboBox * selectors[3] = {
|
||||
m_camerastabilization->rollChannel,
|
||||
m_camerastabilization->pitchChannel,
|
||||
m_camerastabilization->yawChannel
|
||||
};
|
||||
|
||||
// TODO: Need to reformat object so types are an
|
||||
// array themselves. This gets really awkward
|
||||
quint8 * mixerTypes[NUM_MIXERS] = {
|
||||
&mixerSettingsData.Mixer1Type,
|
||||
&mixerSettingsData.Mixer2Type,
|
||||
&mixerSettingsData.Mixer3Type,
|
||||
&mixerSettingsData.Mixer4Type,
|
||||
&mixerSettingsData.Mixer5Type,
|
||||
&mixerSettingsData.Mixer6Type,
|
||||
&mixerSettingsData.Mixer7Type,
|
||||
&mixerSettingsData.Mixer8Type,
|
||||
};
|
||||
|
||||
for (int i = 0; i < 3; i++)
|
||||
{
|
||||
// Channel 1 is second entry, so becomes zero
|
||||
int mixerNum = selectors[i]->currentIndex() - 1;
|
||||
|
||||
if ( mixerNum >= 0 && // Short circuit in case of none
|
||||
*mixerTypes[mixerNum] != MixerSettings::MIXER1TYPE_DISABLED &&
|
||||
(*mixerTypes[mixerNum] != MixerSettings::MIXER1TYPE_CAMERAROLL + i) ) {
|
||||
// If the mixer channel already to something that isn't what we are
|
||||
// about to set it to reset to none
|
||||
selectors[i]->setCurrentIndex(0);
|
||||
} else {
|
||||
// Make sure no other channels have this output set
|
||||
for (int j = 0; j < NUM_MIXERS; j++)
|
||||
if (*mixerTypes[j] == (MixerSettings::MIXER1TYPE_CAMERAROLL + i))
|
||||
*mixerTypes[j] = MixerSettings::MIXER1TYPE_DISABLED;
|
||||
|
||||
// If this channel is assigned to one of the outputs that is not disabled
|
||||
// set it
|
||||
if(mixerNum >= 0 && mixerNum < NUM_MIXERS)
|
||||
*mixerTypes[mixerNum] = MixerSettings::MIXER1TYPE_CAMERAROLL + i;
|
||||
}
|
||||
}
|
||||
|
||||
// Update the ranges
|
||||
CameraStabSettings * cameraStab = CameraStabSettings::GetInstance(getObjectManager());
|
||||
CameraStabSettings::DataFields cameraStabData = cameraStab->getData();
|
||||
cameraStabData.OutputRange[CameraStabSettings::OUTPUTRANGE_ROLL] = m_camerastabilization->rollOutputRange->value();
|
||||
cameraStabData.OutputRange[CameraStabSettings::OUTPUTRANGE_PITCH] = m_camerastabilization->pitchOutputRange->value();
|
||||
cameraStabData.OutputRange[CameraStabSettings::OUTPUTRANGE_YAW] = m_camerastabilization->yawOutputRange->value();
|
||||
|
||||
// Because multiple objects are updated, and all of them trigger the callback
|
||||
// they must be done together (if update one then load settings from second
|
||||
// the first update would wipe the UI controls). However to be extra cautious
|
||||
// I'm also disabling updates during the setting to the UAVObjects
|
||||
disconnectUpdates();
|
||||
hwSettings->setData(hwSettingsData);
|
||||
mixerSettings->setData(mixerSettingsData);
|
||||
cameraStab->setData(cameraStabData);
|
||||
connectUpdates();
|
||||
}
|
||||
|
||||
/**
|
||||
* Push settings into UAV objects then save them
|
||||
*/
|
||||
void ConfigCameraStabilizationWidget::saveSettings()
|
||||
{
|
||||
applySettings();
|
||||
UAVObject * obj = HwSettings::GetInstance(getObjectManager());
|
||||
saveObjectToSD(obj);
|
||||
obj = MixerSettings::GetInstance(getObjectManager());
|
||||
saveObjectToSD(obj);
|
||||
obj = CameraStabSettings::GetInstance(getObjectManager());
|
||||
saveObjectToSD(obj);
|
||||
}
|
||||
|
||||
void ConfigCameraStabilizationWidget::refreshValues()
|
||||
{
|
||||
HwSettings * hwSettings = HwSettings::GetInstance(getObjectManager());
|
||||
HwSettings::DataFields hwSettingsData = hwSettings->getData();
|
||||
m_camerastabilization->enableCameraStabilization->setChecked(
|
||||
hwSettingsData.OptionalModules[HwSettings::OPTIONALMODULES_CAMERASTABILIZATION] ==
|
||||
HwSettings::OPTIONALMODULES_ENABLED);
|
||||
|
||||
CameraStabSettings * cameraStabSettings = CameraStabSettings::GetInstance(getObjectManager());
|
||||
CameraStabSettings::DataFields cameraStab = cameraStabSettings->getData();
|
||||
m_camerastabilization->rollOutputRange->setValue(cameraStab.OutputRange[CameraStabSettings::OUTPUTRANGE_ROLL]);
|
||||
m_camerastabilization->pitchOutputRange->setValue(cameraStab.OutputRange[CameraStabSettings::OUTPUTRANGE_PITCH]);
|
||||
m_camerastabilization->yawOutputRange->setValue(cameraStab.OutputRange[CameraStabSettings::OUTPUTRANGE_YAW]);
|
||||
|
||||
MixerSettings * mixerSettings = MixerSettings::GetInstance(getObjectManager());
|
||||
MixerSettings::DataFields mixerSettingsData = mixerSettings->getData();
|
||||
const int NUM_MIXERS = 8;
|
||||
QComboBox * selectors[3] = {
|
||||
m_camerastabilization->rollChannel,
|
||||
m_camerastabilization->pitchChannel,
|
||||
m_camerastabilization->yawChannel
|
||||
};
|
||||
|
||||
// TODO: Need to reformat object so types are an
|
||||
// array themselves. This gets really awkward
|
||||
quint8 * mixerTypes[NUM_MIXERS] = {
|
||||
&mixerSettingsData.Mixer1Type,
|
||||
&mixerSettingsData.Mixer2Type,
|
||||
&mixerSettingsData.Mixer3Type,
|
||||
&mixerSettingsData.Mixer4Type,
|
||||
&mixerSettingsData.Mixer5Type,
|
||||
&mixerSettingsData.Mixer6Type,
|
||||
&mixerSettingsData.Mixer7Type,
|
||||
&mixerSettingsData.Mixer8Type,
|
||||
};
|
||||
|
||||
for (int i = 0; i < 3; i++)
|
||||
{
|
||||
// Default to none if not found. Then search for any mixer channels set to
|
||||
// this
|
||||
selectors[i]->setCurrentIndex(0);
|
||||
for (int j = 0; j < NUM_MIXERS; j++)
|
||||
if (*mixerTypes[j] == (MixerSettings::MIXER1TYPE_CAMERAROLL + i) &&
|
||||
selectors[i]->currentIndex() != (j + 1))
|
||||
selectors[i]->setCurrentIndex(j + 1);
|
||||
}
|
||||
}
|
||||
|
||||
void ConfigCameraStabilizationWidget::openHelp()
|
||||
{
|
||||
QDesktopServices::openUrl( QUrl("http://wiki.openpilot.org/display/Doc/Camera+Stabilization", QUrl::StrictMode) );
|
||||
}
|
||||
|
||||
void ConfigCameraStabilizationWidget::enableControls(bool enable)
|
||||
{
|
||||
m_camerastabilization->camerastabilizationSaveSD->setEnabled(enable);
|
||||
m_camerastabilization->camerastabilizationSaveRAM->setEnabled(enable);
|
||||
}
|
||||
|
||||
/**
|
||||
@}
|
||||
@}
|
||||
*/
|
@ -0,0 +1,68 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
*
|
||||
* @file configahrstwidget.h
|
||||
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
|
||||
* @addtogroup GCSPlugins GCS Plugins
|
||||
* @{
|
||||
* @addtogroup ConfigPlugin Config Plugin
|
||||
* @{
|
||||
* @brief Telemetry configuration panel
|
||||
*****************************************************************************/
|
||||
/*
|
||||
* 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 CONFIGCAMERASTABILIZATIONWIDGET_H
|
||||
#define CONFIGCAMERASTABILIZATIONWIDGET_H
|
||||
|
||||
#include "ui_camerastabilization.h"
|
||||
#include "configtaskwidget.h"
|
||||
#include "extensionsystem/pluginmanager.h"
|
||||
#include "uavobjectmanager.h"
|
||||
#include "uavobject.h"
|
||||
#include <QtGui/QWidget>
|
||||
#include <QtSvg/QSvgRenderer>
|
||||
#include <QtSvg/QGraphicsSvgItem>
|
||||
#include <QList>
|
||||
#include <QTimer>
|
||||
#include <QMutex>
|
||||
|
||||
#include "camerastabsettings.h"
|
||||
|
||||
class ConfigCameraStabilizationWidget: public ConfigTaskWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
ConfigCameraStabilizationWidget(QWidget *parent = 0);
|
||||
~ConfigCameraStabilizationWidget();
|
||||
|
||||
private:
|
||||
virtual void enableControls(bool enable);
|
||||
|
||||
Ui_CameraStabilizationWidget *m_camerastabilization;
|
||||
|
||||
private slots:
|
||||
void openHelp();
|
||||
void applySettings();
|
||||
void saveSettings();
|
||||
void refreshValues();
|
||||
|
||||
protected:
|
||||
void connectUpdates();
|
||||
void disconnectUpdates();
|
||||
};
|
||||
|
||||
#endif // ConfigCameraStabilization_H
|
@ -15,5 +15,6 @@
|
||||
<file>images/coptercontrol.svg</file>
|
||||
<file>images/hw_config.png</file>
|
||||
<file>images/gyroscope.png</file>
|
||||
<file>images/camera.png</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
|
@ -33,6 +33,7 @@
|
||||
#include "configinputwidget.h"
|
||||
#include "configoutputwidget.h"
|
||||
#include "configstabilizationwidget.h"
|
||||
#include "configcamerastabilizationwidget.h"
|
||||
#include "config_pro_hw_widget.h"
|
||||
#include "config_cc_hw_widget.h"
|
||||
#include "defaultattitudewidget.h"
|
||||
@ -81,6 +82,8 @@ ConfigGadgetWidget::ConfigGadgetWidget(QWidget *parent) : QWidget(parent)
|
||||
qwd = new ConfigStabilizationWidget(this);
|
||||
ftw->insertTab(ConfigGadgetWidget::stabilization, qwd, QIcon(":/configgadget/images/gyroscope.png"), QString("Stabilization"));
|
||||
|
||||
qwd = new ConfigCameraStabilizationWidget(this);
|
||||
ftw->insertTab(ConfigGadgetWidget::camerastabilization, qwd, QIcon(":/configgadget/images/camera.png"), QString("Camera Stab"));
|
||||
|
||||
|
||||
// qwd = new ConfigPipXtremeWidget(this);
|
||||
|
@ -50,7 +50,7 @@ class ConfigGadgetWidget: public QWidget
|
||||
public:
|
||||
ConfigGadgetWidget(QWidget *parent = 0);
|
||||
~ConfigGadgetWidget();
|
||||
enum widgetTabs {hardware=0, aircraft, input, output, ins, stabilization};
|
||||
enum widgetTabs {hardware=0, aircraft, input, output, ins, stabilization, camerastabilization};
|
||||
|
||||
public slots:
|
||||
void onAutopilotConnect();
|
||||
|
BIN
ground/openpilotgcs/src/plugins/config/images/camera.png
Normal file
BIN
ground/openpilotgcs/src/plugins/config/images/camera.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 2.8 KiB |
@ -179,6 +179,8 @@ MainWindow::MainWindow() :
|
||||
m_modeStack->setIconSize(QSize(24,24));
|
||||
m_modeStack->setTabPosition(QTabWidget::South);
|
||||
m_modeStack->setMovable(false);
|
||||
m_modeStack->setMinimumWidth(512);
|
||||
m_modeStack->setElideMode(Qt::ElideRight);
|
||||
#ifndef Q_WS_MAC
|
||||
m_modeStack->setDocumentMode(true);
|
||||
#endif
|
||||
|
@ -291,16 +291,12 @@ void ModelViewGadgetWidget::updateAttitude()
|
||||
{
|
||||
AttitudeActual::DataFields data = attActual->getData(); // get attitude data
|
||||
GLC_StructOccurence* rootObject= m_World.rootOccurence(); // get the full 3D model
|
||||
// create quaternions rotations for each axis
|
||||
QQuaternion qX= QQuaternion::fromAxisAndAngle(QVector3D(1,0,0),data.Pitch);
|
||||
QQuaternion qY= QQuaternion::fromAxisAndAngle(QVector3D(0,1,0),data.Roll);
|
||||
QQuaternion qZ= QQuaternion::fromAxisAndAngle(QVector3D(0,0,1),data.Yaw);
|
||||
QQuaternion quat= qX * qY * qZ; // create the quaternion of all the rotations
|
||||
// pass values to simpler variables
|
||||
double x= quat.vector().x();
|
||||
double y= quat.vector().y();
|
||||
double z= quat.vector().z();
|
||||
double w= quat.scalar();
|
||||
double x= data.q3;
|
||||
double y= data.q2;
|
||||
double z= data.q4;
|
||||
double w= data.q1;
|
||||
if (w == 0.0)
|
||||
w = 1.0;
|
||||
// create and gives the product of 2 4x4 matrices to get the rotation of the 3D model's matrix
|
||||
QMatrix4x4 m1;
|
||||
m1.setRow(0, QVector4D(w,z,-y,x));
|
||||
|
@ -31,6 +31,7 @@ HEADERS += $$UAVOBJECT_SYNTHETICS/accessorydesired.h \
|
||||
$$UAVOBJECT_SYNTHETICS/ahrssettings.h \
|
||||
$$UAVOBJECT_SYNTHETICS/gcstelemetrystats.h \
|
||||
$$UAVOBJECT_SYNTHETICS/attituderaw.h \
|
||||
$$UAVOBJECT_SYNTHETICS/camerastabsettings.h \
|
||||
$$UAVOBJECT_SYNTHETICS/flighttelemetrystats.h \
|
||||
$$UAVOBJECT_SYNTHETICS/systemstats.h \
|
||||
$$UAVOBJECT_SYNTHETICS/systemalarms.h \
|
||||
@ -69,7 +70,8 @@ HEADERS += $$UAVOBJECT_SYNTHETICS/accessorydesired.h \
|
||||
$$UAVOBJECT_SYNTHETICS/sonaraltitude.h \
|
||||
$$UAVOBJECT_SYNTHETICS/flightstatus.h \
|
||||
$$UAVOBJECT_SYNTHETICS/hwsettings.h \
|
||||
$$UAVOBJECT_SYNTHETICS/attitudesettings.h
|
||||
$$UAVOBJECT_SYNTHETICS/attitudesettings.h \
|
||||
$$UAVOBJECT_SYNTHETICS/cameradesired.h
|
||||
|
||||
SOURCES += $$UAVOBJECT_SYNTHETICS/accessorydesired.cpp \
|
||||
$$UAVOBJECT_SYNTHETICS/ahrsstatus.cpp \
|
||||
@ -79,6 +81,7 @@ SOURCES += $$UAVOBJECT_SYNTHETICS/accessorydesired.cpp \
|
||||
$$UAVOBJECT_SYNTHETICS/ahrssettings.cpp \
|
||||
$$UAVOBJECT_SYNTHETICS/gcstelemetrystats.cpp \
|
||||
$$UAVOBJECT_SYNTHETICS/attituderaw.cpp \
|
||||
$$UAVOBJECT_SYNTHETICS/camerastabsettings.cpp \
|
||||
$$UAVOBJECT_SYNTHETICS/flighttelemetrystats.cpp \
|
||||
$$UAVOBJECT_SYNTHETICS/systemstats.cpp \
|
||||
$$UAVOBJECT_SYNTHETICS/systemalarms.cpp \
|
||||
@ -118,4 +121,5 @@ SOURCES += $$UAVOBJECT_SYNTHETICS/accessorydesired.cpp \
|
||||
$$UAVOBJECT_SYNTHETICS/uavobjectsinit.cpp \
|
||||
$$UAVOBJECT_SYNTHETICS/flightstatus.cpp \
|
||||
$$UAVOBJECT_SYNTHETICS/hwsettings.cpp \
|
||||
$$UAVOBJECT_SYNTHETICS/attitudesettings.cpp
|
||||
$$UAVOBJECT_SYNTHETICS/attitudesettings.cpp \
|
||||
$$UAVOBJECT_SYNTHETICS/cameradesired.cpp
|
||||
|
@ -189,7 +189,7 @@ bool deviceWidget::populateBoardStructuredDescription(QByteArray desc)
|
||||
myDevice->lblDescription->setText(QString("Firmware tag: ")+onBoardDescrition.description);
|
||||
QPixmap pix = QPixmap(QString(":uploader/images/application-certificate.svg"));
|
||||
myDevice->lblCertified->setPixmap(pix);
|
||||
myDevice->lblCertified->setToolTip(tr("Official Firmware Build"));
|
||||
myDevice->lblCertified->setToolTip(tr("Tagged officially released firmware build"));
|
||||
|
||||
}
|
||||
else
|
||||
@ -197,7 +197,7 @@ bool deviceWidget::populateBoardStructuredDescription(QByteArray desc)
|
||||
myDevice->lblDescription->setText(onBoardDescrition.description);
|
||||
QPixmap pix = QPixmap(QString(":uploader/images/warning.svg"));
|
||||
myDevice->lblCertified->setPixmap(pix);
|
||||
myDevice->lblCertified->setToolTip(tr("Custom Firmware Build"));
|
||||
myDevice->lblCertified->setToolTip(tr("Untagged or custom firmware build"));
|
||||
}
|
||||
|
||||
myDevice->lblBrdName->setText(idToBoardName(onBoardDescrition.boardType<<8));
|
||||
@ -220,7 +220,7 @@ bool deviceWidget::populateLoadedStructuredDescription(QByteArray desc)
|
||||
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"));
|
||||
myDevice->lblCertifiedL->setToolTip(tr("Tagged officially released firmware build"));
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -228,7 +228,7 @@ bool deviceWidget::populateLoadedStructuredDescription(QByteArray desc)
|
||||
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->lblCertifiedL->setToolTip(tr("Untagged or custom firmware build"));
|
||||
}
|
||||
myDevice->lblBrdNameL->setText(deviceDescriptorStruct::idToBoardName(LoadedDescrition.boardType<<8));
|
||||
|
||||
@ -312,34 +312,34 @@ void deviceWidget::loadFirmware()
|
||||
myDevice->groupCustom->setVisible(false);
|
||||
if(myDevice->lblCRC->text()==myDevice->lblCRCL->text())
|
||||
{
|
||||
myDevice->statusLabel->setText(tr("The loaded firmware the same as on the board. You should not upload it"));
|
||||
myDevice->statusLabel->setText(tr("The board has the same firmware as loaded. No need to update"));
|
||||
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"));
|
||||
myDevice->statusLabel->setText(tr("WARNING: the loaded firmware is for different hardware. Do not update!"));
|
||||
px.load(QString(":/uploader/images/error.svg"));
|
||||
}
|
||||
else if(QDateTime::fromString(onBoardDescrition.buildDate)>QDateTime::fromString(LoadedDescrition.buildDate))
|
||||
{
|
||||
myDevice->statusLabel->setText(tr("The loaded firmware is older than the firmware on the board. You should not upload it"));
|
||||
myDevice->statusLabel->setText(tr("The board has newer firmware than loaded. Are you sure you want to update?"));
|
||||
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"));
|
||||
myDevice->statusLabel->setText(tr("The loaded firmware is untagged or custom build. Update only if it was received from a trusted source (official website or your own build)"));
|
||||
px.load(QString(":/uploader/images/warning.svg"));
|
||||
}
|
||||
else
|
||||
{
|
||||
myDevice->statusLabel->setText(tr("Everything seems OK. You should upload the loaded firmware by pressing 'Flash'"));
|
||||
myDevice->statusLabel->setText(tr("This is the tagged officially released OpenPilot firmware"));
|
||||
px.load(QString(":/uploader/images/gtk-info.svg"));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
myDevice->statusLabel->setText(tr("The loaded firmware was not packaged with the OpenPilot format. You should not upload it unless you know what you are doing."));
|
||||
px.load(QString(":/uploader/images/warning.svg"));
|
||||
myDevice->statusLabel->setText(tr("WARNING: the loaded firmware was not packaged with the OpenPilot format. Do not update unless you know what you are doing"));
|
||||
px.load(QString(":/uploader/images/error.svg"));
|
||||
myDevice->youdont->setChecked(false);
|
||||
myDevice->youdont->setVisible(true);
|
||||
myDevice->verticalGroupBox_loaded->setVisible(false);
|
||||
@ -514,7 +514,7 @@ QString deviceWidget::setOpenFileName()
|
||||
QString fileName = QFileDialog::getOpenFileName(this,
|
||||
tr("Select firmware file"),
|
||||
"",
|
||||
tr("Firmware Files (*.bin *.opfw)"),
|
||||
tr("Firmware Files (*.opfw *.bin)"),
|
||||
&selectedFilter,
|
||||
options);
|
||||
return fileName;
|
||||
|
@ -93,10 +93,10 @@
|
||||
<item>
|
||||
<widget class="QPushButton" name="pbLoad">
|
||||
<property name="toolTip">
|
||||
<string>Loads the firmware</string>
|
||||
<string>Open a file with new firmware image to be flashed</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Load...</string>
|
||||
<string>Open...</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
@ -116,7 +116,7 @@
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Update the firmware on this board.</string>
|
||||
<string>Write loaded firmware image to the board</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Flash</string>
|
||||
@ -126,7 +126,7 @@
|
||||
<item>
|
||||
<widget class="QPushButton" name="retrieveButton">
|
||||
<property name="toolTip">
|
||||
<string>Download the current board firmware to your computer</string>
|
||||
<string>Read and save current board firmware to a file</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Retrieve...</string>
|
||||
@ -228,7 +228,7 @@
|
||||
<item>
|
||||
<widget class="QLabel" name="label_3">
|
||||
<property name="text">
|
||||
<string>GIT Tag:</string>
|
||||
<string>Git tag:</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
|
35
ground/openpilotgcs/src/plugins/uploader/images/error.svg
Normal file
35
ground/openpilotgcs/src/plugins/uploader/images/error.svg
Normal file
@ -0,0 +1,35 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
<svg id="svg3247" xmlns="http://www.w3.org/2000/svg" height="48" width="48" version="1.0" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<defs id="defs3249">
|
||||
<linearGradient id="linearGradient2411" y2="5.4676" gradientUnits="userSpaceOnUse" x2="63.397" gradientTransform="matrix(2.1154 0 0 2.1153 -107.58 32.427)" y1="-12.489" x1="63.397">
|
||||
<stop id="stop4875" style="stop-color:#fff" offset="0"/>
|
||||
<stop id="stop4877" style="stop-color:#fff;stop-opacity:0" offset="1"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="linearGradient2416" y2="3.0816" gradientUnits="userSpaceOnUse" x2="18.379" gradientTransform="matrix(.95844 0 0 .95844 .99752 1.9975)" y1="44.98" x1="18.379">
|
||||
<stop id="stop2492" style="stop-color:#791235" offset="0"/>
|
||||
<stop id="stop2494" style="stop-color:#dd3b27" offset="1"/>
|
||||
</linearGradient>
|
||||
<radialGradient id="radialGradient2414" gradientUnits="userSpaceOnUse" cy="3.99" cx="23.896" gradientTransform="matrix(0 2.2875 -3.0194 0 36.047 -50.63)" r="20.397">
|
||||
<stop id="stop3244" style="stop-color:#f8b17e" offset="0"/>
|
||||
<stop id="stop3246" style="stop-color:#e35d4f" offset=".26238"/>
|
||||
<stop id="stop3248" style="stop-color:#c6262e" offset=".66094"/>
|
||||
<stop id="stop3250" style="stop-color:#690b54" offset="1"/>
|
||||
</radialGradient>
|
||||
<radialGradient id="radialGradient2419" gradientUnits="userSpaceOnUse" cy="4.625" cx="62.625" gradientTransform="matrix(2.1647 0 0 .75294 -111.56 36.518)" r="10.625">
|
||||
<stop id="stop8840" offset="0"/>
|
||||
<stop id="stop8842" style="stop-opacity:0" offset="1"/>
|
||||
</radialGradient>
|
||||
</defs>
|
||||
<g id="layer1">
|
||||
<g id="g3275">
|
||||
<path id="path8836" style="opacity:.3;fill-rule:evenodd;fill:url(#radialGradient2419)" d="m47 40c0 4.418-10.297 8-23 8s-23-3.582-23-8 10.297-8 23-8 23 3.582 23 8z"/>
|
||||
<path id="path2555" style="stroke-linejoin:round;stroke:url(#linearGradient2416);stroke-linecap:round;stroke-width:1.0037;fill:url(#radialGradient2414)" d="m24 5.5018c-10.758 0-19.498 8.7402-19.498 19.498-0.0002 10.758 8.74 19.498 19.498 19.498s19.498-8.74 19.498-19.498-8.74-19.498-19.498-19.498z"/>
|
||||
<path id="path8655" style="opacity:.4;stroke:url(#linearGradient2411);fill:none" d="m42.5 24.999c0 10.218-8.283 18.501-18.5 18.501s-18.5-8.283-18.5-18.501c0-10.217 8.283-18.499 18.5-18.499s18.5 8.282 18.5 18.499z"/>
|
||||
</g>
|
||||
<g id="g3243" transform="translate(51.075 .56862)">
|
||||
<path id="path3295" style="opacity:.2" d="m-29.451 12.554c0.563 5.5 1.208 10.961 1.687 16.482h1.53c0.397-5.302 1.038-10.571 1.501-15.867 0.236-1.254-0.408-2.742-1.732-3.047-1.308-0.3824-2.77 0.565-2.944 1.918-0.029 0.17-0.042 0.342-0.042 0.514zm-0.167 22.359c-0.059 1.637 1.742 2.92 3.28 2.401 1.489-0.38 2.274-2.252 1.51-3.583-0.683-1.375-2.687-1.829-3.84-0.776-0.582 0.479-0.968 1.194-0.95 1.958z"/>
|
||||
<path id="text2315" style="fill:#fff" d="m-29.451 13.555c0.563 5.499 1.208 10.96 1.687 16.481h1.53c0.397-5.301 1.038-10.571 1.501-15.866 0.236-1.254-0.408-2.743-1.732-3.048-1.308-0.382-2.77 0.565-2.944 1.918-0.029 0.17-0.042 0.342-0.042 0.515zm-0.167 22.358c-0.059 1.637 1.742 2.921 3.28 2.402 1.489-0.381 2.274-2.253 1.51-3.584-0.683-1.375-2.687-1.828-3.84-0.776-0.582 0.479-0.968 1.194-0.95 1.958z"/>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 3.2 KiB |
@ -1,35 +1,290 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
<svg id="svg3247" xmlns="http://www.w3.org/2000/svg" height="48" width="48" version="1.0" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<defs id="defs3249">
|
||||
<linearGradient id="linearGradient2411" y2="5.4676" gradientUnits="userSpaceOnUse" x2="63.397" gradientTransform="matrix(2.1154 0 0 2.1153 -107.58 32.427)" y1="-12.489" x1="63.397">
|
||||
<stop id="stop4875" style="stop-color:#fff" offset="0"/>
|
||||
<stop id="stop4877" style="stop-color:#fff;stop-opacity:0" offset="1"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="linearGradient2416" y2="3.0816" gradientUnits="userSpaceOnUse" x2="18.379" gradientTransform="matrix(.95844 0 0 .95844 .99752 1.9975)" y1="44.98" x1="18.379">
|
||||
<stop id="stop2492" style="stop-color:#791235" offset="0"/>
|
||||
<stop id="stop2494" style="stop-color:#dd3b27" offset="1"/>
|
||||
</linearGradient>
|
||||
<radialGradient id="radialGradient2414" gradientUnits="userSpaceOnUse" cy="3.99" cx="23.896" gradientTransform="matrix(0 2.2875 -3.0194 0 36.047 -50.63)" r="20.397">
|
||||
<stop id="stop3244" style="stop-color:#f8b17e" offset="0"/>
|
||||
<stop id="stop3246" style="stop-color:#e35d4f" offset=".26238"/>
|
||||
<stop id="stop3248" style="stop-color:#c6262e" offset=".66094"/>
|
||||
<stop id="stop3250" style="stop-color:#690b54" offset="1"/>
|
||||
</radialGradient>
|
||||
<radialGradient id="radialGradient2419" gradientUnits="userSpaceOnUse" cy="4.625" cx="62.625" gradientTransform="matrix(2.1647 0 0 .75294 -111.56 36.518)" r="10.625">
|
||||
<stop id="stop8840" offset="0"/>
|
||||
<stop id="stop8842" style="stop-opacity:0" offset="1"/>
|
||||
</radialGradient>
|
||||
</defs>
|
||||
<g id="layer1">
|
||||
<g id="g3275">
|
||||
<path id="path8836" style="opacity:.3;fill-rule:evenodd;fill:url(#radialGradient2419)" d="m47 40c0 4.418-10.297 8-23 8s-23-3.582-23-8 10.297-8 23-8 23 3.582 23 8z"/>
|
||||
<path id="path2555" style="stroke-linejoin:round;stroke:url(#linearGradient2416);stroke-linecap:round;stroke-width:1.0037;fill:url(#radialGradient2414)" d="m24 5.5018c-10.758 0-19.498 8.7402-19.498 19.498-0.0002 10.758 8.74 19.498 19.498 19.498s19.498-8.74 19.498-19.498-8.74-19.498-19.498-19.498z"/>
|
||||
<path id="path8655" style="opacity:.4;stroke:url(#linearGradient2411);fill:none" d="m42.5 24.999c0 10.218-8.283 18.501-18.5 18.501s-18.5-8.283-18.5-18.501c0-10.217 8.283-18.499 18.5-18.499s18.5 8.282 18.5 18.499z"/>
|
||||
|
||||
<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:xlink="http://www.w3.org/1999/xlink"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="48"
|
||||
height="48"
|
||||
id="svg2"
|
||||
version="1.1"
|
||||
inkscape:version="0.48.1 "
|
||||
sodipodi:docname="warning.svg">
|
||||
<defs
|
||||
id="defs4">
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
id="linearGradient2850">
|
||||
<stop
|
||||
style="stop-color:#eeeeee;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop2852" />
|
||||
<stop
|
||||
style="stop-color:#eeeeee;stop-opacity:0;"
|
||||
offset="1"
|
||||
id="stop2854" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
id="linearGradient3657">
|
||||
<stop
|
||||
style="stop-color:#986601;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop3659" />
|
||||
<stop
|
||||
id="stop3665"
|
||||
offset="0.33080238"
|
||||
style="stop-color:#fdca01;stop-opacity:1" />
|
||||
<stop
|
||||
style="stop-color:#ffff99;stop-opacity:1"
|
||||
offset="1"
|
||||
id="stop3661" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
id="linearGradient3632">
|
||||
<stop
|
||||
style="stop-color:#999999;stop-opacity:0"
|
||||
offset="0"
|
||||
id="stop3634" />
|
||||
<stop
|
||||
id="stop3640"
|
||||
offset="0.50655138"
|
||||
style="stop-color:#e6e6e6;stop-opacity:1" />
|
||||
<stop
|
||||
style="stop-color:#999999;stop-opacity:0;"
|
||||
offset="1"
|
||||
id="stop3636" />
|
||||
</linearGradient>
|
||||
<inkscape:perspective
|
||||
sodipodi:type="inkscape:persp3d"
|
||||
inkscape:vp_x="0 : 526.18109 : 1"
|
||||
inkscape:vp_y="0 : 1000 : 0"
|
||||
inkscape:vp_z="744.09448 : 526.18109 : 1"
|
||||
inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
|
||||
id="perspective10" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3632"
|
||||
id="linearGradient3638"
|
||||
x1="19.10717"
|
||||
y1="127.34224"
|
||||
x2="260.11157"
|
||||
y2="127.34224"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(0.19402788,0,0,0.19376669,5.5464026,989.71412)" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3632"
|
||||
id="linearGradient3644"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
x1="2.3978782"
|
||||
y1="121.40089"
|
||||
x2="260.11157"
|
||||
y2="127.34224"
|
||||
gradientTransform="matrix(-0.09701394,0.16780688,-0.16803307,-0.09688335,73.208116,1013.465)" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3632"
|
||||
id="linearGradient3648"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(0.09701394,0.16780688,0.16803307,-0.09688335,-8.1841884,1014.9031)"
|
||||
x1="19.10717"
|
||||
y1="127.34224"
|
||||
x2="260.11157"
|
||||
y2="127.34224" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3657"
|
||||
id="linearGradient3680"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
x1="112.5"
|
||||
y1="275.40689"
|
||||
x2="112.5"
|
||||
y2="-4.2200408"
|
||||
gradientTransform="matrix(0.19402788,0,0,0.19376669,5.5464026,989.71412)" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3657"
|
||||
id="linearGradient2847"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(0.45813096,0,0,0.45751424,0.67535737,1.90895)"
|
||||
x1="112.5"
|
||||
y1="275.40689"
|
||||
x2="112.5"
|
||||
y2="-4.2200408" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient2850"
|
||||
id="linearGradient2856"
|
||||
x1="63.993164"
|
||||
y1="8.8525076"
|
||||
x2="63.993164"
|
||||
y2="91.242332"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(0.42352056,0,0,0.42352056,5.2603749,988.90564)" />
|
||||
</defs>
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="1"
|
||||
inkscape:cx="-46.02894"
|
||||
inkscape:cy="-0.138668"
|
||||
inkscape:document-units="px"
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="false"
|
||||
showguides="true"
|
||||
inkscape:guide-bbox="true"
|
||||
inkscape:window-width="1400"
|
||||
inkscape:window-height="1003"
|
||||
inkscape:window-x="-4"
|
||||
inkscape:window-y="-4"
|
||||
inkscape:window-maximized="1"
|
||||
fit-margin-top="0"
|
||||
fit-margin-left="0"
|
||||
fit-margin-right="0"
|
||||
fit-margin-bottom="0" />
|
||||
<metadata
|
||||
id="metadata7">
|
||||
<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></dc:title>
|
||||
<cc:license
|
||||
rdf:resource="" />
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
inkscape:label="Layer 1"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1"
|
||||
transform="translate(-9.125,-988.32372)">
|
||||
<g
|
||||
id="g2975"
|
||||
transform="matrix(0.42352056,0,0,0.42352056,3.9898132,596.57221)">
|
||||
<path
|
||||
style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;opacity:0.02999998;color:#000000;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Bitstream Vera Sans;-inkscape-font-specification:Bitstream Vera Sans"
|
||||
d="m 15.5625,1033.9688 c 35.520833,-1e-4 71.041667,0 106.5625,0 -17.76042,-30.7084 -35.520833,-61.41672 -53.28125,-92.12505 -17.760417,30.70833 -35.520833,61.41665 -53.28125,92.12505 z"
|
||||
id="path2874"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;opacity:0.02999998;color:#000000;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Bitstream Vera Sans;-inkscape-font-specification:Bitstream Vera Sans"
|
||||
d="m 15.03125,1034.2812 c 35.875,0 71.75,1e-4 107.625,0 -17.9375,-31.0312 -35.875,-62.06245 -53.8125,-93.0937 -17.9375,31.03125 -35.875,62.0625 -53.8125,93.0937 z"
|
||||
id="path2878"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;opacity:0.02999998;color:#000000;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Bitstream Vera Sans;-inkscape-font-specification:Bitstream Vera Sans"
|
||||
d="M 68.78125,940.65625 C 50.914197,971.92452 32.089324,1003.5095 14.75,1034.5625 c 36.091043,-0.084 72.452585,0.167 108.375,-0.125 -18.12273,-31.2282 -36.179858,-62.71402 -54.34375,-93.78125 z"
|
||||
id="path2882"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;opacity:0.02999998;color:#000000;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Bitstream Vera Sans;-inkscape-font-specification:Bitstream Vera Sans"
|
||||
d="m 68.71875,940.34375 c -18.21641,31.323 -36.515662,62.85885 -54.46875,94.28125 3.741727,0.6849 8.400562,0.01 12.437499,0.25 32.199492,-0.1047 64.634624,0.2091 96.687501,-0.1562 -2.01836,-4.5363 -5.32611,-9.2498 -7.78102,-13.8467 -15.605622,-26.8084 -31.035873,-53.9715 -46.75023,-80.5596 -0.04179,0.009 -0.102865,-0.0245 -0.125,0.0312 z"
|
||||
id="path2886"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;opacity:0.02999998;color:#000000;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Bitstream Vera Sans;-inkscape-font-specification:Bitstream Vera Sans"
|
||||
d="m 68.625,940.0625 c -1.898442,2.49808 -3.28205,5.61534 -4.997045,8.33338 -16.533965,28.68448 -33.220463,57.33752 -49.659205,86.04162 0.03222,1.4296 2.384617,0.414 3.325,0.7187 35.335267,-0.021 70.705057,0.042 106.01875,-0.031 1.22525,-0.6532 -0.7388,-2.314 -1.00779,-3.2436 -17.6836,-30.5632 -35.377677,-61.22113 -53.05471,-91.72515 -0.17511,-0.11773 -0.421252,-0.17697 -0.625,-0.0937 z"
|
||||
id="path2890"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;opacity:0.02999998;color:#000000;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Bitstream Vera Sans;-inkscape-font-specification:Bitstream Vera Sans"
|
||||
d="m 68.59375,939.65625 c -0.849146,0.26354 -1.046037,1.3532 -1.557052,2.02713 -17.793483,30.78262 -35.586965,61.56522 -53.380448,92.34782 -0.382416,0.719 0.174709,1.5807 0.975,1.5313 36.175,0 72.35,0 108.525,0 0.89258,-0.022 1.26685,-1.0887 0.72476,-1.7909 -18.05408,-31.2051 -36.108172,-62.41024 -54.16226,-93.61535 -0.138442,-0.39413 -0.699141,-0.63415 -1.125,-0.5 z"
|
||||
id="path2894"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;opacity:0.02999998;color:#000000;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Bitstream Vera Sans;-inkscape-font-specification:Bitstream Vera Sans"
|
||||
d="m 68.5625,939.4375 c -1.590286,0.85105 -1.905887,3.12983 -3.033256,4.48971 -17.3826,30.12088 -34.865418,60.21889 -52.185494,90.35399 -0.26697,1.59 1.857007,1.73 2.9875,1.5 35.676932,-0.021 71.388394,0.042 107.04375,-0.031 1.49785,-0.393 0.95277,-2.2528 0.0615,-3.1109 -17.9457,-30.9718 -35.823978,-62.04135 -53.8115,-92.9518 -0.298373,-0.1963 -0.695976,-0.36722 -1.0625,-0.25 z"
|
||||
id="path2898"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;opacity:0.02999998;color:#000000;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Bitstream Vera Sans;-inkscape-font-specification:Bitstream Vera Sans"
|
||||
d="m 68.4375,939.1875 c -2.665517,1.85677 -3.376329,5.93312 -5.441511,8.47941 -16.5968,28.90914 -33.570754,57.68499 -49.933489,86.67689 0.03767,3.0044 4.461608,1.2959 6.268751,1.7187 34.807311,-0.1049 69.688836,0.2093 104.449999,-0.1563 2.48477,-1.8446 -1.4715,-4.7803 -2.01675,-6.799 -17.3631,-29.87443 -34.529605,-59.95355 -52.0145,-89.70095 -0.363201,-0.23912 -0.899825,-0.38311 -1.3125,-0.21875 z"
|
||||
id="path2902"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;opacity:0.02999998;color:#000000;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Bitstream Vera Sans;-inkscape-font-specification:Bitstream Vera Sans"
|
||||
d="m 68.28125,938.90625 c -4.241668,4.50666 -6.418986,11.25217 -10.039272,16.42758 -15.094516,26.42114 -30.798679,52.67447 -45.523228,79.19737 0.973486,3.9884 7.091213,0.8607 9.912501,1.8438 33.766663,-0.1709 67.711681,0.339 101.368749,-0.25 3.02785,-2.6896 -2.75748,-6.5679 -3.33688,-9.4803 -17.04167,-29.14204 -33.624067,-58.76297 -50.94437,-87.61345 -0.446728,-0.17465 -0.976209,-0.34944 -1.4375,-0.125 z"
|
||||
id="path2906"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;opacity:0.02999998;color:#000000;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Bitstream Vera Sans;-inkscape-font-specification:Bitstream Vera Sans"
|
||||
d="m 68.25,938.625 c -4.248341,3.6207 -5.799608,10.30836 -9.257129,14.82104 -15.417424,27.05725 -31.592719,53.89936 -46.555371,81.08516 0.983203,4.5373 7.950662,1.0268 11.09375,2.125 33.518304,-0.1928 67.217157,0.3823 100.625,-0.2812 3.39168,-3.0568 -2.98383,-7.3811 -3.69406,-10.6654 C 103.54587,996.81337 87.118698,967.38512 69.90625,938.8125 69.430976,938.55208 68.767472,938.4102 68.25,938.625 z"
|
||||
id="path2910"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;opacity:0.02999998;color:#000000;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Bitstream Vera Sans;-inkscape-font-specification:Bitstream Vera Sans"
|
||||
d="m 68.15625,938.3125 c -4.44705,3.59724 -5.907996,10.41675 -9.444629,14.97729 -15.460635,27.02312 -31.4413,53.84841 -46.586621,80.99141 0.504744,5.1808 8.151862,1.69 11.40625,2.6876 33.572728,-0.2149 67.307606,0.4253 100.78125,-0.3126 3.72904,-3.2084 -2.74749,-7.7207 -3.56937,-11.1027 C 103.77,996.62017 87.401308,967.12253 70.0625,938.53125 c -0.585006,-0.29694 -1.280735,-0.43981 -1.90625,-0.21875 z"
|
||||
id="path2914"
|
||||
inkscape:connector-curvature="0" />
|
||||
</g>
|
||||
<path
|
||||
style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;color:#000000;fill:#999999;fill-opacity:1;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Bitstream Vera Sans;-inkscape-font-specification:Bitstream Vera Sans"
|
||||
d="m 32.613292,994.11625 a 0.38809457,0.38757213 0 0 0 -0.315295,0.19377 L 9.3056929,1034.0806 a 0.38809457,0.38757213 0 0 0 0.3334856,0.5814 l 45.9906705,0 a 0.38809457,0.38757213 0 0 0 0.333488,-0.5814 L 32.971031,994.31002 a 0.38809457,0.38757213 0 0 0 -0.357739,-0.19377 z"
|
||||
id="path3618"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
id="path3630"
|
||||
d="m 33.062615,1020.8425 -23.7569221,13.2381 c -0.1349863,0.2336 0.06345,0.5795 0.3334856,0.5814 l 45.9906705,0 c 0.270037,0 0.468473,-0.3478 0.333488,-0.5814 -22.912236,-13.1428 -22.926544,-13.255 -22.900722,-13.2381 z"
|
||||
style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;color:#000000;fill:url(#linearGradient3638);fill-opacity:1;stroke:none;stroke-width:4;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Bitstream Vera Sans;-inkscape-font-specification:Bitstream Vera Sans"
|
||||
sodipodi:nodetypes="cccccc"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
sodipodi:nodetypes="cccccc"
|
||||
style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;color:#000000;fill:url(#linearGradient3644);fill-opacity:1;stroke:none;stroke-width:4;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Bitstream Vera Sans;-inkscape-font-specification:Bitstream Vera Sans"
|
||||
d="m 32.854149,994.53305 c -0.135055,-0.23353 -0.534234,-0.23485 -0.670841,-0.002 L 9.1879715,1034.3063 c -0.1335054,0.2344 0.067312,0.579 0.3373558,0.5791 5.9693077,-5.4781 19.5453407,-12.2128 23.6767387,-14.9216 l -0.347917,-25.43075 z"
|
||||
id="path3642"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
id="path3646"
|
||||
d="m 32.169778,995.97114 c 0.135055,-0.23353 0.534234,-0.23485 0.670842,-0.002 l 22.995335,39.77546 c 0.133507,0.2344 -0.06731,0.5791 -0.337355,0.5791 0.102661,-0.049 -22.526131,-13.897 -22.536175,-13.8982 l -0.792647,-26.45412 z"
|
||||
style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;color:#000000;fill:url(#linearGradient3648);fill-opacity:1;stroke:none;stroke-width:4;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Bitstream Vera Sans;-inkscape-font-specification:Bitstream Vera Sans"
|
||||
sodipodi:nodetypes="cccccc"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;color:#000000;fill:url(#linearGradient3680);fill-opacity:1;stroke:none;stroke-width:4;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Bitstream Vera Sans;-inkscape-font-specification:Bitstream Vera Sans"
|
||||
d="m 12.313125,1032.7243 c 13.547593,0 27.095185,0 40.64278,0 -6.772788,-11.7128 -13.545573,-23.4256 -20.318359,-35.13841 -6.774808,11.71281 -13.549614,23.42561 -20.324421,35.13841 z"
|
||||
id="path2838"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
style="fill:#000000;stroke:#333333;stroke-width:0.42352057;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="m 29.60586,1009.936 1.212675,13.8059 3.104446,0 1.649237,-13.8059 -5.966358,0 z"
|
||||
id="path3682"
|
||||
sodipodi:nodetypes="ccccc"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
style="fill:#000000;stroke:#333333;stroke-width:0.42352057;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="m 34.747599,1027.8352 c 0,1.3243 -1.075008,2.3979 -2.401095,2.3979 -1.326087,0 -2.401095,-1.0736 -2.401095,-2.3979 0,-1.3243 1.075008,-2.3978 2.401095,-2.3978 1.326087,0 2.401095,1.0735 2.401095,2.3978 z"
|
||||
id="path3684"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;opacity:0.5;color:#000000;fill:#eeeeee;fill-opacity:1;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Bitstream Vera Sans;-inkscape-font-specification:Bitstream Vera Sans"
|
||||
d="m 32.577451,994.12023 a 0.38809457,0.38757213 0 0 0 -0.277935,0.18529 L 9.3102902,1034.0767 a 0.38809457,0.38757213 0 0 0 0.3308755,0.5824 l 0.3176404,0 22.3407099,-38.65949 a 0.38809457,0.38757213 0 0 1 0.31764,-0.18529 0.38809457,0.38757213 0 0 1 0.357346,0.18529 l 22.340709,38.65949 0.317641,0 a 0.38809457,0.38757213 0 0 0 0.330875,-0.5824 L 32.974502,994.30552 a 0.38809457,0.38757213 0 0 0 -0.357346,-0.18529 0.38809457,0.38757213 0 0 0 -0.0397,0 z"
|
||||
id="path2833"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;opacity:0.4;color:#000000;fill:#eeeeee;fill-opacity:1;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Bitstream Vera Sans;-inkscape-font-specification:Bitstream Vera Sans"
|
||||
d="m 9.4823455,1033.7856 -0.1720553,0.2911 a 0.38809457,0.38757213 0 0 0 0.3308755,0.5824 l 45.9916863,0 a 0.38809457,0.38757213 0 0 0 0.330875,-0.5824 l -0.172055,-0.2911 a 0.38809457,0.38757213 0 0 1 -0.15882,0.026 l -45.9916863,0 a 0.38809457,0.38757213 0 0 1 -0.1588202,-0.026 z"
|
||||
id="path2839"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;color:#000000;fill:url(#linearGradient2856);fill-opacity:1;stroke:none;stroke-width:4;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Bitstream Vera Sans;-inkscape-font-specification:Bitstream Vera Sans"
|
||||
d="m 32.643626,997.58781 -12.890907,22.27449 c 4.381105,-2.304 10.146879,-3.6925 16.464362,-3.6925 2.639259,0 5.184404,0.2491 7.57043,0.7014 L 32.643626,997.58781 z"
|
||||
id="path2843"
|
||||
inkscape:connector-curvature="0" />
|
||||
</g>
|
||||
<g id="g3243" transform="translate(51.075 .56862)">
|
||||
<path id="path3295" style="opacity:.2" d="m-29.451 12.554c0.563 5.5 1.208 10.961 1.687 16.482h1.53c0.397-5.302 1.038-10.571 1.501-15.867 0.236-1.254-0.408-2.742-1.732-3.047-1.308-0.3824-2.77 0.565-2.944 1.918-0.029 0.17-0.042 0.342-0.042 0.514zm-0.167 22.359c-0.059 1.637 1.742 2.92 3.28 2.401 1.489-0.38 2.274-2.252 1.51-3.583-0.683-1.375-2.687-1.829-3.84-0.776-0.582 0.479-0.968 1.194-0.95 1.958z"/>
|
||||
<path id="text2315" style="fill:#fff" d="m-29.451 13.555c0.563 5.499 1.208 10.96 1.687 16.481h1.53c0.397-5.301 1.038-10.571 1.501-15.866 0.236-1.254-0.408-2.743-1.732-3.048-1.308-0.382-2.77 0.565-2.944 1.918-0.029 0.17-0.042 0.342-0.042 0.515zm-0.167 22.358c-0.059 1.637 1.742 2.921 3.28 2.402 1.489-0.381 2.274-2.253 1.51-3.584-0.683-1.375-2.687-1.828-3.84-0.776-0.582 0.479-0.968 1.194-0.95 1.958z"/>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 3.2 KiB After Width: | Height: | Size: 24 KiB |
@ -117,7 +117,7 @@ void runningDeviceWidget::populate()
|
||||
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"));
|
||||
myDevice->lblCertified->setToolTip(tr("Tagged officially released firmware build"));
|
||||
|
||||
}
|
||||
else
|
||||
@ -125,7 +125,7 @@ void runningDeviceWidget::populate()
|
||||
myDevice->lblFWTag->setText(QString("Firmware tag: ")+devDesc.description);
|
||||
QPixmap pix = QPixmap(QString(":uploader/images/warning.svg"));
|
||||
myDevice->lblCertified->setPixmap(pix);
|
||||
myDevice->lblCertified->setToolTip(tr("Custom Firmware Build"));
|
||||
myDevice->lblCertified->setToolTip(tr("Untagged or custom firmware build"));
|
||||
}
|
||||
myDevice->lblGitCommitTag->setText("Git commit tag: "+devDesc.gitTag);
|
||||
myDevice->lblFWDate->setText(QString("Firmware date: ") + devDesc.buildDate);
|
||||
|
@ -11,5 +11,6 @@
|
||||
<file>images/deviceID-0101.svg</file>
|
||||
<file>images/application-certificate.svg</file>
|
||||
<file>images/warning.svg</file>
|
||||
<file>images/error.svg</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
|
@ -34,6 +34,7 @@ bool UAVObjectGeneratorFlight::generate(UAVObjectParser* parser,QString template
|
||||
<<"uint16_t" << "uint32_t" << "float" << "uint8_t";
|
||||
|
||||
QString flightObjInit,objInc,objFileNames,objNames;
|
||||
qint32 sizeCalc;
|
||||
flightCodePath = QDir( templatepath + QString("flight/UAVObjects"));
|
||||
flightOutputPath = QDir( outputpath + QString("flight") );
|
||||
flightOutputPath.mkpath(flightOutputPath.absolutePath());
|
||||
@ -41,6 +42,7 @@ bool UAVObjectGeneratorFlight::generate(UAVObjectParser* parser,QString template
|
||||
flightCodeTemplate = readFile( flightCodePath.absoluteFilePath("uavobjecttemplate.c") );
|
||||
flightIncludeTemplate = readFile( flightCodePath.absoluteFilePath("inc/uavobjecttemplate.h") );
|
||||
flightInitTemplate = readFile( flightCodePath.absoluteFilePath("uavobjectsinittemplate.c") );
|
||||
flightInitIncludeTemplate = readFile( flightCodePath.absoluteFilePath("inc/uavobjectsinittemplate.h") );
|
||||
flightMakeTemplate = readFile( flightCodePath.absoluteFilePath("Makefiletemplate.inc") );
|
||||
|
||||
if ( flightCodeTemplate.isNull() || flightIncludeTemplate.isNull() || flightInitTemplate.isNull()) {
|
||||
@ -48,6 +50,7 @@ bool UAVObjectGeneratorFlight::generate(UAVObjectParser* parser,QString template
|
||||
return false;
|
||||
}
|
||||
|
||||
sizeCalc = 0;
|
||||
for (int objidx = 0; objidx < parser->getNumObjects(); ++objidx) {
|
||||
ObjectInfo* info=parser->getObjectByIndex(objidx);
|
||||
process_object(info);
|
||||
@ -57,6 +60,9 @@ bool UAVObjectGeneratorFlight::generate(UAVObjectParser* parser,QString template
|
||||
objInc.append("#include \"" + info->namelc + ".h\"\r\n");
|
||||
objFileNames.append(" " + info->namelc);
|
||||
objNames.append(" " + info->name);
|
||||
if (parser->getNumBytes(objidx)>sizeCalc) {
|
||||
sizeCalc = parser->getNumBytes(objidx);
|
||||
}
|
||||
}
|
||||
|
||||
// Write the flight object inialization files
|
||||
@ -65,7 +71,16 @@ bool UAVObjectGeneratorFlight::generate(UAVObjectParser* parser,QString template
|
||||
bool res = writeFileIfDiffrent( flightOutputPath.absolutePath() + "/uavobjectsinit.c",
|
||||
flightInitTemplate );
|
||||
if (!res) {
|
||||
cout << "Error: Could not write flight object init files" << endl;
|
||||
cout << "Error: Could not write flight object init file" << endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
// Write the flight object initialization header
|
||||
flightInitIncludeTemplate.replace( QString("$(SIZECALCULATION)"), QString().setNum(sizeCalc));
|
||||
res = writeFileIfDiffrent( flightOutputPath.absolutePath() + "/uavobjectsinit.h",
|
||||
flightInitIncludeTemplate );
|
||||
if (!res) {
|
||||
cout << "Error: Could not write flight object init header file" << endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -34,7 +34,7 @@ class UAVObjectGeneratorFlight
|
||||
public:
|
||||
bool generate(UAVObjectParser* gen,QString templatepath,QString outputpath);
|
||||
QStringList fieldTypeStrC;
|
||||
QString flightCodeTemplate, flightIncludeTemplate, flightInitTemplate, flightMakeTemplate;
|
||||
QString flightCodeTemplate, flightIncludeTemplate, flightInitTemplate, flightInitIncludeTemplate, flightMakeTemplate;
|
||||
QDir flightCodePath;
|
||||
QDir flightOutputPath;
|
||||
|
||||
|
@ -5,7 +5,7 @@
|
||||
<field name="GyroBias" units="deg/s * 100" type="int16" elementnames="X,Y,Z" defaultvalue="0"/>
|
||||
<field name="BoardRotation" units="deg" type="int16" elementnames="Roll,Pitch,Yaw" defaultvalue="0,0,0"/>
|
||||
<field name="GyroGain" units="(rad/s)/lsb" type="float" elements="1" defaultvalue="0.42"/>
|
||||
<field name="AccelKp" units="channel" type="float" elements="1" defaultvalue="0.03"/>
|
||||
<field name="AccelKp" units="channel" type="float" elements="1" defaultvalue="0.05"/>
|
||||
<field name="AccelKi" units="channel" type="float" elements="1" defaultvalue="0.0001"/>
|
||||
<field name="YawBiasRate" units="channel" type="float" elements="1" defaultvalue="0.000001"/>
|
||||
<field name="ZeroDuringArming" units="channel" type="enum" elements="1" options="FALSE,TRUE" defaultvalue="TRUE"/>
|
||||
|
12
shared/uavobjectdefinition/cameradesired.xml
Normal file
12
shared/uavobjectdefinition/cameradesired.xml
Normal file
@ -0,0 +1,12 @@
|
||||
<xml>
|
||||
<object name="CameraDesired" singleinstance="true" settings="false">
|
||||
<description>Desired camera outputs. Comes from @ref CameraStabilization module.</description>
|
||||
<field name="Roll" units="" type="float" elements="1"/>
|
||||
<field name="Pitch" units="" type="float" elements="1"/>
|
||||
<field name="Yaw" units="" type="float" elements="1"/>
|
||||
<access gcs="readwrite" flight="readwrite"/>
|
||||
<telemetrygcs acked="false" updatemode="manual" period="0"/>
|
||||
<telemetryflight acked="false" updatemode="periodic" period="1000"/>
|
||||
<logging updatemode="never" period="0"/>
|
||||
</object>
|
||||
</xml>
|
12
shared/uavobjectdefinition/camerastabsettings.xml
Normal file
12
shared/uavobjectdefinition/camerastabsettings.xml
Normal file
@ -0,0 +1,12 @@
|
||||
<xml>
|
||||
<object name="CameraStabSettings" singleinstance="true" settings="true">
|
||||
<description>Settings for the @ref CameraStab mmodule</description>
|
||||
<field name="Inputs" units="channel" type="enum" elementnames="Roll,Pitch,Yaw" options="Accessory0,Accessory1,Accessory2,Accessory3,Accessory4,Accessory5,,None" defaultvalue="None"/>
|
||||
<field name="InputRange" units="deg" type="uint8" elementnames="Roll,Pitch,Yaw" defaultvalue="20"/>
|
||||
<field name="OutputRange" units="deg" type="uint8" elementnames="Roll,Pitch,Yaw" defaultvalue="20"/>
|
||||
<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>
|
@ -1,11 +1,12 @@
|
||||
<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 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"/>
|
||||
<field name="OptionalModules" units="" type="enum" elementnames="CameraStabilization,GPS" options="Disabled,Enabled" defaultvalue="Disabled"/>
|
||||
<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>
|
||||
|
@ -5,24 +5,24 @@
|
||||
<field name="FeedForward" units="" 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="ThrottleCurve1" units="percent" type="float" elements="5" elementnames="0,25,50,75,100" defaultvalue="0,0,0,0,0"/>
|
||||
<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="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,CameraRoll,CameraPitch,CameraYaw,Accessory0,Accessory1,Accessory2,Accessory3,Accessory4,Accessory5" defaultvalue="Disabled"/>
|
||||
<field name="Mixer1Vector" units="" type="int8" elements="5" elementnames="ThrottleCurve1,ThrottleCurve2,Roll,Pitch,Yaw" defaultvalue="0"/>
|
||||
<field name="Mixer2Type" units="" type="enum" elements="1" options="Disabled,Motor,Servo,Accessory0,Accessory1,Accessory2,Accessory3,Accessory4,Accessory5" defaultvalue="Disabled"/>
|
||||
<field name="Mixer2Type" units="" type="enum" elements="1" options="Disabled,Motor,Servo,CameraRoll,CameraPitch,CameraYaw,Accessory0,Accessory1,Accessory2,Accessory3,Accessory4,Accessory5" defaultvalue="Disabled"/>
|
||||
<field name="Mixer2Vector" units="" type="int8" elements="5" elementnames="ThrottleCurve1,ThrottleCurve2,Roll,Pitch,Yaw" defaultvalue="0"/>
|
||||
<field name="Mixer3Type" units="" type="enum" elements="1" options="Disabled,Motor,Servo,Accessory0,Accessory1,Accessory2,Accessory3,Accessory4,Accessory5" defaultvalue="Disabled"/>
|
||||
<field name="Mixer3Type" units="" type="enum" elements="1" options="Disabled,Motor,Servo,CameraRoll,CameraPitch,CameraYaw,Accessory0,Accessory1,Accessory2,Accessory3,Accessory4,Accessory5" defaultvalue="Disabled"/>
|
||||
<field name="Mixer3Vector" units="" type="int8" elements="5" elementnames="ThrottleCurve1,ThrottleCurve2,Roll,Pitch,Yaw" defaultvalue="0"/>
|
||||
<field name="Mixer4Type" units="" type="enum" elements="1" options="Disabled,Motor,Servo,Accessory0,Accessory1,Accessory2,Accessory3,Accessory4,Accessory5" defaultvalue="Disabled"/>
|
||||
<field name="Mixer4Type" units="" type="enum" elements="1" options="Disabled,Motor,Servo,CameraRoll,CameraPitch,CameraYaw,Accessory0,Accessory1,Accessory2,Accessory3,Accessory4,Accessory5" defaultvalue="Disabled"/>
|
||||
<field name="Mixer4Vector" units="" type="int8" elements="5" elementnames="ThrottleCurve1,ThrottleCurve2,Roll,Pitch,Yaw" defaultvalue="0"/>
|
||||
<field name="Mixer5Type" units="" type="enum" elements="1" options="Disabled,Motor,Servo,Accessory0,Accessory1,Accessory2,Accessory3,Accessory4,Accessory5" defaultvalue="Disabled"/>
|
||||
<field name="Mixer5Type" units="" type="enum" elements="1" options="Disabled,Motor,Servo,CameraRoll,CameraPitch,CameraYaw,Accessory0,Accessory1,Accessory2,Accessory3,Accessory4,Accessory5" defaultvalue="Disabled"/>
|
||||
<field name="Mixer5Vector" units="" type="int8" elements="5" elementnames="ThrottleCurve1,ThrottleCurve2,Roll,Pitch,Yaw" defaultvalue="0"/>
|
||||
<field name="Mixer6Type" units="" type="enum" elements="1" options="Disabled,Motor,Servo,Accessory0,Accessory1,Accessory2,Accessory3,Accessory4,Accessory5" defaultvalue="Disabled"/>
|
||||
<field name="Mixer6Type" units="" type="enum" elements="1" options="Disabled,Motor,Servo,CameraRoll,CameraPitch,CameraYaw,Accessory0,Accessory1,Accessory2,Accessory3,Accessory4,Accessory5" defaultvalue="Disabled"/>
|
||||
<field name="Mixer6Vector" units="" type="int8" elements="5" elementnames="ThrottleCurve1,ThrottleCurve2,Roll,Pitch,Yaw" defaultvalue="0"/>
|
||||
<field name="Mixer7Type" units="" type="enum" elements="1" options="Disabled,Motor,Servo,Accessory0,Accessory1,Accessory2,Accessory3,Accessory4,Accessory5" defaultvalue="Disabled"/>
|
||||
<field name="Mixer7Type" units="" type="enum" elements="1" options="Disabled,Motor,Servo,CameraRoll,CameraPitch,CameraYaw,Accessory0,Accessory1,Accessory2,Accessory3,Accessory4,Accessory5" defaultvalue="Disabled"/>
|
||||
<field name="Mixer7Vector" units="" type="int8" elements="5" elementnames="ThrottleCurve1,ThrottleCurve2,Roll,Pitch,Yaw" defaultvalue="0"/>
|
||||
<field name="Mixer8Type" units="" type="enum" elements="1" options="Disabled,Motor,Servo,Accessory0,Accessory1,Accessory2,Accessory3,Accessory4,Accessory5" defaultvalue="Disabled"/>
|
||||
<field name="Mixer8Type" units="" type="enum" elements="1" options="Disabled,Motor,Servo,CameraRoll,CameraPitch,CameraYaw,Accessory0,Accessory1,Accessory2,Accessory3,Accessory4,Accessory5" defaultvalue="Disabled"/>
|
||||
<field name="Mixer8Vector" units="" type="int8" elements="5" elementnames="ThrottleCurve1,ThrottleCurve2,Roll,Pitch,Yaw" defaultvalue="0"/>
|
||||
<access gcs="readwrite" flight="readwrite"/>
|
||||
<telemetrygcs acked="true" updatemode="onchange" period="0"/>
|
||||
|
@ -16,7 +16,7 @@
|
||||
|
||||
<field name="GyroTau" units="" type="float" elements="1" defaultvalue="0.005"/>
|
||||
|
||||
<field name="MaxAxisLock" units="deg" type="uint8" elements="1" defaultvalue="5"/>
|
||||
<field name="MaxAxisLock" units="deg" type="uint8" elements="1" defaultvalue="15"/>
|
||||
<field name="MaxAxisLockRate" units="deg/s" type="uint8" elements="1" defaultvalue="2"/>
|
||||
|
||||
<field name="WeakLevelingKp" units="(deg/s)/deg" type="float" elements="1" defaultvalue="0.1"/>
|
||||
|
Loading…
Reference in New Issue
Block a user