mirror of
https://bitbucket.org/librepilot/librepilot.git
synced 2025-01-18 03:52:11 +01:00
Merge remote-tracking branch 'origin/next' into os/OP-775_arm-dsplib
This commit is contained in:
commit
97436166e3
86
CREDITS.txt
86
CREDITS.txt
@ -6,47 +6,41 @@ It is sorted alphabetically by name and formatted so that it allows for easy gre
|
||||
The fields are:
|
||||
|
||||
Name (N)
|
||||
Email (E),
|
||||
Description of work (D)
|
||||
Current maintainer function (M)
|
||||
|
||||
----------
|
||||
|
||||
N: Connor Abbott
|
||||
E: connor (at) abbott (dot) cx
|
||||
D: Win32 OpenPilot port
|
||||
|
||||
N: David Ankers
|
||||
E: david (at) openpilot (dot) org
|
||||
D: Co-founder, Project Coordination
|
||||
D: Minor GCS infrastructure, updating the credit file
|
||||
M: Admin
|
||||
|
||||
N: Sergiy Anikeyev
|
||||
D: Improvments to Camera Gimbal control
|
||||
|
||||
N: Pedro Assuncao
|
||||
E: pedro (dot) agda (plus) openpilot (at) gmail (dot) com
|
||||
D: Initial GCS Settings Gadget work
|
||||
|
||||
N: Fredrik Arvidsson
|
||||
E: fredrik (at) arvidssons (dot) org
|
||||
W: GCS Setup Wizard
|
||||
D: GCS Setup Wizard
|
||||
M: GCS Setup Wizard
|
||||
|
||||
N: Werner Backes
|
||||
E: werner (at) bit-1 (dot) de
|
||||
D: Port of CopterControl to PS3 Move Controller (MoveCopter)
|
||||
|
||||
N: Jose Barros
|
||||
E: josembarros (at) hotmail (dot) com
|
||||
D: Next-Gen OP Map Lib, Y-Modem Library, Uploader Plugin
|
||||
D: OP Bootloader, AHRS Bootloader, OPUploadTool and much else
|
||||
M: Bootloader, OP MAP Lib
|
||||
|
||||
N: David "Buzz" Carlson
|
||||
E: chebuzz (plus) openpilot (at) gmail (dot) com
|
||||
D: 3D ModelView GCS Plugin, sponsor of HITL merge work and XPlane addition
|
||||
|
||||
N: James Cotton
|
||||
E: peabody124 (plus) openpilot (at) gmail (dot) com
|
||||
D: Multiplatform HID implementation (firmware & GCS), GCS Joystick control
|
||||
D: Posix OpenPilot work and Mac implementation
|
||||
D: Firmware implementation of Professor Schinstock's INS/GPS
|
||||
@ -54,187 +48,159 @@ D: Android GCS and much else
|
||||
M: Architecture co-lead, Android GCS Lead
|
||||
|
||||
N: Steve Doll
|
||||
E: speakfree07 (at) hotmail (dot) com
|
||||
D: Much Artwork, Logo rework, Welcome page design
|
||||
|
||||
N: Piotr Esden-Tempski
|
||||
E: esden (at) esden (dot) net
|
||||
D: Floss-JTAG Rev A, 4-layer initial design
|
||||
|
||||
N: Richard Flay
|
||||
D: Multiple fixes / Review guru
|
||||
|
||||
N: Darren Furniss
|
||||
E: furnibird (plus) openpilot (at) gmail (dot) com
|
||||
W: GCS Artwork and Android GCS Artwork
|
||||
D: GCS Artwork and Android GCS Artwork
|
||||
|
||||
N: Frederic Goddeeris
|
||||
E: fredericgoddeeris (at) hotmail (dot) com
|
||||
D: I2C work and FreeRTOS work, MK integration
|
||||
D: EagleTree OSD implementation
|
||||
|
||||
N: Daniel Godin
|
||||
E: dgodin (at) dnsct (dot) com
|
||||
W: Sponsor: Notify Plugin for the GCS
|
||||
D: Sponsor: Notify Plugin for the GCS
|
||||
|
||||
N: Bani Greyling
|
||||
E: bani (dot) greyling (plus) openpilot (at) gmail (dot) com
|
||||
D: GCS Scope plugin
|
||||
|
||||
N: Nuno Guedes
|
||||
E: muralha (plus) openpilot (at) gmail (dot) com
|
||||
D: 3D artwork, moving surfaces and work on ModelView
|
||||
D: PFD Artwork
|
||||
|
||||
N: Erik Gustavsson
|
||||
D: Attitude LPF improvments to Self Level
|
||||
|
||||
N: Peter Gunnarsson
|
||||
E: peter (at) pyne (dot) se
|
||||
D: GCS Core Developer
|
||||
D: Multiple GCS plugins, Gadget foundations, UAVObject viewer
|
||||
|
||||
N: Dean Hall
|
||||
E: dwhall256 (plus) openpilot (at) gmail (dot) com
|
||||
D: Creator of http://pythononachip.org
|
||||
|
||||
N: Joe Hlebasko
|
||||
E: joe (dot) hlebasko(plus) openpilot (at) gmail (dot) com
|
||||
D: Early versions of Main Board & Production OP GPS
|
||||
M: Hardware Architecture Team
|
||||
|
||||
N: Andy Honecker
|
||||
E: andywh (at) yahoo (dot) com
|
||||
D: Hardware design review and optimisation
|
||||
|
||||
N: Mark James
|
||||
E: mjames (plus) openpilot (at) gmail (dot) com
|
||||
D: Some of Silk Icon set used in GCS - http://www.famfamfam.com/lab/icons/silk
|
||||
|
||||
N: Sami Korhonen
|
||||
E: samik (dot) korhonen (plus) openpilot (at) gmail (dot) com
|
||||
D: GPS Module, Spektrum RC Module, OSD work
|
||||
M: OpenPilot OSD
|
||||
|
||||
N: Thorsten Klose
|
||||
E: thorsten (dot) klose (at) dmx (dot) de
|
||||
D: Embedded STM32 infrastructure
|
||||
|
||||
N: Hallvard Kristiansen
|
||||
E: hal (at) fleshmx (dot) com
|
||||
D: GCS Artwork, Quad layout diagrams
|
||||
|
||||
N: Mike Labranche
|
||||
E: mdlabranche (plus) openpilot (at) gmail (dot) com
|
||||
D: Tab bar Telem Monitor
|
||||
|
||||
N: Edouard Lafargue
|
||||
E: edouard (at) lafargue (dot) name
|
||||
D: GCS Dial Plugins, GCS PFD Plugin, GCS GPS plugin, GCS Config plugin
|
||||
D: Artwork including standard display dials
|
||||
|
||||
N: Matt Lipski
|
||||
E: mattlipski (plus) openpilot (at) gmail (dot) com
|
||||
D: Deluxe Dials Set artwork, (Artificial Horizon, Compass, Turn Indicator)
|
||||
|
||||
N: Les Newell
|
||||
E: les (dot) newell (at) fastmail (dot) co (dot) uk
|
||||
D: Advanced mixer matrix, SPI protocol based on UAVObjects, feedforward
|
||||
|
||||
N: Ken Northup
|
||||
E: helos360 (at) bellsouth (dot) net
|
||||
D: 3D Modelling, Easystar adaption from FMS
|
||||
|
||||
N: Guy McCaldin
|
||||
E: guymcc (at) gmail (dot) com
|
||||
D: Artwork and design including work on the Deluxe Dial Set
|
||||
|
||||
N: Alessio Morale
|
||||
D: Firmware/Architecture Lead
|
||||
|
||||
N: Cathy Moss
|
||||
E: cmoss296 (at) blueyonder (dot) co (dot) uk
|
||||
D: Hardware design Lead: Gen 2 Mainboard, PipXtreme, Current Sensor
|
||||
D: PipXtreme designer, creator OP Map Plugin
|
||||
|
||||
N: Angus Peart
|
||||
E: gussy (at) openpilot (dot) org
|
||||
D: Co-founder, Principal hardware architect.
|
||||
D: Hardware design of early OpenPilot, AHRS, GPS and other hardware
|
||||
|
||||
N: Dmytro Poplavskiy
|
||||
E: dmytro (dot) poplavskiy (plus) openpilot (at) gmail (dot) com
|
||||
W: QML PFD, QML Welcome page
|
||||
D: QML PFD, QML Welcome page
|
||||
M: Qml plugins
|
||||
|
||||
N: Eric Price
|
||||
E: corvus (dot) corax (at) cybertrench (dot) com
|
||||
D: IL2 HITL GCS Plugin, Posix OpenPilot, Advanced stabilisation module
|
||||
M: SITL Posix, SLAM work
|
||||
|
||||
N: Richard Querin
|
||||
E: rfquerin (plus) openpilot (at) gmail (dot) com
|
||||
D: Graphic Design, OpenPilot Logo
|
||||
|
||||
N: Laurent Ribon
|
||||
E: ribon (dot) l (at) club-internet (dot) fr
|
||||
D: The GLC_lib as used in the ModelView Plugin
|
||||
D: See: http://www.glc-lib.net/
|
||||
|
||||
N: Julien Rouviere
|
||||
E: julien (dot) rouviere (plus) openpilot (at) gmail (dot) com
|
||||
D: GCS Framework and Plugins for the GCS
|
||||
|
||||
N: Zik Saleeba
|
||||
E: zik (at) zikzak (dot) net
|
||||
D: Initial schematic based on Zik's Flying Fox schematic
|
||||
|
||||
N: Professor Dale Schinstock
|
||||
E: dales (at) ksu (dot) edu
|
||||
D: Lead AHRS Developer
|
||||
D: Lead INS Developer
|
||||
D: Creator of the OpenPilot INS / EKF
|
||||
|
||||
N: Professor Kenn Sebesta
|
||||
E: kenn (at) openpilot (dot) org
|
||||
D: Lead Fixed Wing Developer
|
||||
M: Fixed Wing support
|
||||
D: Lead Fixed Wing Developer CC3D / Controls
|
||||
D: GCS improvments including HiTL Merge
|
||||
M: Fixed Wing support CC3D
|
||||
|
||||
N: Oleg Semyonov
|
||||
E: os-openpilot-org (at) os-propo (dot) info
|
||||
D: Core tester & Project organisation
|
||||
D: Core Developer & Project organisation
|
||||
D: TxPID module
|
||||
M: CameraStab module
|
||||
M: Common part of multi-platform packaging system
|
||||
M: Windows NSIS Installer
|
||||
M: Russian Documentation Lead
|
||||
|
||||
N: Stacey Sheldon
|
||||
E: stac (at) solidgoldbomb (dot) org
|
||||
D: Core Embedded Developer
|
||||
D: SPI protocol for AHRS, I2C rewrite and much core work
|
||||
|
||||
N: Troy Schultz
|
||||
E: troy (dot) schultz (at) rogers (dot) com
|
||||
D: INS design review and optimisation
|
||||
|
||||
N: Dr. Erhard Siegl
|
||||
E: Erhard (dot) Siegl (at) zogazoga (dot) at
|
||||
D: Configuration engine for the GCS
|
||||
|
||||
N: Pete Stapley
|
||||
E: pete (at) stapleylabs (dot) com
|
||||
D: PPM inputs
|
||||
|
||||
N: Rowan Taubitz
|
||||
E: rowan (at) zantek (dot) com (dot) au
|
||||
D: Hardware debugging and testing, creation of 2-layer Floss-JTAG Rev B
|
||||
D: Creation of Next-Gen FOSS-JTAG board
|
||||
|
||||
N: Andrew Thoms
|
||||
E: electronics (at) andrewspizza (dot) net
|
||||
D: IP Telemtry plugin for the GCS
|
||||
D: Helicopter support code and mixing for CCPM
|
||||
|
||||
N: Vassilis Varveropoulos
|
||||
E: vassilis (at) openpilot (dot) org
|
||||
D: Co-founder, Principal embedded software architect.
|
||||
D: Module architecture and UAVTalk/UAVObjects implementation.
|
||||
|
||||
N: Alex Vrubel
|
||||
E: alex (dot) vrubel (plus) openpilot (at) gmail (dot) com
|
||||
D: Russian translation of the GCS
|
||||
|
||||
N: Brian Webb
|
||||
E: webbbn (plus) openpilot (at) gmail (dot) com
|
||||
W: Modem lead developer
|
||||
D: Modem lead developer
|
||||
M: OP Modems
|
||||
|
||||
N: Dmitriy Zaitsev
|
||||
D: AeroSim-RC HiTL plugin
|
||||
|
31
HISTORY.txt
31
HISTORY.txt
@ -1,5 +1,34 @@
|
||||
Short summary of changes. For a complete list see the git log.
|
||||
|
||||
2012-11-17
|
||||
Advanced camera stabilization features.
|
||||
They include optional manual control input filtering (moved from camera
|
||||
stabilization to manual control input and now available also for main controls),
|
||||
optional airframe attitude filtering used by camera stabilization, and optional
|
||||
camera actuator feed forward to improve gimbal response.
|
||||
|
||||
--- RELEASE-12.10.2 --- Mayan Apocalypse Release ---
|
||||
|
||||
List of issues resolved in this maintenance release:
|
||||
http://progress.openpilot.org/issues/?filter=10361
|
||||
|
||||
OP-459, OP-545, OP-674, OP-679, OP-685, OP-686, OP-687, OP-690, OP-691,
|
||||
OP-702, OP-703, OP-714, OP-715, OP-716, OP-721, OP-728, OP-746, OP-748,
|
||||
OP-749, OP-750, OP-758, OP-759, OP-760
|
||||
|
||||
2012-11-12
|
||||
Implemented smoothing filter for accelerometer data.
|
||||
Added support for Mode 3 and Mode 4 to the TX Configuration Wizard.
|
||||
|
||||
--- RELEASE-12.10.1 ---
|
||||
|
||||
2012-10-26
|
||||
Temporary disabled AutoTune GCS GUI. It was listed as an experimental
|
||||
feature in the previous release, there were however a few cases where
|
||||
it did not behave as expected.
|
||||
|
||||
--- RELEASE-12.10 ---
|
||||
|
||||
2012-10-06
|
||||
Receiver port can now be configured as PPM *and* PWM inputs.
|
||||
Pin 1 is PPM, other pins are PWM inputs.
|
||||
@ -14,7 +43,7 @@ Several UI changes.
|
||||
MixerCurveWidget refactoring, now as a simple and advanced view.
|
||||
|
||||
2012-07-27
|
||||
Added “advanced mode” option to general settings. Right now it only shows the hidden apply buttons.
|
||||
Added "advanced mode" option to general settings. Right now it only shows the hidden apply buttons.
|
||||
To enable go to tools->options->General and click one of the checkboxes to give focus to the form,
|
||||
then press F7
|
||||
|
||||
|
@ -1,10 +1,22 @@
|
||||
+ Halt/Reset buttons don't work if board is armed. But no way to use them if "Always armed". Use rescue as workaround.
|
||||
+ Missing Translations, use English.
|
||||
+ Radio Wizard confused by a reversed throttle, fix it on your transmitter before starting wizard.
|
||||
+ [Windows 8] USB Driver is broken.
|
||||
+ Firmware Update Instructions on Firmware Tab not entirely accurate for all upgrade paths.
|
||||
+ Radio Wizard Throttle display does not show full range properly.
|
||||
+ Tricopter's using Vehicle Wizard need to check servo does not need reversed manually.
|
||||
+ XAircraft ESCs uses non-standard PPM range which may cause issues with Vehicle Wizard.
|
||||
+ Spectrum Satellite Receivers setup in Radio Wizard may have wrong protocol set.
|
||||
+ Old Intel 965 have an OpenGL bug that turns the QML PFD black and while.
|
||||
Here is a list of some known unresolved issues. If an issue has JIRA ID [OP-XXX], you may track it using the
|
||||
following URL: http://bugs.openpilot.org/browse/OP-XXX
|
||||
|
||||
+ Missing Translations, use English.
|
||||
+ Radio Wizard confused by a reversed throttle, fix it on your transmitter before starting wizard.
|
||||
+ Radio Wizard Throttle display does not show full range properly.
|
||||
+ [Windows 8] USB Driver is broken.
|
||||
+ Firmware Update Instructions on Firmware Tab not entirely accurate for all upgrade paths.
|
||||
+ Tricopter's using Vehicle Wizard need to check servo does not need reversed manually.
|
||||
+ XAircraft ESCs uses non-standard PPM range which may cause issues with Vehicle Wizard.
|
||||
+ Spectrum Satellite Receivers setup in Radio Wizard may have wrong protocol set.
|
||||
+ Old Intel 965 have an OpenGL bug that turns the QML PFD black and while.
|
||||
+ [OP-732] Import UAV Settings for inactive modules crashes the running firmware (board restarts).
|
||||
Workaround: update firmware, power cycle, enable modules, power cycle, import configuration.
|
||||
+ [OP-747] Board infinitely reboots itself after firmware upgrade (settings erase firmware is a workaround).
|
||||
+ [OP-723] GCS uses the system language ot the 1st run. After restart it uses English (can be changed later).
|
||||
+ [OP-725] GCS camera stab config error message disappears too fast (but config error is cleared as it should)
|
||||
+ [OP-767] GCS does not send AttitudeActual packets over serial port when GPS is connected and system is armed
|
||||
+ [OP-768] GCS does not show UAV position on the map (master or next CC branches, but works in Revo branches)
|
||||
+ [OP-682] GCS crashes on firmware page. Noted on Windows and OSX platforms, difficult to reproduce.
|
||||
Workaround: use Vehicle setup wizard to update the firmware.
|
||||
+ [OP-769] Can't enter "12,45" on German system. Workaround: change GCS language (in fact, locale) to German.
|
||||
|
@ -240,8 +240,8 @@ C:
|
||||
D:
|
||||
V:
|
||||
|
||||
M: First Auto landing on a fixed Wing using Revo
|
||||
C:
|
||||
M: First Auto spot landing on a fixed Wing using Revo
|
||||
C:
|
||||
D:
|
||||
V:
|
||||
|
||||
|
20
Makefile
20
Makefile
@ -445,7 +445,7 @@ dfuutil_clean:
|
||||
# see http://developer.android.com/sdk/ for latest versions
|
||||
ANDROID_SDK_DIR := $(TOOLS_DIR)/android-sdk-linux
|
||||
.PHONY: android_sdk_install
|
||||
android_sdk_install: ANDROID_SDK_URL := http://dl.google.com/android/android-sdk_r20.0.3-linux.tgz
|
||||
android_sdk_install: ANDROID_SDK_URL := http://dl.google.com/android/android-sdk_r21.0.1-linux.tgz
|
||||
android_sdk_install: ANDROID_SDK_FILE := $(notdir $(ANDROID_SDK_URL))
|
||||
# order-only prereq on directory existance:
|
||||
android_sdk_install: | $(DL_DIR) $(TOOLS_DIR)
|
||||
@ -466,7 +466,7 @@ android_sdk_clean:
|
||||
.PHONY: android_sdk_update
|
||||
android_sdk_update:
|
||||
$(V0) @echo " UPDATE $(ANDROID_SDK_DIR)"
|
||||
$(ANDROID_SDK_DIR)/tools/android update sdk --no-ui -t platform-tools,android-16,addon-google_apis-google-16
|
||||
$(ANDROID_SDK_DIR)/tools/android update sdk --no-ui -t platform-tools,android-14,addon-google_apis-google-14
|
||||
|
||||
##############################
|
||||
#
|
||||
@ -579,6 +579,7 @@ uavobjects_clean:
|
||||
#
|
||||
################################
|
||||
|
||||
ANDROIDGCS_BUILD_CONF ?= debug
|
||||
|
||||
# Build the output directory for the Android GCS build
|
||||
ANDROIDGCS_OUT_DIR := $(BUILD_DIR)/androidgcs
|
||||
@ -601,12 +602,12 @@ endif
|
||||
androidgcs: uavo-collections_java
|
||||
$(V0) @echo " ANDROID $(call toprel, $(ANDROIDGCS_OUT_DIR))"
|
||||
$(V1) mkdir -p $(ANDROIDGCS_OUT_DIR)
|
||||
$(V1) $(ANDROID) $(ANDROID_SILENT) update project --target 'Google Inc.:Google APIs:16' --name androidgcs --path ./androidgcs
|
||||
$(V1) $(ANDROID) $(ANDROID_SILENT) update project --target 'Google Inc.:Google APIs:14' --name androidgcs --path ./androidgcs
|
||||
$(V1) ant -f ./androidgcs/build.xml \
|
||||
$(ANT_QUIET) \
|
||||
-Dout.dir="../$(call toprel, $(ANDROIDGCS_OUT_DIR)/bin)" \
|
||||
-Dgen.absolute.dir="$(ANDROIDGCS_OUT_DIR)/gen" \
|
||||
debug
|
||||
$(ANDROIDGCS_BUILD_CONF)
|
||||
|
||||
.PHONY: androidgcs_clean
|
||||
androidgcs_clean:
|
||||
@ -618,7 +619,7 @@ androidgcs_clean:
|
||||
#
|
||||
# Find the git hashes of each commit that changes uavobjects with:
|
||||
# git log --format=%h -- shared/uavobjectdefinition/ | head -n 2
|
||||
UAVO_GIT_VERSIONS := 684620d 43f85d9
|
||||
UAVO_GIT_VERSIONS := 5e14f53
|
||||
|
||||
# All versions includes a pseudo collection called "working" which represents
|
||||
# the UAVOs in the source tree
|
||||
@ -980,3 +981,12 @@ package:
|
||||
.PHONY: package_resources
|
||||
package_resources:
|
||||
$(V1) cd package && $(MAKE) --no-print-directory opfw_resource
|
||||
|
||||
.PHONY: build-info
|
||||
build-info:
|
||||
$(V1) mkdir -p $(BUILD_DIR)
|
||||
$(V1) python $(ROOT_DIR)/make/scripts/version-info.py \
|
||||
--path=$(ROOT_DIR) \
|
||||
--uavodir=$(ROOT_DIR)/shared/uavobjectdefinition \
|
||||
--template="make/templates/$@.txt" \
|
||||
--outfile="$(BUILD_DIR)/$@.txt"
|
||||
|
@ -1,16 +1,13 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @addtogroup OpenPilotModules OpenPilot Modules
|
||||
* @{
|
||||
* @addtogroup Radio Input / Output Module
|
||||
* @brief Read and Write packets from/to a radio device.
|
||||
* @{
|
||||
*
|
||||
* @file radio.h
|
||||
* @file %FILENAME%
|
||||
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2012.
|
||||
* @brief Include file of the radio module.
|
||||
* @see The GNU Public License (GPL) Version 3
|
||||
*
|
||||
* @addtogroup [Group]
|
||||
* @{
|
||||
* @addtogroup %CLASS%
|
||||
* @{
|
||||
* @brief [Brief]
|
||||
*****************************************************************************/
|
||||
/*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
@ -27,13 +24,3 @@
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef RADIOMODULE_H
|
||||
#define RADIOMODULE_H
|
||||
|
||||
#endif // RADIOMODULE_H
|
||||
|
||||
/**
|
||||
* @}
|
||||
* @}
|
||||
*/
|
@ -77,6 +77,11 @@ USE_ALTITUDE ?= NO
|
||||
USE_AUTOTUNE ?= YES
|
||||
TEST_FAULTS ?= NO
|
||||
|
||||
# Camera gimbal options
|
||||
USE_INPUT_LPF ?= YES
|
||||
USE_GIMBAL_LPF ?= YES
|
||||
USE_GIMBAL_FF ?= YES
|
||||
|
||||
# List of optional modules to include
|
||||
OPTMODULES =
|
||||
ifeq ($(USE_CAMERASTAB), YES)
|
||||
@ -465,6 +470,18 @@ ifeq ($(USE_I2C), YES)
|
||||
CDEFS += -DUSE_I2C
|
||||
endif
|
||||
|
||||
ifeq ($(USE_INPUT_LPF), YES)
|
||||
CDEFS += -DUSE_INPUT_LPF
|
||||
endif
|
||||
|
||||
ifeq ($(USE_GIMBAL_LPF), YES)
|
||||
CDEFS += -DUSE_GIMBAL_LPF
|
||||
endif
|
||||
|
||||
ifeq ($(USE_GIMBAL_FF), YES)
|
||||
CDEFS += -DUSE_GIMBAL_FF
|
||||
endif
|
||||
|
||||
# Declare all non-optional modules as built-in to force inclusion
|
||||
CDEFS += ${foreach MOD, ${MODULES}, -DMODULE_$(MOD)_BUILTIN }
|
||||
|
||||
|
@ -32,6 +32,8 @@
|
||||
|
||||
#include <uavobjectmanager.h>
|
||||
#include <gcsreceiver.h>
|
||||
#include <oplinksettings.h>
|
||||
#include <pios_rfm22b_rcvr.h>
|
||||
|
||||
// Public defines / macros
|
||||
#define PHPacketSize(p) ((uint8_t*)(p->data) + p->header.data_size - (uint8_t*)p)
|
||||
@ -40,19 +42,14 @@
|
||||
// Public types
|
||||
typedef enum {
|
||||
PACKET_TYPE_NONE = 0,
|
||||
PACKET_TYPE_CONNECT, // for requesting a connection
|
||||
PACKET_TYPE_DISCONNECT, // to tell the other modem they cannot connect to us
|
||||
PACKET_TYPE_READY, // tells the other modem we are ready to accept more data
|
||||
PACKET_TYPE_NOTREADY, // tells the other modem we're not ready to accept more data - we can also send user data in this packet type
|
||||
PACKET_TYPE_STATUS, // broadcasts status of this modem
|
||||
PACKET_TYPE_DATARATE, // for changing the RF data rate
|
||||
PACKET_TYPE_PING, // used to check link is still up
|
||||
PACKET_TYPE_ADJUST_TX_PWR, // used to ask the other modem to adjust it's tx power
|
||||
PACKET_TYPE_CON_REQUEST, // request a connection to another modem
|
||||
PACKET_TYPE_DATA, // data packet (packet contains user data)
|
||||
PACKET_TYPE_ACKED_DATA, // data packet that requies an ACK
|
||||
PACKET_TYPE_DUPLICATE_DATA, // a duplicate data packet
|
||||
PACKET_TYPE_PPM, // PPM relay values
|
||||
PACKET_TYPE_ACK,
|
||||
PACKET_TYPE_NACK
|
||||
PACKET_TYPE_ACK, // Acknowlege the receipt of a packet
|
||||
PACKET_TYPE_ACK_RTS, // Acknowlege the receipt of a packet and indicate that the receiving side has data to send (ready to send)
|
||||
PACKET_TYPE_NACK, // Acknowlege the receipt of an uncorrectable packet
|
||||
} PHPacketType;
|
||||
|
||||
typedef struct {
|
||||
@ -64,58 +61,45 @@ typedef struct {
|
||||
} PHPacketHeader;
|
||||
|
||||
#define PH_MAX_DATA (PIOS_PH_MAX_PACKET - sizeof(PHPacketHeader) - RS_ECC_NPARITY)
|
||||
#define PH_PACKET_SIZE(p) (p->data + p->header.data_size - (uint8_t*)p + RS_ECC_NPARITY)
|
||||
#define PH_PACKET_SIZE(p) ((p)->data + (p)->header.data_size - (uint8_t*)(p) + RS_ECC_NPARITY)
|
||||
typedef struct {
|
||||
PHPacketHeader header;
|
||||
uint8_t data[PH_MAX_DATA + RS_ECC_NPARITY];
|
||||
} PHPacket, *PHPacketHandle;
|
||||
|
||||
#define PH_ACK_NACK_DATA_SIZE(p) ((uint8_t*)((p)->ecc) - (uint8_t*)(((PHPacketHandle)(p))->data))
|
||||
typedef struct {
|
||||
PHPacketHeader header;
|
||||
uint8_t ecc[RS_ECC_NPARITY];
|
||||
} PHAckNackPacket, *PHAckNackPacketHandle;
|
||||
|
||||
#define PH_PPM_DATA_SIZE(p) ((uint8_t*)((p)->ecc) - (uint8_t*)(((PHPacketHandle)(p))->data))
|
||||
typedef struct {
|
||||
PHPacketHeader header;
|
||||
uint16_t channels[GCSRECEIVER_CHANNEL_NUMELEM];
|
||||
uint16_t channels[PIOS_RFM22B_RCVR_MAX_CHANNELS];
|
||||
uint8_t ecc[RS_ECC_NPARITY];
|
||||
} PHPpmPacket, *PHPpmPacketHandle;
|
||||
|
||||
#define PH_STATUS_DATA_SIZE(p) ((uint8_t*)((p)->ecc) - (uint8_t*)(((PHPacketHandle)(p))->data))
|
||||
typedef struct {
|
||||
PHPacketHeader header;
|
||||
uint16_t retries;
|
||||
uint16_t errors;
|
||||
uint16_t uavtalk_errors;
|
||||
uint16_t dropped;
|
||||
uint16_t resets;
|
||||
uint8_t link_quality;
|
||||
int8_t received_rssi;
|
||||
uint8_t ecc[RS_ECC_NPARITY];
|
||||
} PHStatusPacket, *PHStatusPacketHandle;
|
||||
|
||||
#define PH_CONNECTION_DATA_SIZE(p) ((uint8_t*)((p)->ecc) - (uint8_t*)(((PHPacketHandle)(p))->data))
|
||||
typedef struct {
|
||||
uint32_t default_destination_id;
|
||||
uint32_t source_id;
|
||||
uint16_t max_connections;
|
||||
uint8_t win_size;
|
||||
} PacketHandlerConfig;
|
||||
|
||||
typedef int32_t (*PHOutputStream)(PHPacketHandle packet);
|
||||
typedef void (*PHDataHandler)(uint8_t *data, uint8_t len, int8_t rssi, int8_t afc);
|
||||
typedef void (*PHStatusHandler)(PHStatusPacketHandle s, int8_t rssi, int8_t afc);
|
||||
typedef void (*PHPPMHandler)(uint16_t *channels);
|
||||
|
||||
typedef uint32_t PHInstHandle;
|
||||
|
||||
// Public functions
|
||||
PHInstHandle PHInitialize(PacketHandlerConfig *cfg);
|
||||
void PHRegisterOutputStream(PHInstHandle h, PHOutputStream f);
|
||||
void PHRegisterDataHandler(PHInstHandle h, PHDataHandler f);
|
||||
void PHRegisterStatusHandler(PHInstHandle h, PHStatusHandler f);
|
||||
void PHRegisterPPMHandler(PHInstHandle h, PHPPMHandler f);
|
||||
uint32_t PHConnect(PHInstHandle h, uint32_t dest_id);
|
||||
PHPacketHandle PHGetRXPacket(PHInstHandle h);
|
||||
void PHReleaseRXPacket(PHInstHandle h, PHPacketHandle p);
|
||||
PHPacketHandle PHGetTXPacket(PHInstHandle h);
|
||||
void PHReleaseTXPacket(PHInstHandle h, PHPacketHandle p);
|
||||
uint8_t PHTransmitPacket(PHInstHandle h, PHPacketHandle p);
|
||||
uint8_t PHTransmitData(PHInstHandle h, uint8_t *buf, uint16_t len);
|
||||
uint8_t PHReceivePacket(PHInstHandle h, PHPacketHandle p);
|
||||
PHPacketHeader header;
|
||||
uint8_t datarate;
|
||||
uint32_t frequency_hz;
|
||||
uint32_t min_frequency;
|
||||
uint32_t max_frequency;
|
||||
uint8_t max_tx_power;
|
||||
OPLinkSettingsOutputConnectionOptions port;
|
||||
OPLinkSettingsComSpeedOptions com_speed;
|
||||
uint8_t ecc[RS_ECC_NPARITY];
|
||||
} PHConnectionPacket, *PHConnectionPacketHandle;
|
||||
|
||||
#endif // __PACKET_HANDLER_H__
|
||||
|
||||
|
@ -1,385 +0,0 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @addtogroup OpenPilotSystem OpenPilot System
|
||||
* @{
|
||||
* @addtogroup OpenPilotLibraries OpenPilot System Libraries
|
||||
* @{
|
||||
*
|
||||
* @file packet_handler.c
|
||||
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2012.
|
||||
* @brief A packet handler for handeling radio packet transmission.
|
||||
* @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"
|
||||
#include "packet_handler.h"
|
||||
#include "aes.h"
|
||||
#include "ecc.h"
|
||||
|
||||
extern char *debug_msg;
|
||||
|
||||
// Private types and constants
|
||||
typedef struct {
|
||||
PacketHandlerConfig cfg;
|
||||
PHPacket *tx_packets;
|
||||
uint8_t tx_win_start;
|
||||
uint8_t tx_win_end;
|
||||
PHPacket *rx_packets;
|
||||
uint8_t rx_win_start;
|
||||
uint8_t rx_win_end;
|
||||
xSemaphoreHandle lock;
|
||||
PHOutputStream output_stream;
|
||||
PHDataHandler data_handler;
|
||||
PHStatusHandler status_handler;
|
||||
PHPPMHandler ppm_handler;
|
||||
} PHPacketData, *PHPacketDataHandle;
|
||||
|
||||
// Private functions
|
||||
static uint8_t PHLTransmitPacket(PHPacketDataHandle data, PHPacketHandle p);
|
||||
|
||||
/**
|
||||
* Initialize the Packet Handler library
|
||||
* \param[in] txWinSize The transmission window size (number of tx packet buffers).
|
||||
* \param[in] streme A callback function for transmitting the packet.
|
||||
* \param[in] id The source ID of transmitter.
|
||||
* \return PHInstHandle The Pachet Handler instance data.
|
||||
* \return 0 Failure
|
||||
*/
|
||||
PHInstHandle PHInitialize(PacketHandlerConfig *cfg)
|
||||
{
|
||||
// Allocate the primary structure
|
||||
PHPacketDataHandle data = pvPortMalloc(sizeof(PHPacketData));
|
||||
if (!data)
|
||||
return 0;
|
||||
data->cfg = *cfg;
|
||||
|
||||
// Allocate the packet windows
|
||||
data->tx_packets = pvPortMalloc(sizeof(PHPacket) * data->cfg.win_size);
|
||||
data->rx_packets = pvPortMalloc(sizeof(PHPacket) * data->cfg.win_size);
|
||||
|
||||
// Initialize the windows
|
||||
data->tx_win_start = data->tx_win_end = 0;
|
||||
data->rx_win_start = data->rx_win_end = 0;
|
||||
for (uint8_t i = 0; i < data->cfg.win_size; ++i)
|
||||
{
|
||||
data->tx_packets[i].header.type = PACKET_TYPE_NONE;
|
||||
data->rx_packets[i].header.type = PACKET_TYPE_NONE;
|
||||
}
|
||||
|
||||
// Create the lock
|
||||
data->lock = xSemaphoreCreateRecursiveMutex();
|
||||
|
||||
// Initialize the ECC library.
|
||||
initialize_ecc();
|
||||
|
||||
// Initialize the handlers
|
||||
data->output_stream = 0;
|
||||
data->data_handler = 0;
|
||||
data->status_handler = 0;
|
||||
data->ppm_handler = 0;
|
||||
|
||||
// Return the structure.
|
||||
return (PHInstHandle)data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Register an output stream handler
|
||||
* \param[in] h The packet handler instance data pointer.
|
||||
* \param[in] f The output stream handler function
|
||||
*/
|
||||
void PHRegisterOutputStream(PHInstHandle h, PHOutputStream f)
|
||||
{
|
||||
PHPacketDataHandle data = (PHPacketDataHandle)h;
|
||||
|
||||
data->output_stream = f;
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a data handler
|
||||
* \param[in] h The packet handler instance data pointer.
|
||||
* \param[in] f The data handler function
|
||||
*/
|
||||
void PHRegisterDataHandler(PHInstHandle h, PHDataHandler f)
|
||||
{
|
||||
PHPacketDataHandle data = (PHPacketDataHandle)h;
|
||||
|
||||
data->data_handler = f;
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a PPM packet handler
|
||||
* \param[in] h The packet handler instance data pointer.
|
||||
* \param[in] f The PPM handler function
|
||||
*/
|
||||
void PHRegisterStatusHandler(PHInstHandle h, PHStatusHandler f)
|
||||
{
|
||||
PHPacketDataHandle data = (PHPacketDataHandle)h;
|
||||
|
||||
data->status_handler = f;
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a PPM packet handler
|
||||
* \param[in] h The packet handler instance data pointer.
|
||||
* \param[in] f The PPM handler function
|
||||
*/
|
||||
void PHRegisterPPMHandler(PHInstHandle h, PHPPMHandler f)
|
||||
{
|
||||
PHPacketDataHandle data = (PHPacketDataHandle)h;
|
||||
|
||||
data->ppm_handler = f;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a packet out of the transmit buffer.
|
||||
* \param[in] h The packet handler instance data pointer.
|
||||
* \param[in] dest_id The destination ID of this connection
|
||||
* \return PHPacketHandle A pointer to the packet buffer.
|
||||
* \return 0 No packets buffers avaiable in the transmit window.
|
||||
*/
|
||||
uint32_t PHConnect(PHInstHandle h, uint32_t dest_id)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a packet out of the transmit buffer.
|
||||
* \param[in] h The packet handler instance data pointer.
|
||||
* \return PHPacketHandle A pointer to the packet buffer.
|
||||
* \return 0 No packets buffers avaiable in the transmit window.
|
||||
*/
|
||||
PHPacketHandle PHGetTXPacket(PHInstHandle h)
|
||||
{
|
||||
PHPacketDataHandle data = (PHPacketDataHandle)h;
|
||||
|
||||
// Lock
|
||||
xSemaphoreTakeRecursive(data->lock, portMAX_DELAY);
|
||||
|
||||
// Find a free packet.
|
||||
PHPacketHandle p = NULL;
|
||||
for (uint8_t i = 0; i < data->cfg.win_size; ++i)
|
||||
if (data->tx_packets[i].header.type == PACKET_TYPE_NONE)
|
||||
{
|
||||
p = data->tx_packets + i;
|
||||
break;
|
||||
}
|
||||
|
||||
// Release lock
|
||||
xSemaphoreGiveRecursive(data->lock);
|
||||
|
||||
// Return a pointer to the packet at the end of the TX window.
|
||||
return p;
|
||||
}
|
||||
|
||||
/**
|
||||
* Release a packet from the transmit packet buffer window.
|
||||
* \param[in] h The packet handler instance data pointer.
|
||||
* \param[in] p A pointer to the packet buffer.
|
||||
* \return Nothing
|
||||
*/
|
||||
void PHReleaseTXPacket(PHInstHandle h, PHPacketHandle p)
|
||||
{
|
||||
PHPacketDataHandle data = (PHPacketDataHandle)h;
|
||||
|
||||
// Lock
|
||||
xSemaphoreTakeRecursive(data->lock, portMAX_DELAY);
|
||||
|
||||
// Change the packet type so we know this packet is unused.
|
||||
p->header.type = PACKET_TYPE_NONE;
|
||||
|
||||
// If this packet is at the start of the window, increment the start index.
|
||||
while ((data->tx_win_start != data->tx_win_end) &&
|
||||
(data->tx_packets[data->tx_win_start].header.type == PACKET_TYPE_NONE))
|
||||
data->tx_win_start = (data->tx_win_start + 1) % data->cfg.win_size;
|
||||
|
||||
// Release lock
|
||||
xSemaphoreGiveRecursive(data->lock);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a packet out of the receive buffer.
|
||||
* \param[in] h The packet handler instance data pointer.
|
||||
* \return PHPacketHandle A pointer to the packet buffer.
|
||||
* \return 0 No packets buffers avaiable in the transmit window.
|
||||
*/
|
||||
PHPacketHandle PHGetRXPacket(PHInstHandle h)
|
||||
{
|
||||
PHPacketDataHandle data = (PHPacketDataHandle)h;
|
||||
|
||||
// Lock
|
||||
xSemaphoreTakeRecursive(data->lock, portMAX_DELAY);
|
||||
|
||||
// Find a free packet.
|
||||
PHPacketHandle p = NULL;
|
||||
for (uint8_t i = 0; i < data->cfg.win_size; ++i)
|
||||
if (data->rx_packets[i].header.type == PACKET_TYPE_NONE)
|
||||
{
|
||||
p = data->rx_packets + i;
|
||||
break;
|
||||
}
|
||||
|
||||
// Release lock
|
||||
xSemaphoreGiveRecursive(data->lock);
|
||||
|
||||
// Return a pointer to the packet at the end of the TX window.
|
||||
return p;
|
||||
}
|
||||
|
||||
/**
|
||||
* Release a packet from the receive packet buffer window.
|
||||
* \param[in] h The packet handler instance data pointer.
|
||||
* \param[in] p A pointer to the packet buffer.
|
||||
* \return Nothing
|
||||
*/
|
||||
void PHReleaseRXPacket(PHInstHandle h, PHPacketHandle p)
|
||||
{
|
||||
PHPacketDataHandle data = (PHPacketDataHandle)h;
|
||||
|
||||
// Lock
|
||||
xSemaphoreTakeRecursive(data->lock, portMAX_DELAY);
|
||||
|
||||
// Change the packet type so we know this packet is unused.
|
||||
p->header.type = PACKET_TYPE_NONE;
|
||||
|
||||
// If this packet is at the start of the window, increment the start index.
|
||||
while ((data->rx_win_start != data->rx_win_end) &&
|
||||
(data->rx_packets[data->rx_win_start].header.type == PACKET_TYPE_NONE))
|
||||
data->rx_win_start = (data->rx_win_start + 1) % data->cfg.win_size;
|
||||
|
||||
// Release lock
|
||||
xSemaphoreGiveRecursive(data->lock);
|
||||
}
|
||||
|
||||
/**
|
||||
* Transmit a packet from the transmit packet buffer window.
|
||||
* \param[in] h The packet handler instance data pointer.
|
||||
* \param[in] p A pointer to the packet buffer.
|
||||
* \return 1 Success
|
||||
* \return 0 Failure
|
||||
*/
|
||||
uint8_t PHTransmitPacket(PHInstHandle h, PHPacketHandle p)
|
||||
{
|
||||
PHPacketDataHandle data = (PHPacketDataHandle)h;
|
||||
|
||||
// Try to transmit the packet.
|
||||
if (!PHLTransmitPacket(data, p))
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Transmit a packet of data.
|
||||
* \param[in] h The packet handler instance data pointer.
|
||||
* \param[in] p A pointer to the data buffer.
|
||||
* \param[in] len The length of the data buffer.
|
||||
* \return 1 Success
|
||||
* \return 0 Failure
|
||||
*/
|
||||
uint8_t PHTransmitData(PHInstHandle h, uint8_t *buf, uint16_t len)
|
||||
{
|
||||
PHPacketDataHandle data = (PHPacketDataHandle)h;
|
||||
|
||||
// Get a packet from the packet handler.
|
||||
PHPacketHandle p = PHGetTXPacket(pios_packet_handler);
|
||||
if (!p)
|
||||
return 0;
|
||||
|
||||
// Initialize the packet.
|
||||
p->header.destination_id = data->cfg.default_destination_id;
|
||||
p->header.source_id = data->cfg.source_id;
|
||||
p->header.type = PACKET_TYPE_DATA;
|
||||
p->header.data_size = len;
|
||||
|
||||
// Copy the data into the packet.
|
||||
memcpy(p->data, buf, len);
|
||||
|
||||
// Send the packet.
|
||||
return PHLTransmitPacket(data, p);
|
||||
}
|
||||
|
||||
/**
|
||||
* Process a packet that has been received.
|
||||
* \param[in] h The packet handler instance data pointer.
|
||||
* \param[in] p A pointer to the packet buffer.
|
||||
* \param[in] received_len The length of data received.
|
||||
* \return 0 Failure
|
||||
* \return 1 Success
|
||||
*/
|
||||
uint8_t PHReceivePacket(PHInstHandle h, PHPacketHandle p)
|
||||
{
|
||||
PHPacketDataHandle data = (PHPacketDataHandle)h;
|
||||
uint16_t len = PHPacketSizeECC(p);
|
||||
|
||||
// Extract the RSSI and AFC.
|
||||
int8_t rssi = *(((int8_t*)p) + len);
|
||||
int8_t afc = *(((int8_t*)p) + len + 1);
|
||||
|
||||
switch (p->header.type) {
|
||||
|
||||
case PACKET_TYPE_STATUS:
|
||||
|
||||
// Pass on the channels to the status handler.
|
||||
if(data->status_handler)
|
||||
data->status_handler((PHStatusPacketHandle)p, rssi, afc);
|
||||
break;
|
||||
|
||||
case PACKET_TYPE_PPM:
|
||||
|
||||
// Pass on the channels to the PPM handler.
|
||||
if(data->ppm_handler)
|
||||
data->ppm_handler(((PHPpmPacketHandle)p)->channels);
|
||||
break;
|
||||
|
||||
case PACKET_TYPE_DATA:
|
||||
|
||||
// Pass on the data to the data handler.
|
||||
if(data->data_handler)
|
||||
data->data_handler(p->data, p->header.data_size, rssi, afc);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
// Release the packet.
|
||||
PHReleaseRXPacket(h, p);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Transmit a packet from the transmit packet buffer window.
|
||||
* \param[in] data The packet handler instance data pointer.
|
||||
* \param[in] p A pointer to the packet buffer.
|
||||
* \return 1 Success
|
||||
* \return 0 Failure
|
||||
*/
|
||||
static uint8_t PHLTransmitPacket(PHPacketDataHandle data, PHPacketHandle p)
|
||||
{
|
||||
|
||||
if(!data->output_stream)
|
||||
return 0;
|
||||
|
||||
// Transmit the packet using the output stream.
|
||||
if(data->output_stream(p) == -1)
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
@ -57,6 +57,8 @@
|
||||
#define FAILSAFE_TIMEOUT_MS 100
|
||||
#define MAX_MIX_ACTUATORS ACTUATORCOMMAND_CHANNEL_NUMELEM
|
||||
|
||||
#define CAMERA_BOOT_DELAY_MS 7000
|
||||
|
||||
// Private types
|
||||
|
||||
|
||||
@ -205,7 +207,7 @@ static void actuatorTask(void* parameters)
|
||||
// Check how long since last update
|
||||
thisSysTime = xTaskGetTickCount();
|
||||
if(thisSysTime > lastSysTime) // reuse dt in case of wraparound
|
||||
dT = (thisSysTime - lastSysTime) / portTICK_RATE_MS / 1000.0f;
|
||||
dT = (thisSysTime - lastSysTime) * (portTICK_RATE_MS * 0.001f);
|
||||
lastSysTime = thisSysTime;
|
||||
|
||||
FlightStatusGet(&flightStatus);
|
||||
@ -277,10 +279,15 @@ static void actuatorTask(void* parameters)
|
||||
|
||||
for(int ct=0; ct < MAX_MIX_ACTUATORS; ct++)
|
||||
{
|
||||
// During boot all camera actuators should be completely disabled (PWM pulse = 0).
|
||||
// command.Channel[i] is reused below as a channel PWM activity flag:
|
||||
// 0 - PWM disabled, >0 - PWM set to real mixer value using scaleChannel() later.
|
||||
// Setting it to 1 by default means "Rescale this channel and enable PWM on its output".
|
||||
command.Channel[ct] = 1;
|
||||
|
||||
if(mixers[ct].type == MIXERSETTINGS_MIXER1TYPE_DISABLED) {
|
||||
// Set to minimum if disabled. This is not the same as saying PWM pulse = 0 us
|
||||
status[ct] = -1;
|
||||
command.Channel[ct] = 0;
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -289,8 +296,6 @@ static void actuatorTask(void* parameters)
|
||||
else
|
||||
status[ct] = -1;
|
||||
|
||||
|
||||
|
||||
// Motors have additional protection for when to be on
|
||||
if(mixers[ct].type == MIXERSETTINGS_MIXER1TYPE_MOTOR) {
|
||||
|
||||
@ -322,6 +327,7 @@ static void actuatorTask(void* parameters)
|
||||
else
|
||||
status[ct] = -1;
|
||||
}
|
||||
|
||||
if( (mixers[ct].type >= MIXERSETTINGS_MIXER1TYPE_CAMERAROLL) &&
|
||||
(mixers[ct].type <= MIXERSETTINGS_MIXER1TYPE_CAMERAYAW))
|
||||
{
|
||||
@ -343,19 +349,26 @@ static void actuatorTask(void* parameters)
|
||||
}
|
||||
else
|
||||
status[ct] = -1;
|
||||
|
||||
// Disable camera actuators for CAMERA_BOOT_DELAY_MS after boot
|
||||
if (thisSysTime < (CAMERA_BOOT_DELAY_MS / portTICK_RATE_MS))
|
||||
command.Channel[ct] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
for(int i = 0; i < MAX_MIX_ACTUATORS; i++)
|
||||
command.Channel[i] = scaleChannel(status[i],
|
||||
|
||||
// Set real actuator output values scaling them from mixers. All channels
|
||||
// will be set except explicitly disabled (which will have PWM pulse = 0).
|
||||
for (int i = 0; i < MAX_MIX_ACTUATORS; i++)
|
||||
if (command.Channel[i])
|
||||
command.Channel[i] = scaleChannel(status[i],
|
||||
actuatorSettings.ChannelMax[i],
|
||||
actuatorSettings.ChannelMin[i],
|
||||
actuatorSettings.ChannelNeutral[i]);
|
||||
|
||||
|
||||
// Store update time
|
||||
command.UpdateTime = 1000.0f*dT;
|
||||
if(1000.0f*dT > command.MaxUpdateTime)
|
||||
command.MaxUpdateTime = 1000.0f*dT;
|
||||
command.UpdateTime = dT * 1000.0f;
|
||||
if (command.UpdateTime > command.MaxUpdateTime)
|
||||
command.MaxUpdateTime = command.UpdateTime;
|
||||
|
||||
// Update output object
|
||||
ActuatorCommandSet(&command);
|
||||
|
@ -86,6 +86,10 @@ static void settingsUpdatedCb(UAVObjEvent * objEv);
|
||||
|
||||
static float accelKi = 0;
|
||||
static float accelKp = 0;
|
||||
static float accel_alpha = 0;
|
||||
static bool accel_filter_enabled = false;
|
||||
static float accels_filtered[3];
|
||||
static float grot_filtered[3];
|
||||
static float yawBiasRate = 0;
|
||||
static float gyroGain = 0.42;
|
||||
static int16_t accelbias[3];
|
||||
@ -215,18 +219,22 @@ static void AttitudeTask(void *parameters)
|
||||
accelKp = 1;
|
||||
accelKi = 0.9;
|
||||
yawBiasRate = 0.23;
|
||||
accel_filter_enabled = false;
|
||||
init = 0;
|
||||
}
|
||||
else if (zero_during_arming && (flightStatus.Armed == FLIGHTSTATUS_ARMED_ARMING)) {
|
||||
accelKp = 1;
|
||||
accelKi = 0.9;
|
||||
yawBiasRate = 0.23;
|
||||
accel_filter_enabled = false;
|
||||
init = 0;
|
||||
} else if (init == 0) {
|
||||
// Reload settings (all the rates)
|
||||
AttitudeSettingsAccelKiGet(&accelKi);
|
||||
AttitudeSettingsAccelKpGet(&accelKp);
|
||||
AttitudeSettingsYawBiasRateGet(&yawBiasRate);
|
||||
if (accel_alpha > 0.0f)
|
||||
accel_filter_enabled = true;
|
||||
init = 1;
|
||||
}
|
||||
|
||||
@ -407,7 +415,6 @@ static int32_t updateSensorsCC3D(AccelsData * accelsData, GyrosData * gyrosData)
|
||||
accelsData->x = accels[0] - accelbias[0] * ACCEL_SCALE; // Applying arbitrary scale here to match CC v1
|
||||
accelsData->y = accels[1] - accelbias[1] * ACCEL_SCALE;
|
||||
accelsData->z = accels[2] - accelbias[2] * ACCEL_SCALE;
|
||||
AccelsSet(&accelsData);
|
||||
|
||||
gyrosData->x = gyros[0];
|
||||
gyrosData->y = gyros[1];
|
||||
@ -430,6 +437,19 @@ static int32_t updateSensorsCC3D(AccelsData * accelsData, GyrosData * gyrosData)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline void apply_accel_filter(const float *raw, float *filtered)
|
||||
{
|
||||
if (accel_filter_enabled) {
|
||||
filtered[0] = filtered[0] * accel_alpha + raw[0] * (1 - accel_alpha);
|
||||
filtered[1] = filtered[1] * accel_alpha + raw[1] * (1 - accel_alpha);
|
||||
filtered[2] = filtered[2] * accel_alpha + raw[2] * (1 - accel_alpha);
|
||||
} else {
|
||||
filtered[0] = raw[0];
|
||||
filtered[1] = raw[1];
|
||||
filtered[2] = raw[2];
|
||||
}
|
||||
}
|
||||
|
||||
static void updateAttitude(AccelsData * accelsData, GyrosData * gyrosData)
|
||||
{
|
||||
float dT;
|
||||
@ -445,21 +465,38 @@ static void updateAttitude(AccelsData * accelsData, GyrosData * gyrosData)
|
||||
|
||||
float grot[3];
|
||||
float accel_err[3];
|
||||
|
||||
// Apply smoothing to accel values, to reduce vibration noise before main calculations.
|
||||
apply_accel_filter(accels, accels_filtered);
|
||||
|
||||
// Rotate gravity to body frame and cross with accels
|
||||
// Rotate gravity unit vector to body frame, filter and cross with accels
|
||||
grot[0] = -(2 * (q[1] * q[3] - q[0] * q[2]));
|
||||
grot[1] = -(2 * (q[2] * q[3] + q[0] * q[1]));
|
||||
grot[2] = -(q[0] * q[0] - q[1]*q[1] - q[2]*q[2] + q[3]*q[3]);
|
||||
CrossProduct((const float *) accels, (const float *) grot, accel_err);
|
||||
|
||||
apply_accel_filter(grot, grot_filtered);
|
||||
|
||||
CrossProduct((const float *)accels_filtered, (const float *)grot_filtered, accel_err);
|
||||
|
||||
// Account for accel magnitude
|
||||
float accel_mag = sqrtf(accels[0]*accels[0] + accels[1]*accels[1] + accels[2]*accels[2]);
|
||||
if(accel_mag < 1.0e-3f)
|
||||
float accel_mag = sqrtf(accels_filtered[0]*accels_filtered[0] + accels_filtered[1]*accels_filtered[1] + accels_filtered[2]*accels_filtered[2]);
|
||||
if (accel_mag < 1.0e-3f)
|
||||
return;
|
||||
|
||||
accel_err[0] /= accel_mag;
|
||||
accel_err[1] /= accel_mag;
|
||||
accel_err[2] /= accel_mag;
|
||||
// Account for filtered gravity vector magnitude
|
||||
float grot_mag;
|
||||
|
||||
if (accel_filter_enabled)
|
||||
grot_mag = sqrtf(grot_filtered[0]*grot_filtered[0] + grot_filtered[1]*grot_filtered[1] + grot_filtered[2]*grot_filtered[2]);
|
||||
else
|
||||
grot_mag = 1.0f;
|
||||
|
||||
if (grot_mag < 1.0e-3f)
|
||||
return;
|
||||
|
||||
accel_err[0] /= (accel_mag*grot_mag);
|
||||
accel_err[1] /= (accel_mag*grot_mag);
|
||||
accel_err[2] /= (accel_mag*grot_mag);
|
||||
|
||||
// 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;
|
||||
@ -531,6 +568,16 @@ static void settingsUpdatedCb(UAVObjEvent * objEv) {
|
||||
accelKi = attitudeSettings.AccelKi;
|
||||
yawBiasRate = attitudeSettings.YawBiasRate;
|
||||
gyroGain = attitudeSettings.GyroGain;
|
||||
|
||||
// Calculate accel filter alpha, in the same way as for gyro data in stabilization module.
|
||||
const float fakeDt = 0.0025;
|
||||
if (attitudeSettings.AccelTau < 0.0001) {
|
||||
accel_alpha = 0; // not trusting this to resolve to 0
|
||||
accel_filter_enabled = false;
|
||||
} else {
|
||||
accel_alpha = expf(-fakeDt / attitudeSettings.AccelTau);
|
||||
accel_filter_enabled = true;
|
||||
}
|
||||
|
||||
zero_during_arming = attitudeSettings.ZeroDuringArming == ATTITUDESETTINGS_ZERODURINGARMING_TRUE;
|
||||
bias_correct_gyro = attitudeSettings.BiasCorrectGyro == ATTITUDESETTINGS_BIASCORRECTGYRO_TRUE;
|
||||
|
@ -64,13 +64,28 @@
|
||||
static struct CameraStab_data {
|
||||
portTickType lastSysTime;
|
||||
float inputs[CAMERASTABSETTINGS_INPUT_NUMELEM];
|
||||
float inputs_filtered[CAMERASTABSETTINGS_INPUT_NUMELEM];
|
||||
|
||||
#ifdef USE_GIMBAL_LPF
|
||||
float attitudeFiltered[CAMERASTABSETTINGS_INPUT_NUMELEM];
|
||||
#endif
|
||||
|
||||
#ifdef USE_GIMBAL_FF
|
||||
float ffLastAttitude[CAMERASTABSETTINGS_INPUT_NUMELEM];
|
||||
float ffLastAttitudeFiltered[CAMERASTABSETTINGS_INPUT_NUMELEM];
|
||||
float ffFilterAccumulator[CAMERASTABSETTINGS_INPUT_NUMELEM];
|
||||
#endif
|
||||
|
||||
} *csd;
|
||||
|
||||
// Private functions
|
||||
static void attitudeUpdated(UAVObjEvent* ev);
|
||||
static float bound(float val, float limit);
|
||||
|
||||
#ifdef USE_GIMBAL_FF
|
||||
static void applyFeedForward(uint8_t index, float dT, float *attitude, CameraStabSettingsData *cameraStab);
|
||||
#endif
|
||||
|
||||
|
||||
/**
|
||||
* Initialise the module, called on startup
|
||||
* \returns 0 on success or -1 if initialisation failed
|
||||
@ -100,7 +115,7 @@ int32_t CameraStabInitialize(void)
|
||||
if (!csd)
|
||||
return -1;
|
||||
|
||||
// make sure that all inputs[] and inputs_filtered[] are zeroed
|
||||
// initialize camera state variables
|
||||
memset(csd, 0, sizeof(struct CameraStab_data));
|
||||
csd->lastSysTime = xTaskGetTickCount();
|
||||
|
||||
@ -139,15 +154,17 @@ static void attitudeUpdated(UAVObjEvent* ev)
|
||||
CameraStabSettingsData cameraStab;
|
||||
CameraStabSettingsGet(&cameraStab);
|
||||
|
||||
// Check how long since last update, time delta between calls in ms
|
||||
// check how long since last update, time delta between calls in ms
|
||||
portTickType thisSysTime = xTaskGetTickCount();
|
||||
float dT = (thisSysTime > csd->lastSysTime) ?
|
||||
(thisSysTime - csd->lastSysTime) / portTICK_RATE_MS :
|
||||
(float)SAMPLE_PERIOD_MS / 1000.0f;
|
||||
float dT_millis = (thisSysTime > csd->lastSysTime) ?
|
||||
(float)((thisSysTime - csd->lastSysTime) * portTICK_RATE_MS) :
|
||||
(float)SAMPLE_PERIOD_MS;
|
||||
csd->lastSysTime = thisSysTime;
|
||||
|
||||
// Read any input channels and apply LPF
|
||||
// process axes
|
||||
for (uint8_t i = 0; i < CAMERASTABSETTINGS_INPUT_NUMELEM; i++) {
|
||||
|
||||
// read and process control input
|
||||
if (cameraStab.Input[i] != CAMERASTABSETTINGS_INPUT_NONE) {
|
||||
if (AccessoryDesiredInstGet(cameraStab.Input[i] - CAMERASTABSETTINGS_INPUT_ACCESSORY0, &accessory) == 0) {
|
||||
float input_rate;
|
||||
@ -158,38 +175,59 @@ static void attitudeUpdated(UAVObjEvent* ev)
|
||||
case CAMERASTABSETTINGS_STABILIZATIONMODE_AXISLOCK:
|
||||
input_rate = accessory.AccessoryVal * cameraStab.InputRate[i];
|
||||
if (fabs(input_rate) > cameraStab.MaxAxisLockRate)
|
||||
csd->inputs[i] = bound(csd->inputs[i] + input_rate * dT / 1000.0f, cameraStab.InputRange[i]);
|
||||
csd->inputs[i] = bound(csd->inputs[i] + input_rate * 0.001f * dT_millis, cameraStab.InputRange[i]);
|
||||
break;
|
||||
default:
|
||||
PIOS_Assert(0);
|
||||
}
|
||||
|
||||
// bypass LPF calculation if ResponseTime is zero
|
||||
float rt = (float)cameraStab.ResponseTime[i];
|
||||
if (rt)
|
||||
csd->inputs_filtered[i] = (rt / (rt + dT)) * csd->inputs_filtered[i]
|
||||
+ (dT / (rt + dT)) * csd->inputs[i];
|
||||
else
|
||||
csd->inputs_filtered[i] = csd->inputs[i];
|
||||
}
|
||||
}
|
||||
|
||||
// calculate servo output
|
||||
float attitude;
|
||||
|
||||
switch (i) {
|
||||
case CAMERASTABSETTINGS_INPUT_ROLL:
|
||||
AttitudeActualRollGet(&attitude);
|
||||
break;
|
||||
case CAMERASTABSETTINGS_INPUT_PITCH:
|
||||
AttitudeActualPitchGet(&attitude);
|
||||
break;
|
||||
case CAMERASTABSETTINGS_INPUT_YAW:
|
||||
AttitudeActualYawGet(&attitude);
|
||||
break;
|
||||
default:
|
||||
PIOS_Assert(0);
|
||||
}
|
||||
|
||||
#ifdef USE_GIMBAL_LPF
|
||||
if (cameraStab.ResponseTime) {
|
||||
float rt = (float)cameraStab.ResponseTime[i];
|
||||
attitude = csd->attitudeFiltered[i] = ((rt * csd->attitudeFiltered[i]) + (dT_millis * attitude)) / (rt + dT_millis);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef USE_GIMBAL_FF
|
||||
if (cameraStab.FeedForward[i])
|
||||
applyFeedForward(i, dT_millis, &attitude, &cameraStab);
|
||||
#endif
|
||||
|
||||
// set output channels
|
||||
float output = bound((attitude + csd->inputs[i]) / cameraStab.OutputRange[i], 1.0f);
|
||||
switch (i) {
|
||||
case CAMERASTABSETTINGS_INPUT_ROLL:
|
||||
CameraDesiredRollSet(&output);
|
||||
break;
|
||||
case CAMERASTABSETTINGS_INPUT_PITCH:
|
||||
CameraDesiredPitchSet(&output);
|
||||
break;
|
||||
case CAMERASTABSETTINGS_INPUT_YAW:
|
||||
CameraDesiredYawSet(&output);
|
||||
break;
|
||||
default:
|
||||
PIOS_Assert(0);
|
||||
}
|
||||
}
|
||||
|
||||
// Set output channels
|
||||
float attitude;
|
||||
float output;
|
||||
|
||||
AttitudeActualRollGet(&attitude);
|
||||
output = bound((attitude + csd->inputs_filtered[CAMERASTABSETTINGS_INPUT_ROLL]) / cameraStab.OutputRange[CAMERASTABSETTINGS_OUTPUTRANGE_ROLL], 1.0f);
|
||||
CameraDesiredRollSet(&output);
|
||||
|
||||
AttitudeActualPitchGet(&attitude);
|
||||
output = bound((attitude + csd->inputs_filtered[CAMERASTABSETTINGS_INPUT_PITCH]) / cameraStab.OutputRange[CAMERASTABSETTINGS_OUTPUTRANGE_PITCH], 1.0f);
|
||||
CameraDesiredPitchSet(&output);
|
||||
|
||||
AttitudeActualYawGet(&attitude);
|
||||
output = bound((attitude + csd->inputs_filtered[CAMERASTABSETTINGS_INPUT_YAW]) / cameraStab.OutputRange[CAMERASTABSETTINGS_OUTPUTRANGE_YAW], 1.0f);
|
||||
CameraDesiredYawSet(&output);
|
||||
}
|
||||
|
||||
float bound(float val, float limit)
|
||||
@ -198,6 +236,62 @@ float bound(float val, float limit)
|
||||
(val < -limit) ? -limit :
|
||||
val;
|
||||
}
|
||||
|
||||
#ifdef USE_GIMBAL_FF
|
||||
void applyFeedForward(uint8_t index, float dT_millis, float *attitude, CameraStabSettingsData *cameraStab)
|
||||
{
|
||||
// compensate high feed forward values depending on gimbal type
|
||||
float gimbalTypeCorrection = 1.0f;
|
||||
|
||||
switch (cameraStab->GimbalType) {
|
||||
case CAMERASTABSETTINGS_GIMBALTYPE_GENERIC:
|
||||
// no correction
|
||||
break;
|
||||
case CAMERASTABSETTINGS_GIMBALTYPE_YAWROLLPITCH:
|
||||
if (index == CAMERASTABSETTINGS_INPUT_ROLL) {
|
||||
float pitch;
|
||||
AttitudeActualPitchGet(&pitch);
|
||||
gimbalTypeCorrection = (cameraStab->OutputRange[CAMERASTABSETTINGS_OUTPUTRANGE_PITCH] - fabs(pitch))
|
||||
/ cameraStab->OutputRange[CAMERASTABSETTINGS_OUTPUTRANGE_PITCH];
|
||||
}
|
||||
break;
|
||||
case CAMERASTABSETTINGS_GIMBALTYPE_YAWPITCHROLL:
|
||||
if (index == CAMERASTABSETTINGS_INPUT_PITCH) {
|
||||
float roll;
|
||||
AttitudeActualRollGet(&roll);
|
||||
gimbalTypeCorrection = (cameraStab->OutputRange[CAMERASTABSETTINGS_OUTPUTRANGE_ROLL] - fabs(roll))
|
||||
/ cameraStab->OutputRange[CAMERASTABSETTINGS_OUTPUTRANGE_ROLL];
|
||||
}
|
||||
break;
|
||||
default:
|
||||
PIOS_Assert(0);
|
||||
}
|
||||
|
||||
// apply feed forward
|
||||
float accumulator = csd->ffFilterAccumulator[index];
|
||||
accumulator += (*attitude - csd->ffLastAttitude[index]) * (float)cameraStab->FeedForward[index] * gimbalTypeCorrection;
|
||||
csd->ffLastAttitude[index] = *attitude;
|
||||
*attitude += accumulator;
|
||||
|
||||
float filter = (float)((accumulator > 0.0f) ? cameraStab->AccelTime[index] : cameraStab->DecelTime[index]) / dT_millis;
|
||||
if (filter < 1.0f)
|
||||
filter = 1.0f;
|
||||
accumulator -= accumulator / filter;
|
||||
csd->ffFilterAccumulator[index] = accumulator;
|
||||
*attitude += accumulator;
|
||||
|
||||
// apply acceleration limit
|
||||
float delta = *attitude - csd->ffLastAttitudeFiltered[index];
|
||||
float maxDelta = (float)cameraStab->MaxAccel * 0.001f * dT_millis;
|
||||
|
||||
if (fabs(delta) > maxDelta) {
|
||||
// we are accelerating too hard
|
||||
*attitude = csd->ffLastAttitudeFiltered[index] + ((delta > 0.0f) ? maxDelta : -maxDelta);
|
||||
}
|
||||
csd->ffLastAttitudeFiltered[index] = *attitude;
|
||||
}
|
||||
#endif // USE_GIMBAL_FF
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
@ -83,6 +83,11 @@ static xTaskHandle taskHandle;
|
||||
static ArmState_t armState;
|
||||
static portTickType lastSysTime;
|
||||
|
||||
#ifdef USE_INPUT_LPF
|
||||
static portTickType lastSysTimeLPF;
|
||||
static float inputFiltered[MANUALCONTROLSETTINGS_RESPONSETIME_NUMELEM];
|
||||
#endif
|
||||
|
||||
// Private functions
|
||||
static void updateActuatorDesired(ManualControlCommandData * cmd);
|
||||
static void updateStabilizationDesired(ManualControlCommandData * cmd, ManualControlSettingsData * settings);
|
||||
@ -99,6 +104,10 @@ static bool okToArm(void);
|
||||
static bool validInputRange(int16_t min, int16_t max, uint16_t value);
|
||||
static void applyDeadband(float *value, float deadband);
|
||||
|
||||
#ifdef USE_INPUT_LPF
|
||||
static void applyLPF(float *value, ManualControlSettingsResponseTimeElem channel, ManualControlSettingsData *settings, float dT);
|
||||
#endif
|
||||
|
||||
#define RCVR_ACTIVITY_MONITOR_CHANNELS_PER_GROUP 12
|
||||
#define RCVR_ACTIVITY_MONITOR_MIN_RANGE 10
|
||||
struct rcvr_activity_fsm {
|
||||
@ -337,7 +346,18 @@ static void manualControlTask(void *parameters)
|
||||
applyDeadband(&cmd.Pitch, settings.Deadband);
|
||||
applyDeadband(&cmd.Yaw, settings.Deadband);
|
||||
}
|
||||
#ifdef USE_INPUT_LPF
|
||||
// Apply Low Pass Filter to input channels, time delta between calls in ms
|
||||
portTickType thisSysTime = xTaskGetTickCount();
|
||||
float dT = (thisSysTime > lastSysTimeLPF) ?
|
||||
(float)((thisSysTime - lastSysTimeLPF) * portTICK_RATE_MS) :
|
||||
(float)UPDATE_PERIOD_MS;
|
||||
lastSysTimeLPF = thisSysTime;
|
||||
|
||||
applyLPF(&cmd.Roll, MANUALCONTROLSETTINGS_RESPONSETIME_ROLL, &settings, dT);
|
||||
applyLPF(&cmd.Pitch, MANUALCONTROLSETTINGS_RESPONSETIME_PITCH, &settings, dT);
|
||||
applyLPF(&cmd.Yaw, MANUALCONTROLSETTINGS_RESPONSETIME_YAW, &settings, dT);
|
||||
#endif // USE_INPUT_LPF
|
||||
if(cmd.Channel[MANUALCONTROLSETTINGS_CHANNELGROUPS_COLLECTIVE] != (uint16_t) PIOS_RCVR_INVALID &&
|
||||
cmd.Channel[MANUALCONTROLSETTINGS_CHANNELGROUPS_COLLECTIVE] != (uint16_t) PIOS_RCVR_NODRIVER &&
|
||||
cmd.Channel[MANUALCONTROLSETTINGS_CHANNELGROUPS_COLLECTIVE] != (uint16_t) PIOS_RCVR_TIMEOUT)
|
||||
@ -348,6 +368,9 @@ static void manualControlTask(void *parameters)
|
||||
if (settings.ChannelGroups[MANUALCONTROLSETTINGS_CHANNELGROUPS_ACCESSORY0] !=
|
||||
MANUALCONTROLSETTINGS_CHANNELGROUPS_NONE) {
|
||||
accessory.AccessoryVal = scaledChannel[MANUALCONTROLSETTINGS_CHANNELGROUPS_ACCESSORY0];
|
||||
#ifdef USE_INPUT_LPF
|
||||
applyLPF(&accessory.AccessoryVal, MANUALCONTROLSETTINGS_RESPONSETIME_ACCESSORY0, &settings, dT);
|
||||
#endif
|
||||
if(AccessoryDesiredInstSet(0, &accessory) != 0)
|
||||
AlarmsSet(SYSTEMALARMS_ALARM_MANUALCONTROL, SYSTEMALARMS_ALARM_WARNING);
|
||||
}
|
||||
@ -355,6 +378,9 @@ static void manualControlTask(void *parameters)
|
||||
if (settings.ChannelGroups[MANUALCONTROLSETTINGS_CHANNELGROUPS_ACCESSORY1] !=
|
||||
MANUALCONTROLSETTINGS_CHANNELGROUPS_NONE) {
|
||||
accessory.AccessoryVal = scaledChannel[MANUALCONTROLSETTINGS_CHANNELGROUPS_ACCESSORY1];
|
||||
#ifdef USE_INPUT_LPF
|
||||
applyLPF(&accessory.AccessoryVal, MANUALCONTROLSETTINGS_RESPONSETIME_ACCESSORY1, &settings, dT);
|
||||
#endif
|
||||
if(AccessoryDesiredInstSet(1, &accessory) != 0)
|
||||
AlarmsSet(SYSTEMALARMS_ALARM_MANUALCONTROL, SYSTEMALARMS_ALARM_WARNING);
|
||||
}
|
||||
@ -362,6 +388,9 @@ static void manualControlTask(void *parameters)
|
||||
if (settings.ChannelGroups[MANUALCONTROLSETTINGS_CHANNELGROUPS_ACCESSORY2] !=
|
||||
MANUALCONTROLSETTINGS_CHANNELGROUPS_NONE) {
|
||||
accessory.AccessoryVal = scaledChannel[MANUALCONTROLSETTINGS_CHANNELGROUPS_ACCESSORY2];
|
||||
#ifdef USE_INPUT_LPF
|
||||
applyLPF(&accessory.AccessoryVal, MANUALCONTROLSETTINGS_RESPONSETIME_ACCESSORY2, &settings, dT);
|
||||
#endif
|
||||
if(AccessoryDesiredInstSet(2, &accessory) != 0)
|
||||
AlarmsSet(SYSTEMALARMS_ALARM_MANUALCONTROL, SYSTEMALARMS_ALARM_WARNING);
|
||||
}
|
||||
@ -498,6 +527,9 @@ static bool updateRcvrActivityCompare(uint32_t rcvr_id, struct rcvr_activity_fsm
|
||||
case MANUALCONTROLSETTINGS_CHANNELGROUPS_GCS:
|
||||
group = RECEIVERACTIVITY_ACTIVEGROUP_GCS;
|
||||
break;
|
||||
case MANUALCONTROLSETTINGS_CHANNELGROUPS_OPLINK:
|
||||
group = RECEIVERACTIVITY_ACTIVEGROUP_OPLINK;
|
||||
break;
|
||||
default:
|
||||
PIOS_Assert(0);
|
||||
break;
|
||||
@ -1030,6 +1062,20 @@ static void applyDeadband(float *value, float deadband)
|
||||
*value += deadband;
|
||||
}
|
||||
|
||||
#ifdef USE_INPUT_LPF
|
||||
/**
|
||||
* @brief Apply Low Pass Filter to Throttle/Roll/Pitch/Yaw or Accessory channel
|
||||
*/
|
||||
static void applyLPF(float *value, ManualControlSettingsResponseTimeElem channel, ManualControlSettingsData *settings, float dT)
|
||||
{
|
||||
if (settings->ResponseTime[channel]) {
|
||||
float rt = (float)settings->ResponseTime[channel];
|
||||
inputFiltered[channel] = ((rt * inputFiltered[channel]) + (dT * (*value))) / (rt + dT);
|
||||
*value = inputFiltered[channel];
|
||||
}
|
||||
}
|
||||
#endif // USE_INPUT_LPF
|
||||
|
||||
/**
|
||||
* @}
|
||||
* @}
|
||||
|
@ -39,8 +39,10 @@
|
||||
*/
|
||||
|
||||
#include <openpilot.h>
|
||||
#include <pipxstatus.h>
|
||||
#include <oplinkstatus.h>
|
||||
#include <pios_rfm22b.h>
|
||||
#include <pios_board_info.h>
|
||||
#include <oplinksettings.h>
|
||||
#include "systemmod.h"
|
||||
|
||||
// Private constants
|
||||
@ -94,20 +96,20 @@ int32_t PipXtremeModInitialize(void)
|
||||
// Must registers objects here for system thread because ObjectManager started in OpenPilotInit
|
||||
|
||||
// Initialize out status object.
|
||||
PipXStatusInitialize();
|
||||
PipXStatusData pipxStatus;
|
||||
PipXStatusGet(&pipxStatus);
|
||||
OPLinkStatusInitialize();
|
||||
OPLinkStatusData oplinkStatus;
|
||||
OPLinkStatusGet(&oplinkStatus);
|
||||
|
||||
// Get our hardware information.
|
||||
const struct pios_board_info * bdinfo = &pios_board_info_blob;
|
||||
|
||||
pipxStatus.BoardType= bdinfo->board_type;
|
||||
PIOS_BL_HELPER_FLASH_Read_Description(pipxStatus.Description, PIPXSTATUS_DESCRIPTION_NUMELEM);
|
||||
PIOS_SYS_SerialNumberGetBinary(pipxStatus.CPUSerial);
|
||||
pipxStatus.BoardRevision= bdinfo->board_rev;
|
||||
oplinkStatus.BoardType= bdinfo->board_type;
|
||||
PIOS_BL_HELPER_FLASH_Read_Description(oplinkStatus.Description, OPLINKSTATUS_DESCRIPTION_NUMELEM);
|
||||
PIOS_SYS_SerialNumberGetBinary(oplinkStatus.CPUSerial);
|
||||
oplinkStatus.BoardRevision= bdinfo->board_rev;
|
||||
|
||||
// Update the object
|
||||
PipXStatusSet(&pipxStatus);
|
||||
OPLinkStatusSet(&oplinkStatus);
|
||||
|
||||
// Call the module start function.
|
||||
PipXtremeModStart();
|
||||
@ -123,6 +125,9 @@ MODULE_INITCALL(PipXtremeModInitialize, 0)
|
||||
static void systemTask(void *parameters)
|
||||
{
|
||||
portTickType lastSysTime;
|
||||
uint16_t prev_tx_count = 0;
|
||||
uint16_t prev_rx_count = 0;
|
||||
bool first_time = true;
|
||||
|
||||
/* create all modules thread */
|
||||
MODULE_TASKCREATE_ALL;
|
||||
@ -148,6 +153,58 @@ static void systemTask(void *parameters)
|
||||
PIOS_LED_Toggle(PIOS_LED_HEARTBEAT);
|
||||
#endif /* PIOS_LED_HEARTBEAT */
|
||||
|
||||
// Update the PipXstatus UAVO
|
||||
OPLinkStatusData oplinkStatus;
|
||||
uint32_t pairID;
|
||||
OPLinkStatusGet(&oplinkStatus);
|
||||
OPLinkSettingsPairIDGet(&pairID);
|
||||
|
||||
// Get the other device stats.
|
||||
PIOS_RFM2B_GetPairStats(pios_rfm22b_id, oplinkStatus.PairIDs, oplinkStatus.PairSignalStrengths, OPLINKSTATUS_PAIRIDS_NUMELEM);
|
||||
|
||||
// Get the stats from the radio device
|
||||
struct rfm22b_stats radio_stats;
|
||||
PIOS_RFM22B_GetStats(pios_rfm22b_id, &radio_stats);
|
||||
|
||||
// Update the status
|
||||
oplinkStatus.DeviceID = PIOS_RFM22B_DeviceID(pios_rfm22b_id);
|
||||
oplinkStatus.RxGood = radio_stats.rx_good;
|
||||
oplinkStatus.RxCorrected = radio_stats.rx_corrected;
|
||||
oplinkStatus.RxErrors = radio_stats.rx_error;
|
||||
oplinkStatus.RxMissed = radio_stats.rx_missed;
|
||||
oplinkStatus.RxFailure = radio_stats.rx_failure;
|
||||
oplinkStatus.TxDropped = radio_stats.tx_dropped;
|
||||
oplinkStatus.TxResent = radio_stats.tx_resent;
|
||||
oplinkStatus.TxFailure = radio_stats.tx_failure;
|
||||
oplinkStatus.Resets = radio_stats.resets;
|
||||
oplinkStatus.Timeouts = radio_stats.timeouts;
|
||||
oplinkStatus.RSSI = radio_stats.rssi;
|
||||
oplinkStatus.AFCCorrection = radio_stats.afc_correction;
|
||||
oplinkStatus.LinkQuality = radio_stats.link_quality;
|
||||
if (first_time)
|
||||
first_time = false;
|
||||
else
|
||||
{
|
||||
uint16_t tx_count = radio_stats.tx_byte_count;
|
||||
uint16_t rx_count = radio_stats.rx_byte_count;
|
||||
uint16_t tx_bytes = (tx_count < prev_tx_count) ? (0xffff - prev_tx_count + tx_count) : (tx_count - prev_tx_count);
|
||||
uint16_t rx_bytes = (rx_count < prev_rx_count) ? (0xffff - prev_rx_count + rx_count) : (rx_count - prev_rx_count);
|
||||
oplinkStatus.TXRate = (uint16_t)((float)(tx_bytes * 1000) / SYSTEM_UPDATE_PERIOD_MS);
|
||||
oplinkStatus.RXRate = (uint16_t)((float)(rx_bytes * 1000) / SYSTEM_UPDATE_PERIOD_MS);
|
||||
prev_tx_count = tx_count;
|
||||
prev_rx_count = rx_count;
|
||||
}
|
||||
oplinkStatus.TXSeq = radio_stats.tx_seq;
|
||||
oplinkStatus.RXSeq = radio_stats.rx_seq;
|
||||
oplinkStatus.LinkState = radio_stats.link_state;
|
||||
if (radio_stats.link_state == OPLINKSTATUS_LINKSTATE_CONNECTED)
|
||||
LINK_LED_ON;
|
||||
else
|
||||
LINK_LED_OFF;
|
||||
|
||||
// Update the object
|
||||
OPLinkStatusSet(&oplinkStatus);
|
||||
|
||||
// Wait until next period
|
||||
vTaskDelayUntil(&lastSysTime, SYSTEM_UPDATE_PERIOD_MS / portTICK_RATE_MS);
|
||||
}
|
||||
|
@ -1,476 +0,0 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @addtogroup OpenPilotModules OpenPilot Modules
|
||||
* @{
|
||||
* @addtogroup Radio Input / Output Module
|
||||
* @brief Read and Write packets from/to a radio device.
|
||||
* @{
|
||||
*
|
||||
* @file radio.c
|
||||
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2012.
|
||||
* @brief Bridges selected Com Port to the COM VCP emulated serial port
|
||||
* @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 <pios.h>
|
||||
#include <pios_board_info.h>
|
||||
#include <openpilot.h>
|
||||
#include <gcsreceiver.h>
|
||||
#include <hwsettings.h>
|
||||
#include <pipxsettings.h>
|
||||
#include <pipxstatus.h>
|
||||
#include <packet_handler.h>
|
||||
#include <pios_com_priv.h>
|
||||
#include <pios_rfm22b_priv.h>
|
||||
#include <radio.h>
|
||||
|
||||
// ****************
|
||||
// Private constants
|
||||
|
||||
#define STACK_SIZE_BYTES 200
|
||||
#define TASK_PRIORITY (tskIDLE_PRIORITY + 2)
|
||||
#define PACKET_QUEUE_SIZE PIOS_PH_WIN_SIZE
|
||||
#define MAX_PORT_DELAY 200
|
||||
#define STATS_UPDATE_PERIOD_MS 500
|
||||
#define RADIOSTATS_UPDATE_PERIOD_MS 250
|
||||
#define MAX_LOST_CONTACT_TIME 4
|
||||
#define PACKET_MAX_DELAY 50
|
||||
|
||||
#ifndef LINK_LED_ON
|
||||
#define LINK_LED_ON
|
||||
#define LINK_LED_OFF
|
||||
#endif
|
||||
|
||||
// ****************
|
||||
// Private types
|
||||
|
||||
typedef struct {
|
||||
uint32_t pairID;
|
||||
uint16_t retries;
|
||||
uint16_t errors;
|
||||
uint16_t uavtalk_errors;
|
||||
uint16_t resets;
|
||||
uint16_t dropped;
|
||||
int8_t rssi;
|
||||
uint8_t lastContact;
|
||||
} PairStats;
|
||||
|
||||
typedef struct {
|
||||
|
||||
// The task handles.
|
||||
xTaskHandle radioReceiveTaskHandle;
|
||||
xTaskHandle radioStatusTaskHandle;
|
||||
|
||||
// Queue handles.
|
||||
xQueueHandle radioPacketQueue;
|
||||
|
||||
// Error statistics.
|
||||
uint32_t radioTxErrors;
|
||||
uint32_t radioRxErrors;
|
||||
uint16_t txBytes;
|
||||
uint16_t rxBytes;
|
||||
|
||||
// External error statistics
|
||||
uint32_t droppedPackets;
|
||||
uint32_t comTxRetries;
|
||||
uint32_t UAVTalkErrors;
|
||||
|
||||
// The destination ID
|
||||
uint32_t destination_id;
|
||||
|
||||
// Track other radios that are in range.
|
||||
PairStats pairStats[PIPXSTATUS_PAIRIDS_NUMELEM];
|
||||
|
||||
// The RSSI of the last packet received.
|
||||
int8_t RSSI;
|
||||
|
||||
} RadioData;
|
||||
|
||||
// ****************
|
||||
// Private functions
|
||||
|
||||
static void radioReceiveTask(void *parameters);
|
||||
static void radioStatusTask(void *parameters);
|
||||
static void StatusHandler(PHStatusPacketHandle p, int8_t rssi, int8_t afc);
|
||||
static int32_t transmitPacket(PHPacketHandle packet);
|
||||
static void PPMHandler(uint16_t *channels);
|
||||
|
||||
// ****************
|
||||
// Private variables
|
||||
|
||||
static RadioData *data = 0;
|
||||
|
||||
// ****************
|
||||
// Global variables
|
||||
uint32_t pios_rfm22b_id = 0;
|
||||
uint32_t pios_com_rfm22b_id = 0;
|
||||
uint32_t pios_packet_handler = 0;
|
||||
const struct pios_rfm22b_cfg *pios_rfm22b_cfg;
|
||||
|
||||
// ***************
|
||||
// External functions
|
||||
extern const struct pios_rfm22b_cfg * PIOS_BOARD_HW_DEFS_GetRfm22Cfg (uint32_t board_revision);
|
||||
|
||||
/**
|
||||
* Start the module
|
||||
* \return -1 if initialisation failed
|
||||
* \return 0 on success
|
||||
*/
|
||||
static int32_t RadioStart(void)
|
||||
{
|
||||
if (!data)
|
||||
return -1;
|
||||
|
||||
// Start the tasks.
|
||||
xTaskCreate(radioReceiveTask, (signed char *)"RadioReceive", STACK_SIZE_BYTES, NULL, TASK_PRIORITY, &(data->radioReceiveTaskHandle));
|
||||
xTaskCreate(radioStatusTask, (signed char *)"RadioStatus", STACK_SIZE_BYTES * 2, NULL, TASK_PRIORITY, &(data->radioStatusTaskHandle));
|
||||
|
||||
// Install the monitors
|
||||
TaskMonitorAdd(TASKINFO_RUNNING_MODEMRX, data->radioReceiveTaskHandle);
|
||||
TaskMonitorAdd(TASKINFO_RUNNING_MODEMSTAT, data->radioStatusTaskHandle);
|
||||
|
||||
// Register the watchdog timers.
|
||||
#ifdef PIOS_WDG_RADIORECEIVE
|
||||
PIOS_WDG_RegisterFlag(PIOS_WDG_RADIORECEIVE);
|
||||
#endif /* PIOS_WDG_RADIORECEIVE */
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Initialise the module
|
||||
* \return -1 if initialisation failed
|
||||
* \return 0 on success
|
||||
*/
|
||||
static int32_t RadioInitialize(void)
|
||||
{
|
||||
|
||||
// See if this module is enabled.
|
||||
#ifndef RADIO_BUILTIN
|
||||
HwSettingsInitialize();
|
||||
uint8_t optionalModules[HWSETTINGS_OPTIONALMODULES_NUMELEM];
|
||||
HwSettingsOptionalModulesGet(optionalModules);
|
||||
if (optionalModules[HWSETTINGS_OPTIONALMODULES_RADIO] != HWSETTINGS_OPTIONALMODULES_ENABLED) {
|
||||
pios_packet_handler = 0;
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
|
||||
// Initalize out UAVOs
|
||||
PipXSettingsInitialize();
|
||||
PipXStatusInitialize();
|
||||
|
||||
PipXSettingsData pipxSettings;
|
||||
PipXSettingsGet(&pipxSettings);
|
||||
|
||||
/* Retrieve hardware settings. */
|
||||
const struct pios_board_info * bdinfo = &pios_board_info_blob;
|
||||
pios_rfm22b_cfg = PIOS_BOARD_HW_DEFS_GetRfm22Cfg(bdinfo->board_rev);
|
||||
|
||||
/* Initalize the RFM22B radio COM device. */
|
||||
if (PIOS_RFM22B_Init(&pios_rfm22b_id, PIOS_RFM22_SPI_PORT, pios_rfm22b_cfg->slave_num, pios_rfm22b_cfg))
|
||||
return -1;
|
||||
|
||||
// Set the maximum radio RF power.
|
||||
switch (pipxSettings.MaxRFPower)
|
||||
{
|
||||
case PIPXSETTINGS_MAXRFPOWER_125:
|
||||
PIOS_RFM22B_SetTxPower(pios_rfm22b_id, RFM22_tx_pwr_txpow_0);
|
||||
break;
|
||||
case PIPXSETTINGS_MAXRFPOWER_16:
|
||||
PIOS_RFM22B_SetTxPower(pios_rfm22b_id, RFM22_tx_pwr_txpow_1);
|
||||
break;
|
||||
case PIPXSETTINGS_MAXRFPOWER_316:
|
||||
PIOS_RFM22B_SetTxPower(pios_rfm22b_id, RFM22_tx_pwr_txpow_2);
|
||||
break;
|
||||
case PIPXSETTINGS_MAXRFPOWER_63:
|
||||
PIOS_RFM22B_SetTxPower(pios_rfm22b_id, RFM22_tx_pwr_txpow_3);
|
||||
break;
|
||||
case PIPXSETTINGS_MAXRFPOWER_126:
|
||||
PIOS_RFM22B_SetTxPower(pios_rfm22b_id, RFM22_tx_pwr_txpow_4);
|
||||
break;
|
||||
case PIPXSETTINGS_MAXRFPOWER_25:
|
||||
PIOS_RFM22B_SetTxPower(pios_rfm22b_id, RFM22_tx_pwr_txpow_5);
|
||||
break;
|
||||
case PIPXSETTINGS_MAXRFPOWER_50:
|
||||
PIOS_RFM22B_SetTxPower(pios_rfm22b_id, RFM22_tx_pwr_txpow_6);
|
||||
break;
|
||||
case PIPXSETTINGS_MAXRFPOWER_100:
|
||||
PIOS_RFM22B_SetTxPower(pios_rfm22b_id, RFM22_tx_pwr_txpow_7);
|
||||
break;
|
||||
}
|
||||
|
||||
switch (pipxSettings.RFSpeed) {
|
||||
case PIPXSETTINGS_RFSPEED_2400:
|
||||
RFM22_SetDatarate(pios_rfm22b_id, RFM22_datarate_2000, true);
|
||||
break;
|
||||
case PIPXSETTINGS_RFSPEED_4800:
|
||||
RFM22_SetDatarate(pios_rfm22b_id, RFM22_datarate_4000, true);
|
||||
break;
|
||||
case PIPXSETTINGS_RFSPEED_9600:
|
||||
RFM22_SetDatarate(pios_rfm22b_id, RFM22_datarate_9600, true);
|
||||
break;
|
||||
case PIPXSETTINGS_RFSPEED_19200:
|
||||
RFM22_SetDatarate(pios_rfm22b_id, RFM22_datarate_19200, true);
|
||||
break;
|
||||
case PIPXSETTINGS_RFSPEED_38400:
|
||||
RFM22_SetDatarate(pios_rfm22b_id, RFM22_datarate_32000, true);
|
||||
break;
|
||||
case PIPXSETTINGS_RFSPEED_57600:
|
||||
RFM22_SetDatarate(pios_rfm22b_id, RFM22_datarate_64000, true);
|
||||
break;
|
||||
case PIPXSETTINGS_RFSPEED_115200:
|
||||
RFM22_SetDatarate(pios_rfm22b_id, RFM22_datarate_128000, true);
|
||||
break;
|
||||
}
|
||||
|
||||
// Set the radio destination ID.
|
||||
PIOS_RFM22B_SetDestinationId(pios_rfm22b_id, pipxSettings.PairID);
|
||||
|
||||
// Initialize the packet handler
|
||||
PacketHandlerConfig pios_ph_cfg = {
|
||||
.default_destination_id = 0xffffffff, // Broadcast
|
||||
.source_id = PIOS_RFM22B_DeviceID(pios_rfm22b_id),
|
||||
.win_size = PIOS_PH_WIN_SIZE,
|
||||
.max_connections = PIOS_PH_MAX_CONNECTIONS,
|
||||
};
|
||||
pios_packet_handler = PHInitialize(&pios_ph_cfg);
|
||||
|
||||
// allocate and initialize the static data storage only if module is enabled
|
||||
data = (RadioData *)pvPortMalloc(sizeof(RadioData));
|
||||
if (!data)
|
||||
return -1;
|
||||
|
||||
// Initialize the statistics.
|
||||
data->radioTxErrors = 0;
|
||||
data->radioRxErrors = 0;
|
||||
data->droppedPackets = 0;
|
||||
data->comTxRetries = 0;
|
||||
data->UAVTalkErrors = 0;
|
||||
data->RSSI = -127;
|
||||
|
||||
// Initialize the detected device statistics.
|
||||
for (uint8_t i = 0; i < PIPXSTATUS_PAIRIDS_NUMELEM; ++i)
|
||||
{
|
||||
data->pairStats[i].pairID = 0;
|
||||
data->pairStats[i].rssi = -127;
|
||||
data->pairStats[i].retries = 0;
|
||||
data->pairStats[i].errors = 0;
|
||||
data->pairStats[i].uavtalk_errors = 0;
|
||||
data->pairStats[i].resets = 0;
|
||||
data->pairStats[i].dropped = 0;
|
||||
data->pairStats[i].lastContact = 0;
|
||||
}
|
||||
// The first slot is reserved for our current pairID
|
||||
PipXSettingsPairIDGet(&(data->pairStats[0].pairID));
|
||||
data->destination_id = data->pairStats[0].pairID ? data->pairStats[0].pairID : 0xffffffff;
|
||||
|
||||
// Register the callbacks with the packet handler
|
||||
PHRegisterStatusHandler(pios_packet_handler, StatusHandler);
|
||||
PHRegisterOutputStream(pios_packet_handler, transmitPacket);
|
||||
PHRegisterPPMHandler(pios_packet_handler, PPMHandler);
|
||||
|
||||
return 0;
|
||||
}
|
||||
MODULE_INITCALL(RadioInitialize, RadioStart)
|
||||
|
||||
/**
|
||||
* The task that receives packets from the radio.
|
||||
*/
|
||||
static void radioReceiveTask(void *parameters)
|
||||
{
|
||||
PHPacketHandle p = NULL;
|
||||
|
||||
/* Handle radio -> usart/usb direction */
|
||||
while (1) {
|
||||
uint32_t rx_bytes;
|
||||
|
||||
#ifdef PIOS_WDG_RADIORECEIVE
|
||||
// Update the watchdog timer.
|
||||
PIOS_WDG_UpdateFlag(PIOS_WDG_RADIORECEIVE);
|
||||
#endif /* PIOS_INCLUDE_WDG */
|
||||
|
||||
// Receive data from the radio port
|
||||
p = NULL;
|
||||
rx_bytes = PIOS_RFM22B_Receive_Packet(pios_rfm22b_id, &p, MAX_PORT_DELAY);
|
||||
if(rx_bytes == 0)
|
||||
continue;
|
||||
data->rxBytes += rx_bytes;
|
||||
PHReceivePacket(pios_packet_handler, p);
|
||||
p = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Transmit a packet to the radio port.
|
||||
* \param[in] buf Data buffer to send
|
||||
* \param[in] length Length of buffer
|
||||
* \return -1 on failure
|
||||
* \return number of bytes transmitted on success
|
||||
*/
|
||||
static int32_t transmitPacket(PHPacketHandle p)
|
||||
{
|
||||
uint16_t len = PH_PACKET_SIZE(p);
|
||||
data->txBytes += len;
|
||||
if (!PIOS_RFM22B_Send_Packet(pios_rfm22b_id, p, PACKET_MAX_DELAY))
|
||||
return -1;
|
||||
return len;
|
||||
}
|
||||
|
||||
/**
|
||||
* Receive a status packet
|
||||
* \param[in] status The status structure
|
||||
*/
|
||||
static void StatusHandler(PHStatusPacketHandle status, int8_t rssi, int8_t afc)
|
||||
{
|
||||
uint32_t id = status->header.source_id;
|
||||
bool found = false;
|
||||
// Have we seen this device recently?
|
||||
uint8_t id_idx = 0;
|
||||
for ( ; id_idx < PIPXSTATUS_PAIRIDS_NUMELEM; ++id_idx)
|
||||
if(data->pairStats[id_idx].pairID == id)
|
||||
{
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
|
||||
// If we have seen it, update the RSSI and reset the last contact couter
|
||||
if(found)
|
||||
{
|
||||
data->pairStats[id_idx].rssi = rssi;
|
||||
data->pairStats[id_idx].retries = status->retries;
|
||||
data->pairStats[id_idx].errors = status->errors;
|
||||
data->pairStats[id_idx].uavtalk_errors = status->uavtalk_errors;
|
||||
data->pairStats[id_idx].resets = status->resets;
|
||||
data->pairStats[id_idx].dropped = status->dropped;
|
||||
data->pairStats[id_idx].lastContact = 0;
|
||||
}
|
||||
|
||||
// If we haven't seen it, find a slot to put it in.
|
||||
if (!found)
|
||||
{
|
||||
uint32_t pairID;
|
||||
PipXSettingsPairIDGet(&pairID);
|
||||
|
||||
uint8_t min_idx = 0;
|
||||
if(id != pairID)
|
||||
{
|
||||
int8_t min_rssi = data->pairStats[0].rssi;
|
||||
for (id_idx = 1; id_idx < PIPXSTATUS_PAIRIDS_NUMELEM; ++id_idx)
|
||||
{
|
||||
if(data->pairStats[id_idx].rssi < min_rssi)
|
||||
{
|
||||
min_rssi = data->pairStats[id_idx].rssi;
|
||||
min_idx = id_idx;
|
||||
}
|
||||
}
|
||||
}
|
||||
data->pairStats[min_idx].pairID = id;
|
||||
data->pairStats[min_idx].rssi = rssi;
|
||||
data->pairStats[min_idx].retries = status->retries;
|
||||
data->pairStats[min_idx].errors = status->errors;
|
||||
data->pairStats[min_idx].uavtalk_errors = status->uavtalk_errors;
|
||||
data->pairStats[min_idx].resets = status->resets;
|
||||
data->pairStats[min_idx].dropped = status->dropped;
|
||||
data->pairStats[min_idx].lastContact = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The stats update task.
|
||||
*/
|
||||
static void radioStatusTask(void *parameters)
|
||||
{
|
||||
while (1) {
|
||||
PipXStatusData pipxStatus;
|
||||
uint32_t pairID;
|
||||
|
||||
// Get object data
|
||||
PipXStatusGet(&pipxStatus);
|
||||
PipXSettingsPairIDGet(&pairID);
|
||||
|
||||
// Update the status
|
||||
pipxStatus.DeviceID = PIOS_RFM22B_DeviceID(pios_rfm22b_id);
|
||||
pipxStatus.Retries = data->comTxRetries;
|
||||
pipxStatus.LinkQuality = PIOS_RFM22B_LinkQuality(pios_rfm22b_id);
|
||||
pipxStatus.UAVTalkErrors = data->UAVTalkErrors;
|
||||
pipxStatus.Dropped = data->droppedPackets;
|
||||
pipxStatus.Resets = PIOS_RFM22B_Resets(pios_rfm22b_id);
|
||||
pipxStatus.TXRate = (uint16_t)((float)(data->txBytes * 1000) / STATS_UPDATE_PERIOD_MS);
|
||||
data->txBytes = 0;
|
||||
pipxStatus.RXRate = (uint16_t)((float)(data->rxBytes * 1000) / STATS_UPDATE_PERIOD_MS);
|
||||
data->rxBytes = 0;
|
||||
pipxStatus.LinkState = PIPXSTATUS_LINKSTATE_DISCONNECTED;
|
||||
pipxStatus.RSSI = PIOS_RFM22B_LinkQuality(pios_rfm22b_id);
|
||||
LINK_LED_OFF;
|
||||
|
||||
// Update the potential pairing contacts
|
||||
for (uint8_t i = 0; i < PIPXSTATUS_PAIRIDS_NUMELEM; ++i)
|
||||
{
|
||||
pipxStatus.PairIDs[i] = data->pairStats[i].pairID;
|
||||
pipxStatus.PairSignalStrengths[i] = data->pairStats[i].rssi;
|
||||
data->pairStats[i].lastContact++;
|
||||
// Remove this device if it's stale.
|
||||
if(data->pairStats[i].lastContact > MAX_LOST_CONTACT_TIME)
|
||||
{
|
||||
data->pairStats[i].pairID = 0;
|
||||
data->pairStats[i].rssi = -127;
|
||||
data->pairStats[i].retries = 0;
|
||||
data->pairStats[i].errors = 0;
|
||||
data->pairStats[i].uavtalk_errors = 0;
|
||||
data->pairStats[i].resets = 0;
|
||||
data->pairStats[i].dropped = 0;
|
||||
data->pairStats[i].lastContact = 0;
|
||||
}
|
||||
// Add the paired devices statistics to ours.
|
||||
if(pairID && (data->pairStats[i].pairID == pairID) && (data->pairStats[i].rssi > -127))
|
||||
{
|
||||
pipxStatus.Retries += data->pairStats[i].retries;
|
||||
pipxStatus.UAVTalkErrors += data->pairStats[i].uavtalk_errors;
|
||||
pipxStatus.Dropped += data->pairStats[i].dropped;
|
||||
pipxStatus.Resets += data->pairStats[i].resets;
|
||||
pipxStatus.Dropped += data->pairStats[i].dropped;
|
||||
pipxStatus.LinkState = PIPXSTATUS_LINKSTATE_CONNECTED;
|
||||
LINK_LED_ON;
|
||||
}
|
||||
}
|
||||
|
||||
// Update the object
|
||||
PipXStatusSet(&pipxStatus);
|
||||
|
||||
vTaskDelay(STATS_UPDATE_PERIOD_MS / portTICK_RATE_MS);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Receive a ppm packet
|
||||
* \param[in] channels The ppm channels
|
||||
*/
|
||||
static void PPMHandler(uint16_t *channels)
|
||||
{
|
||||
GCSReceiverData rcvr;
|
||||
|
||||
// Copy the receiver channels into the GCSReceiver object.
|
||||
for (uint8_t i = 0; i < GCSRECEIVER_CHANNEL_NUMELEM; ++i)
|
||||
rcvr.Channel[i] = channels[i];
|
||||
|
||||
// Set the GCSReceiverData object.
|
||||
GCSReceiverSet(&rcvr);
|
||||
}
|
@ -34,9 +34,9 @@
|
||||
#include <radiocombridge.h>
|
||||
#include <packet_handler.h>
|
||||
#include <gcsreceiver.h>
|
||||
#include <pipxstatus.h>
|
||||
#include <oplinkstatus.h>
|
||||
#include <objectpersistence.h>
|
||||
#include <pipxsettings.h>
|
||||
#include <oplinksettings.h>
|
||||
#include <uavtalk_priv.h>
|
||||
#include <pios_rfm22b.h>
|
||||
#include <ecc.h>
|
||||
@ -49,46 +49,28 @@
|
||||
// ****************
|
||||
// Private constants
|
||||
|
||||
#define TEMP_BUFFER_SIZE 25
|
||||
#define STACK_SIZE_BYTES 150
|
||||
#define TASK_PRIORITY (tskIDLE_PRIORITY + 1)
|
||||
#define BRIDGE_BUF_LEN 512
|
||||
#define MAX_RETRIES 2
|
||||
#define RETRY_TIMEOUT_MS 20
|
||||
#define STATS_UPDATE_PERIOD_MS 1000
|
||||
#define RADIOSTATS_UPDATE_PERIOD_MS 500
|
||||
#define MAX_LOST_CONTACT_TIME 4
|
||||
#define PACKET_QUEUE_SIZE 10
|
||||
#define EVENT_QUEUE_SIZE 10
|
||||
#define MAX_PORT_DELAY 200
|
||||
#define EV_PACKET_RECEIVED 0x20
|
||||
#define EV_TRANSMIT_PACKET 0x30
|
||||
#define EV_SEND_ACK 0x40
|
||||
#define EV_SEND_NACK 0x50
|
||||
#define EV_SEND_ACK 0x20
|
||||
#define EV_SEND_NACK 0x30
|
||||
|
||||
// ****************
|
||||
// Private types
|
||||
|
||||
typedef struct {
|
||||
uint32_t comPort;
|
||||
UAVTalkConnection UAVTalkCon;
|
||||
xQueueHandle sendQueue;
|
||||
xQueueHandle recvQueue;
|
||||
uint16_t wdg;
|
||||
bool isGCS;
|
||||
} UAVTalkComTaskParams;
|
||||
|
||||
typedef struct {
|
||||
|
||||
// The task handles.
|
||||
xTaskHandle GCSUAVTalkRecvTaskHandle;
|
||||
xTaskHandle UAVTalkRecvTaskHandle;
|
||||
xTaskHandle UAVTalkSendTaskHandle;
|
||||
xTaskHandle transparentCommTaskHandle;
|
||||
xTaskHandle ppmInputTaskHandle;
|
||||
xTaskHandle telemetryTxTaskHandle;
|
||||
xTaskHandle radioRxTaskHandle;
|
||||
xTaskHandle radioTxTaskHandle;
|
||||
|
||||
// The UAVTalk connection on the com side.
|
||||
UAVTalkConnection UAVTalkCon;
|
||||
UAVTalkConnection GCSUAVTalkCon;
|
||||
UAVTalkConnection outUAVTalkCon;
|
||||
UAVTalkConnection inUAVTalkCon;
|
||||
|
||||
// Queue handles.
|
||||
xQueueHandle gcsEventQueue;
|
||||
@ -100,45 +82,19 @@ typedef struct {
|
||||
uint32_t UAVTalkErrors;
|
||||
uint32_t droppedPackets;
|
||||
|
||||
// The destination ID
|
||||
uint32_t destination_id;
|
||||
|
||||
// The packet timeout.
|
||||
portTickType send_timeout;
|
||||
uint16_t min_packet_size;
|
||||
|
||||
// The RSSI of the last packet received.
|
||||
int8_t RSSI;
|
||||
|
||||
// Thread parameters.
|
||||
UAVTalkComTaskParams uavtalk_params;
|
||||
UAVTalkComTaskParams gcs_uavtalk_params;
|
||||
|
||||
} RadioComBridgeData;
|
||||
|
||||
typedef struct {
|
||||
uint32_t com_port;
|
||||
uint8_t *buffer;
|
||||
uint16_t length;
|
||||
uint16_t index;
|
||||
uint16_t data_length;
|
||||
} ReadBuffer, *BufferedReadHandle;
|
||||
|
||||
// ****************
|
||||
// Private functions
|
||||
|
||||
static void UAVTalkRecvTask(void *parameters);
|
||||
static void UAVTalkSendTask(void *parameters);
|
||||
static void transparentCommTask(void * parameters);
|
||||
static void ppmInputTask(void *parameters);
|
||||
static int32_t UAVTalkSendHandler(uint8_t * data, int32_t length);
|
||||
static int32_t GCSUAVTalkSendHandler(uint8_t * data, int32_t length);
|
||||
static void receiveData(uint8_t *buf, uint8_t len, int8_t rssi, int8_t afc);
|
||||
static void transmitData(uint32_t outputPort, uint8_t *buf, uint8_t len, bool checkHid);
|
||||
static BufferedReadHandle BufferedReadInit(uint32_t com_port, uint16_t buffer_length);
|
||||
static bool BufferedRead(BufferedReadHandle h, uint8_t *value, uint32_t timeout_ms);
|
||||
static void BufferedReadSetCom(BufferedReadHandle h, uint32_t com_port);
|
||||
static void telemetryTxTask(void *parameters);
|
||||
static void radioRxTask(void *parameters);
|
||||
static void radioTxTask(void *parameters);
|
||||
static int32_t UAVTalkSendHandler(uint8_t *buf, int32_t length);
|
||||
static int32_t RadioSendHandler(uint8_t *buf, int32_t length);
|
||||
static void ProcessInputStream(UAVTalkConnection connectionHandle, uint8_t rxbyte);
|
||||
static void queueEvent(xQueueHandle queue, void *obj, uint16_t instId, UAVObjEventType type);
|
||||
static void configureComCallback(OPLinkSettingsOutputConnectionOptions com_port, OPLinkSettingsComSpeedOptions com_speed);
|
||||
static void updateSettings();
|
||||
|
||||
// ****************
|
||||
@ -155,37 +111,24 @@ static int32_t RadioComBridgeStart(void)
|
||||
{
|
||||
if(data) {
|
||||
|
||||
// Register the callbacks with the packet handler
|
||||
// This has to happen after the Radio module is initialized.
|
||||
PHRegisterDataHandler(pios_packet_handler, receiveData);
|
||||
// Configure the com port configuration callback
|
||||
PIOS_RFM22B_SetComConfigCallback(pios_rfm22b_id, &configureComCallback);
|
||||
|
||||
// Set the baudrates, etc.
|
||||
updateSettings();
|
||||
|
||||
// Start the primary tasks for receiving/sending UAVTalk packets from the GCS.
|
||||
xTaskCreate(UAVTalkRecvTask, (signed char *)"GCSUAVTalkRecvTask", STACK_SIZE_BYTES, (void*)&(data->gcs_uavtalk_params), TASK_PRIORITY + 2, &(data->GCSUAVTalkRecvTaskHandle));
|
||||
xTaskCreate(UAVTalkSendTask, (signed char *)"GCSUAVTalkSendTask", STACK_SIZE_BYTES, (void*)&(data->gcs_uavtalk_params), TASK_PRIORITY+ 2, &(data->UAVTalkSendTaskHandle));
|
||||
|
||||
// If a UAVTalk (non-GCS) com port is set it implies that the com port is connected on the flight side.
|
||||
// In this case we want to start another com thread on the HID port to talk to the GCS when connected.
|
||||
if (PIOS_COM_UAVTALK)
|
||||
{
|
||||
xTaskCreate(UAVTalkRecvTask, (signed char *)"UAVTalkRecvTask", STACK_SIZE_BYTES, (void*)&(data->uavtalk_params), TASK_PRIORITY + 2, &(data->UAVTalkRecvTaskHandle));
|
||||
xTaskCreate(UAVTalkSendTask, (signed char *)"UAVTalkSendTask", STACK_SIZE_BYTES, (void*)&(data->uavtalk_params), TASK_PRIORITY+ 2, &(data->UAVTalkSendTaskHandle));
|
||||
}
|
||||
|
||||
// Start the tasks
|
||||
if(PIOS_COM_TRANS_COM)
|
||||
xTaskCreate(transparentCommTask, (signed char *)"transparentComm", STACK_SIZE_BYTES, NULL, TASK_PRIORITY + 2, &(data->transparentCommTaskHandle));
|
||||
if(PIOS_PPM_RECEIVER)
|
||||
xTaskCreate(ppmInputTask, (signed char *)"PPMInputTask", STACK_SIZE_BYTES, NULL, TASK_PRIORITY + 2, &(data->ppmInputTaskHandle));
|
||||
xTaskCreate(telemetryTxTask, (signed char *)"telemTxTask", STACK_SIZE_BYTES, NULL, TASK_PRIORITY, &(data->telemetryTxTaskHandle));
|
||||
xTaskCreate(radioRxTask, (signed char *)"radioRxTask", STACK_SIZE_BYTES, NULL, TASK_PRIORITY, &(data->radioRxTaskHandle));
|
||||
xTaskCreate(radioTxTask, (signed char *)"radioTxTask", STACK_SIZE_BYTES, NULL, TASK_PRIORITY, &(data->radioTxTaskHandle));
|
||||
|
||||
// Register the watchdog timers.
|
||||
#ifdef PIOS_INCLUDE_WDG
|
||||
PIOS_WDG_RegisterFlag(PIOS_WDG_COMGCS);
|
||||
if(PIOS_COM_UAVTALK)
|
||||
PIOS_WDG_RegisterFlag(PIOS_WDG_COMUAVTALK);
|
||||
if(PIOS_COM_TRANS_COM)
|
||||
PIOS_WDG_RegisterFlag(PIOS_WDG_TRANSCOMM);
|
||||
if(PIOS_PPM_RECEIVER)
|
||||
PIOS_WDG_RegisterFlag(PIOS_WDG_PPMINPUT);
|
||||
PIOS_WDG_RegisterFlag(PIOS_WDG_TELEMETRY);
|
||||
PIOS_WDG_RegisterFlag(PIOS_WDG_RADIORX);
|
||||
PIOS_WDG_RegisterFlag(PIOS_WDG_RADIOTX);
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -207,315 +150,50 @@ static int32_t RadioComBridgeInitialize(void)
|
||||
|
||||
// Initialize the UAVObjects that we use
|
||||
GCSReceiverInitialize();
|
||||
PipXStatusInitialize();
|
||||
OPLinkStatusInitialize();
|
||||
ObjectPersistenceInitialize();
|
||||
updateSettings();
|
||||
|
||||
// Initialise UAVTalk
|
||||
data->GCSUAVTalkCon = UAVTalkInitialize(&GCSUAVTalkSendHandler);
|
||||
if (PIOS_COM_UAVTALK)
|
||||
data->UAVTalkCon = UAVTalkInitialize(&UAVTalkSendHandler);
|
||||
else
|
||||
data->UAVTalkCon = 0;
|
||||
data->outUAVTalkCon = UAVTalkInitialize(&UAVTalkSendHandler);
|
||||
data->inUAVTalkCon = UAVTalkInitialize(&RadioSendHandler);
|
||||
|
||||
// Initialize the queues.
|
||||
data->gcsEventQueue = xQueueCreate(PACKET_QUEUE_SIZE, sizeof(UAVObjEvent));
|
||||
if (PIOS_COM_UAVTALK)
|
||||
data->uavtalkEventQueue = xQueueCreate(PACKET_QUEUE_SIZE, sizeof(UAVObjEvent));
|
||||
else
|
||||
{
|
||||
data->uavtalkEventQueue = 0;
|
||||
}
|
||||
data->uavtalkEventQueue = xQueueCreate(EVENT_QUEUE_SIZE, sizeof(UAVObjEvent));
|
||||
|
||||
// Configure our UAVObjects for updates.
|
||||
UAVObjConnectQueue(UAVObjGetByID(OPLINKSTATUS_OBJID), data->uavtalkEventQueue, EV_UPDATED | EV_UPDATED_MANUAL | EV_UPDATE_REQ);
|
||||
UAVObjConnectQueue(UAVObjGetByID(OBJECTPERSISTENCE_OBJID), data->uavtalkEventQueue, EV_UPDATED | EV_UPDATED_MANUAL);
|
||||
|
||||
// Initialize the statistics.
|
||||
data->comTxErrors = 0;
|
||||
data->comTxRetries = 0;
|
||||
data->UAVTalkErrors = 0;
|
||||
data->RSSI = -127;
|
||||
|
||||
// Initialize the packet send timeout
|
||||
data->send_timeout = 25; // ms
|
||||
data->min_packet_size = 50;
|
||||
|
||||
// Configure our UAVObjects for updates.
|
||||
UAVObjConnectQueue(UAVObjGetByID(PIPXSTATUS_OBJID), data->gcsEventQueue, EV_UPDATED | EV_UPDATED_MANUAL | EV_UPDATE_REQ);
|
||||
UAVObjConnectQueue(UAVObjGetByID(GCSRECEIVER_OBJID), data->uavtalkEventQueue ? data->uavtalkEventQueue : data->gcsEventQueue, EV_UPDATED | EV_UPDATED_MANUAL | EV_UPDATE_REQ);
|
||||
UAVObjConnectQueue(UAVObjGetByID(OBJECTPERSISTENCE_OBJID), data->gcsEventQueue, EV_UPDATED | EV_UPDATED_MANUAL);
|
||||
|
||||
// Initialize the UAVTalk comm parameters.
|
||||
data->gcs_uavtalk_params.isGCS = true;
|
||||
data->gcs_uavtalk_params.UAVTalkCon = data->GCSUAVTalkCon;
|
||||
data->gcs_uavtalk_params.sendQueue = data->uavtalkEventQueue;
|
||||
data->gcs_uavtalk_params.recvQueue = data->gcsEventQueue;
|
||||
data->gcs_uavtalk_params.wdg = PIOS_WDG_COMGCS;
|
||||
data->gcs_uavtalk_params.comPort = PIOS_COM_GCS;
|
||||
if (PIOS_COM_UAVTALK)
|
||||
{
|
||||
data->uavtalk_params.isGCS = false;
|
||||
data->uavtalk_params.UAVTalkCon = data->UAVTalkCon;
|
||||
data->uavtalk_params.sendQueue = data->gcsEventQueue;
|
||||
data->uavtalk_params.recvQueue = data->uavtalkEventQueue;
|
||||
data->uavtalk_params.wdg = PIOS_WDG_COMUAVTALK;
|
||||
data->uavtalk_params.comPort = PIOS_COM_UAVTALK;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
MODULE_INITCALL(RadioComBridgeInitialize, RadioComBridgeStart)
|
||||
|
||||
/**
|
||||
* Reads UAVTalk messages froma com port and creates packets out of them.
|
||||
* Telemetry transmit task, regular priority
|
||||
*/
|
||||
static void UAVTalkRecvTask(void *parameters)
|
||||
static void telemetryTxTask(void *parameters)
|
||||
{
|
||||
UAVTalkComTaskParams *params = (UAVTalkComTaskParams *)parameters;
|
||||
PHPacketHandle p = NULL;
|
||||
|
||||
// Create the buffered reader.
|
||||
BufferedReadHandle f = BufferedReadInit(params->comPort, TEMP_BUFFER_SIZE);
|
||||
|
||||
while (1) {
|
||||
bool HID_available = false;
|
||||
xQueueHandle sendQueue = 0;
|
||||
|
||||
#ifdef PIOS_INCLUDE_WDG
|
||||
// Update the watchdog timer.
|
||||
if (params->wdg)
|
||||
PIOS_WDG_UpdateFlag(params->wdg);
|
||||
#endif /* PIOS_INCLUDE_WDG */
|
||||
|
||||
#if defined(PIOS_INCLUDE_USB)
|
||||
// Is USB plugged in?
|
||||
if (PIOS_USB_CheckAvailable(0))
|
||||
HID_available = true;
|
||||
#endif /* PIOS_INCLUDE_USB */
|
||||
|
||||
// Receive from USB HID if available, otherwise UAVTalk com if it's available.
|
||||
if (params->isGCS && HID_available)
|
||||
BufferedReadSetCom(f, PIOS_COM_USB_HID);
|
||||
else
|
||||
{
|
||||
if (params->comPort)
|
||||
BufferedReadSetCom(f, params->comPort);
|
||||
else
|
||||
{
|
||||
vTaskDelay(5);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// Send packets to the UAVTalk port if this is a GCS connction and UAVTalk port is configured
|
||||
// or to the GCS port if this is a UAVTalk connection and USB is plugged in.
|
||||
if ((params->isGCS && data->UAVTalkCon) || (!params->isGCS && HID_available))
|
||||
sendQueue = params->sendQueue;
|
||||
|
||||
// Read the next byte
|
||||
uint8_t rx_byte;
|
||||
if (!BufferedRead(f, &rx_byte, MAX_PORT_DELAY))
|
||||
continue;
|
||||
|
||||
// Get a TX packet from the packet handler if required.
|
||||
if (p == NULL)
|
||||
{
|
||||
|
||||
// Wait until we receive a sync.
|
||||
UAVTalkRxState state = UAVTalkProcessInputStreamQuiet(params->UAVTalkCon, rx_byte);
|
||||
if (state != UAVTALK_STATE_TYPE)
|
||||
continue;
|
||||
|
||||
// Get a packet when we see the sync
|
||||
p = PHGetTXPacket(pios_packet_handler);
|
||||
|
||||
// No packets available?
|
||||
if (p == NULL)
|
||||
{
|
||||
data->droppedPackets++;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Initialize the packet.
|
||||
p->header.destination_id = data->destination_id;
|
||||
p->header.type = PACKET_TYPE_DATA;
|
||||
p->data[0] = rx_byte;
|
||||
p->header.data_size = 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Insert this byte.
|
||||
p->data[p->header.data_size++] = rx_byte;
|
||||
|
||||
// Keep reading until we receive a completed packet.
|
||||
UAVTalkRxState state = UAVTalkProcessInputStreamQuiet(params->UAVTalkCon, rx_byte);
|
||||
UAVTalkConnectionData *connection = (UAVTalkConnectionData*)(params->UAVTalkCon);
|
||||
UAVTalkInputProcessor *iproc = &(connection->iproc);
|
||||
|
||||
if (state == UAVTALK_STATE_COMPLETE)
|
||||
{
|
||||
// Is this a local UAVObject?
|
||||
// We only generate GcsReceiver ojects, we don't consume them.
|
||||
if ((iproc->obj != NULL) && (iproc->objId != GCSRECEIVER_OBJID))
|
||||
{
|
||||
// We treat the ObjectPersistence object differently
|
||||
if(iproc->objId == OBJECTPERSISTENCE_OBJID)
|
||||
{
|
||||
// Unpack object, if the instance does not exist it will be created!
|
||||
UAVObjUnpack(iproc->obj, iproc->instId, connection->rxBuffer);
|
||||
|
||||
// Get the ObjectPersistence object.
|
||||
ObjectPersistenceData obj_per;
|
||||
ObjectPersistenceGet(&obj_per);
|
||||
|
||||
// Is this concerning or setting object?
|
||||
if (obj_per.ObjectID == PIPXSETTINGS_OBJID)
|
||||
{
|
||||
// Queue up the ACK.
|
||||
queueEvent(params->recvQueue, (void*)iproc->obj, iproc->instId, EV_SEND_ACK);
|
||||
|
||||
// Is this a save, load, or delete?
|
||||
bool success = true;
|
||||
switch (obj_per.Operation)
|
||||
{
|
||||
case OBJECTPERSISTENCE_OPERATION_LOAD:
|
||||
{
|
||||
#if defined(PIOS_INCLUDE_FLASH_EEPROM)
|
||||
// Load the settings.
|
||||
PipXSettingsData pipxSettings;
|
||||
if (PIOS_EEPROM_Load((uint8_t*)&pipxSettings, sizeof(PipXSettingsData)) == 0)
|
||||
PipXSettingsSet(&pipxSettings);
|
||||
else
|
||||
success = false;
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
case OBJECTPERSISTENCE_OPERATION_SAVE:
|
||||
{
|
||||
#if defined(PIOS_INCLUDE_FLASH_EEPROM)
|
||||
// Save the settings.
|
||||
PipXSettingsData pipxSettings;
|
||||
PipXSettingsGet(&pipxSettings);
|
||||
int32_t ret = PIOS_EEPROM_Save((uint8_t*)&pipxSettings, sizeof(PipXSettingsData));
|
||||
if (ret != 0)
|
||||
success = false;
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
case OBJECTPERSISTENCE_OPERATION_DELETE:
|
||||
{
|
||||
#if defined(PIOS_INCLUDE_FLASH_EEPROM)
|
||||
// Erase the settings.
|
||||
PipXSettingsData pipxSettings;
|
||||
uint8_t *ptr = (uint8_t*)&pipxSettings;
|
||||
memset(ptr, 0, sizeof(PipXSettingsData));
|
||||
int32_t ret = PIOS_EEPROM_Save(ptr, sizeof(PipXSettingsData));
|
||||
if (ret != 0)
|
||||
success = false;
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if (success == true)
|
||||
{
|
||||
obj_per.Operation = OBJECTPERSISTENCE_OPERATION_COMPLETED;
|
||||
ObjectPersistenceSet(&obj_per);
|
||||
}
|
||||
|
||||
// Release the packet, since we don't need it.
|
||||
PHReleaseTXPacket(pios_packet_handler, p);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Otherwise, queue the packet for transmission.
|
||||
if (sendQueue)
|
||||
queueEvent(sendQueue, (void*)p, 0, EV_TRANSMIT_PACKET);
|
||||
else
|
||||
PHTransmitPacket(PIOS_PACKET_HANDLER, p);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (iproc->type)
|
||||
{
|
||||
case UAVTALK_TYPE_OBJ:
|
||||
// Unpack object, if the instance does not exist it will be created!
|
||||
UAVObjUnpack(iproc->obj, iproc->instId, connection->rxBuffer);
|
||||
break;
|
||||
case UAVTALK_TYPE_OBJ_REQ:
|
||||
// Queue up an object send request.
|
||||
queueEvent(params->recvQueue, (void*)iproc->obj, iproc->instId, EV_UPDATE_REQ);
|
||||
break;
|
||||
case UAVTALK_TYPE_OBJ_ACK:
|
||||
if (UAVObjUnpack(iproc->obj, iproc->instId, connection->rxBuffer) == 0)
|
||||
// Queue up an ACK
|
||||
queueEvent(params->recvQueue, (void*)iproc->obj, iproc->instId, EV_SEND_ACK);
|
||||
break;
|
||||
}
|
||||
|
||||
// Release the packet, since we don't need it.
|
||||
PHReleaseTXPacket(pios_packet_handler, p);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Queue the packet for transmission.
|
||||
if (sendQueue)
|
||||
queueEvent(sendQueue, (void*)p, 0, EV_TRANSMIT_PACKET);
|
||||
else
|
||||
PHTransmitPacket(PIOS_PACKET_HANDLER, p);
|
||||
}
|
||||
p = NULL;
|
||||
|
||||
} else if(state == UAVTALK_STATE_ERROR) {
|
||||
data->UAVTalkErrors++;
|
||||
|
||||
// Send a NACK if required.
|
||||
if((iproc->obj) && (iproc->type == UAVTALK_TYPE_OBJ_ACK))
|
||||
{
|
||||
// Queue up a NACK
|
||||
queueEvent(params->recvQueue, iproc->obj, iproc->instId, EV_SEND_NACK);
|
||||
|
||||
// Release the packet and start over again.
|
||||
PHReleaseTXPacket(pios_packet_handler, p);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Transmit the packet anyway...
|
||||
if (sendQueue)
|
||||
queueEvent(sendQueue, (void*)p, 0, EV_TRANSMIT_PACKET);
|
||||
else
|
||||
PHTransmitPacket(PIOS_PACKET_HANDLER, p);
|
||||
}
|
||||
p = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Send packets to the com port.
|
||||
*/
|
||||
static void UAVTalkSendTask(void *parameters)
|
||||
{
|
||||
UAVTalkComTaskParams *params = (UAVTalkComTaskParams *)parameters;
|
||||
UAVObjEvent ev;
|
||||
|
||||
// Loop forever
|
||||
while (1) {
|
||||
#ifdef PIOS_INCLUDE_WDG
|
||||
// Update the watchdog timer.
|
||||
// NOTE: this is temporarily turned off becase PIOS_Com_SendBuffer appears to block for an uncontrollable time,
|
||||
// and SendBufferNonBlocking doesn't seem to be working in this case.
|
||||
//PIOS_WDG_UpdateFlag(PIOS_WDG_SENDDATA);
|
||||
#endif /* PIOS_INCLUDE_WDG */
|
||||
// Wait for a packet on the queue.
|
||||
if (xQueueReceive(params->recvQueue, &ev, MAX_PORT_DELAY) == pdTRUE) {
|
||||
PIOS_WDG_UpdateFlag(PIOS_WDG_TELEMETRY);
|
||||
#endif
|
||||
// Wait for queue message
|
||||
if (xQueueReceive(data->uavtalkEventQueue, &ev, MAX_PORT_DELAY) == pdTRUE) {
|
||||
if ((ev.event == EV_UPDATED) || (ev.event == EV_UPDATE_REQ))
|
||||
{
|
||||
// Send update (with retries)
|
||||
uint32_t retries = 0;
|
||||
int32_t success = -1;
|
||||
while (retries < MAX_RETRIES && success == -1) {
|
||||
success = UAVTalkSendObject(params->UAVTalkCon, ev.obj, 0, 0, RETRY_TIMEOUT_MS) == 0;
|
||||
success = UAVTalkSendObject(data->outUAVTalkCon, ev.obj, 0, 0, RETRY_TIMEOUT_MS) == 0;
|
||||
if (!success)
|
||||
++retries;
|
||||
}
|
||||
@ -527,7 +205,7 @@ static void UAVTalkSendTask(void *parameters)
|
||||
uint32_t retries = 0;
|
||||
int32_t success = -1;
|
||||
while (retries < MAX_RETRIES && success == -1) {
|
||||
success = UAVTalkSendAck(params->UAVTalkCon, ev.obj, ev.instId) == 0;
|
||||
success = UAVTalkSendAck(data->outUAVTalkCon, ev.obj, ev.instId) == 0;
|
||||
if (!success)
|
||||
++retries;
|
||||
}
|
||||
@ -539,182 +217,76 @@ static void UAVTalkSendTask(void *parameters)
|
||||
uint32_t retries = 0;
|
||||
int32_t success = -1;
|
||||
while (retries < MAX_RETRIES && success == -1) {
|
||||
success = UAVTalkSendNack(params->UAVTalkCon, UAVObjGetID(ev.obj)) == 0;
|
||||
success = UAVTalkSendNack(data->outUAVTalkCon, UAVObjGetID(ev.obj)) == 0;
|
||||
if (!success)
|
||||
++retries;
|
||||
}
|
||||
data->comTxRetries += retries;
|
||||
}
|
||||
else if(ev.event == EV_PACKET_RECEIVED)
|
||||
{
|
||||
// Receive the packet.
|
||||
PHReceivePacket(pios_packet_handler, (PHPacketHandle)ev.obj);
|
||||
}
|
||||
else if(ev.event == EV_TRANSMIT_PACKET)
|
||||
{
|
||||
// Transmit the packet.
|
||||
PHPacketHandle p = (PHPacketHandle)ev.obj;
|
||||
UAVTalkSendBuf(params->UAVTalkCon, p->data, p->header.data_size);
|
||||
PHReleaseTXPacket(pios_packet_handler, p);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The com to radio bridge task.
|
||||
* Radio rx task. Receive data packets from the radio and pass them on.
|
||||
*/
|
||||
static void transparentCommTask(void * parameters)
|
||||
static void radioRxTask(void *parameters)
|
||||
{
|
||||
portTickType packet_start_time = 0;
|
||||
uint32_t timeout = MAX_PORT_DELAY;
|
||||
PHPacketHandle p = NULL;
|
||||
|
||||
/* Handle usart/usb -> radio direction */
|
||||
// Task loop
|
||||
while (1) {
|
||||
|
||||
#ifdef PIOS_INCLUDE_WDG
|
||||
// Update the watchdog timer.
|
||||
PIOS_WDG_UpdateFlag(PIOS_WDG_TRANSCOMM);
|
||||
#endif /* PIOS_INCLUDE_WDG */
|
||||
|
||||
// Get a TX packet from the packet handler if required.
|
||||
if (p == NULL)
|
||||
{
|
||||
p = PHGetTXPacket(pios_packet_handler);
|
||||
|
||||
// No packets available?
|
||||
if (p == NULL)
|
||||
{
|
||||
data->droppedPackets++;
|
||||
// Wait a bit for a packet to come available.
|
||||
vTaskDelay(5);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Initialize the packet.
|
||||
p->header.destination_id = data->destination_id;
|
||||
//p->header.type = PACKET_TYPE_ACKED_DATA;
|
||||
p->header.type = PACKET_TYPE_DATA;
|
||||
p->header.data_size = 0;
|
||||
}
|
||||
|
||||
// Receive data from the com port
|
||||
uint32_t cur_rx_bytes = PIOS_COM_ReceiveBuffer(PIOS_COM_TRANS_COM, p->data + p->header.data_size,
|
||||
PH_MAX_DATA - p->header.data_size, timeout);
|
||||
|
||||
// Do we have an data to send?
|
||||
p->header.data_size += cur_rx_bytes;
|
||||
if (p->header.data_size > 0) {
|
||||
|
||||
// Check how long since last update
|
||||
portTickType cur_sys_time = xTaskGetTickCount();
|
||||
|
||||
// Is this the start of a packet?
|
||||
if(packet_start_time == 0)
|
||||
packet_start_time = cur_sys_time;
|
||||
|
||||
// Just send the packet on wraparound
|
||||
bool send_packet = (cur_sys_time < packet_start_time);
|
||||
if (!send_packet)
|
||||
{
|
||||
portTickType dT = (cur_sys_time - packet_start_time) / portTICK_RATE_MS;
|
||||
if (dT > data->send_timeout)
|
||||
send_packet = true;
|
||||
else
|
||||
timeout = data->send_timeout - dT;
|
||||
}
|
||||
|
||||
// Also send the packet if the size is over the minimum.
|
||||
send_packet |= (p->header.data_size > data->min_packet_size);
|
||||
|
||||
// Should we send this packet?
|
||||
if (send_packet)
|
||||
{
|
||||
// Queue the packet for transmission.
|
||||
PHTransmitPacket(PIOS_PACKET_HANDLER, p);
|
||||
|
||||
// Reset the timeout
|
||||
timeout = MAX_PORT_DELAY;
|
||||
p = NULL;
|
||||
packet_start_time = 0;
|
||||
}
|
||||
}
|
||||
PIOS_WDG_UpdateFlag(PIOS_WDG_RADIORX);
|
||||
#endif
|
||||
uint8_t serial_data[1];
|
||||
uint16_t bytes_to_process = PIOS_COM_ReceiveBuffer(PIOS_COM_RADIO, serial_data, sizeof(serial_data), MAX_PORT_DELAY);
|
||||
if (bytes_to_process > 0)
|
||||
for (uint8_t i = 0; i < bytes_to_process; i++)
|
||||
if (UAVTalkRelayInputStream(data->outUAVTalkCon, serial_data[i]) == UAVTALK_STATE_ERROR)
|
||||
data->UAVTalkErrors++;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The PPM input task.
|
||||
* Radio rx task. Receive data from a com port and pass it on to the radio.
|
||||
*/
|
||||
static void ppmInputTask(void *parameters)
|
||||
static void radioTxTask(void *parameters)
|
||||
{
|
||||
PHPpmPacket ppm_packet;
|
||||
PHPacketHandle pph = (PHPacketHandle)&ppm_packet;
|
||||
|
||||
// Task loop
|
||||
while (1) {
|
||||
|
||||
uint32_t inputPort = PIOS_COM_TELEMETRY;
|
||||
#ifdef PIOS_INCLUDE_WDG
|
||||
// Update the watchdog timer.
|
||||
PIOS_WDG_UpdateFlag(PIOS_WDG_PPMINPUT);
|
||||
#endif /* PIOS_INCLUDE_WDG */
|
||||
|
||||
// Read the receiver.
|
||||
bool valid_input_detected = false;
|
||||
for (uint8_t i = 1; i <= PIOS_PPM_NUM_INPUTS; ++i)
|
||||
PIOS_WDG_UpdateFlag(PIOS_WDG_RADIOTX);
|
||||
#endif
|
||||
#if defined(PIOS_INCLUDE_USB)
|
||||
// Determine output port (USB takes priority over telemetry port)
|
||||
if (PIOS_USB_CheckAvailable(0) && PIOS_COM_TELEM_USB)
|
||||
inputPort = PIOS_COM_TELEM_USB;
|
||||
#endif /* PIOS_INCLUDE_USB */
|
||||
if(inputPort)
|
||||
{
|
||||
ppm_packet.channels[i - 1] = PIOS_RCVR_Read(PIOS_PPM_RECEIVER, i);
|
||||
if(ppm_packet.channels[i - 1] != PIOS_RCVR_TIMEOUT)
|
||||
valid_input_detected = true;
|
||||
uint8_t serial_data[1];
|
||||
uint16_t bytes_to_process = PIOS_COM_ReceiveBuffer(inputPort, serial_data, sizeof(serial_data), MAX_PORT_DELAY);
|
||||
if (bytes_to_process > 0)
|
||||
for (uint8_t i = 0; i < bytes_to_process; i++)
|
||||
ProcessInputStream(data->inUAVTalkCon, serial_data[i]);
|
||||
}
|
||||
|
||||
// Send the PPM packet if it's valid
|
||||
if (valid_input_detected)
|
||||
{
|
||||
// Set the GCSReceiver UAVO if we're connected to the FC.
|
||||
if (data->UAVTalkCon)
|
||||
{
|
||||
GCSReceiverData rcvr;
|
||||
|
||||
// Copy the receiver channels into the GCSReceiver object.
|
||||
for (uint8_t i = 0; i < GCSRECEIVER_CHANNEL_NUMELEM; ++i)
|
||||
rcvr.Channel[i] = ppm_packet.channels[i];
|
||||
|
||||
// Set the GCSReceiverData object.
|
||||
GCSReceiverSet(&rcvr);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Otherwise, send a PPM packet over the radio link.
|
||||
ppm_packet.header.destination_id = data->destination_id;
|
||||
ppm_packet.header.type = PACKET_TYPE_PPM;
|
||||
ppm_packet.header.data_size = PH_PPM_DATA_SIZE(&ppm_packet);
|
||||
PHTransmitPacket(PIOS_PACKET_HANDLER, pph);
|
||||
}
|
||||
}
|
||||
|
||||
// Delay until the next update period.
|
||||
vTaskDelay(PIOS_PPM_PACKET_UPDATE_PERIOD_MS / portTICK_RATE_MS);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Transmit data buffer to the com port.
|
||||
* \param[in] params The comm parameters.
|
||||
* \param[in] buf Data buffer to send
|
||||
* \param[in] length Length of buffer
|
||||
* \return -1 on failure
|
||||
* \return number of bytes transmitted on success
|
||||
*/
|
||||
static int32_t UAVTalkSend(UAVTalkComTaskParams *params, uint8_t *buf, int32_t length)
|
||||
static int32_t UAVTalkSendHandler(uint8_t *buf, int32_t length)
|
||||
{
|
||||
uint32_t outputPort = params->comPort;
|
||||
uint32_t outputPort = PIOS_COM_TELEMETRY;
|
||||
#if defined(PIOS_INCLUDE_USB)
|
||||
if (params->isGCS)
|
||||
{
|
||||
// Determine output port (USB takes priority over telemetry port)
|
||||
if (PIOS_USB_CheckAvailable(0) && PIOS_COM_USB_HID)
|
||||
outputPort = PIOS_COM_USB_HID;
|
||||
}
|
||||
// Determine output port (USB takes priority over telemetry port)
|
||||
if (PIOS_COM_TELEM_USB && PIOS_COM_Available(PIOS_COM_TELEM_USB))
|
||||
outputPort = PIOS_COM_TELEM_USB;
|
||||
#endif /* PIOS_INCLUDE_USB */
|
||||
if(outputPort)
|
||||
return PIOS_COM_SendBufferNonBlocking(outputPort, buf, length);
|
||||
@ -729,103 +301,126 @@ static int32_t UAVTalkSend(UAVTalkComTaskParams *params, uint8_t *buf, int32_t l
|
||||
* \return -1 on failure
|
||||
* \return number of bytes transmitted on success
|
||||
*/
|
||||
static int32_t UAVTalkSendHandler(uint8_t *buf, int32_t length)
|
||||
static int32_t RadioSendHandler(uint8_t *buf, int32_t length)
|
||||
{
|
||||
return UAVTalkSend(&(data->uavtalk_params), buf, length);
|
||||
}
|
||||
|
||||
/**
|
||||
* Transmit data buffer to the com port.
|
||||
* \param[in] buf Data buffer to send
|
||||
* \param[in] length Length of buffer
|
||||
* \return -1 on failure
|
||||
* \return number of bytes transmitted on success
|
||||
*/
|
||||
static int32_t GCSUAVTalkSendHandler(uint8_t *buf, int32_t length)
|
||||
{
|
||||
return UAVTalkSend(&(data->gcs_uavtalk_params), buf, length);
|
||||
}
|
||||
|
||||
/**
|
||||
* Receive a packet
|
||||
* \param[in] buf The received data buffer
|
||||
* \param[in] length Length of buffer
|
||||
*/
|
||||
static void transmitData(uint32_t outputPort, uint8_t *buf, uint8_t len, bool checkHid)
|
||||
{
|
||||
#if defined(PIOS_INCLUDE_USB)
|
||||
// See if USB is connected if requested.
|
||||
if(checkHid)
|
||||
// Determine output port (USB takes priority over telemetry port)
|
||||
if (PIOS_USB_CheckAvailable(0) && PIOS_COM_USB_HID)
|
||||
outputPort = PIOS_COM_USB_HID;
|
||||
#endif /* PIOS_INCLUDE_USB */
|
||||
if (!outputPort)
|
||||
return;
|
||||
|
||||
// Send the received data to the com port
|
||||
if (PIOS_COM_SendBuffer(outputPort, buf, len) != len)
|
||||
// Error on transmit
|
||||
data->comTxErrors++;
|
||||
}
|
||||
|
||||
/**
|
||||
* Receive a packet
|
||||
* \param[in] buf The received data buffer
|
||||
* \param[in] length Length of buffer
|
||||
*/
|
||||
static void receiveData(uint8_t *buf, uint8_t len, int8_t rssi, int8_t afc)
|
||||
{
|
||||
data->RSSI = rssi;
|
||||
|
||||
// Packet data should go to transparent com if it's configured,
|
||||
// or just send it through the UAVTalk link.
|
||||
if (PIOS_COM_TRANS_COM)
|
||||
transmitData(PIOS_COM_TRANS_COM, buf, len, false);
|
||||
else if (data->UAVTalkCon)
|
||||
UAVTalkSendBuf(data->UAVTalkCon, buf, len);
|
||||
uint32_t outputPort = PIOS_COM_RADIO;
|
||||
// Don't send any data unless the radio port is available.
|
||||
if(outputPort && PIOS_COM_Available(outputPort))
|
||||
return PIOS_COM_SendBuffer(outputPort, buf, length);
|
||||
else
|
||||
UAVTalkSendBuf(data->GCSUAVTalkCon, buf, len);
|
||||
// For some reason, if this function returns failure, it prevents saving settings.
|
||||
return length;
|
||||
}
|
||||
|
||||
static BufferedReadHandle BufferedReadInit(uint32_t com_port, uint16_t buffer_length)
|
||||
static void ProcessInputStream(UAVTalkConnection connectionHandle, uint8_t rxbyte)
|
||||
{
|
||||
BufferedReadHandle h = (BufferedReadHandle)pvPortMalloc(sizeof(ReadBuffer));
|
||||
if (!h)
|
||||
return NULL;
|
||||
// Keep reading until we receive a completed packet.
|
||||
UAVTalkRxState state = UAVTalkRelayInputStream(connectionHandle, rxbyte);
|
||||
UAVTalkConnectionData *connection = (UAVTalkConnectionData*)(connectionHandle);
|
||||
UAVTalkInputProcessor *iproc = &(connection->iproc);
|
||||
|
||||
h->com_port = com_port;
|
||||
h->buffer = (uint8_t*)pvPortMalloc(buffer_length);
|
||||
h->length = buffer_length;
|
||||
h->index = 0;
|
||||
h->data_length = 0;
|
||||
if (state == UAVTALK_STATE_COMPLETE)
|
||||
{
|
||||
// Is this a local UAVObject?
|
||||
// We only generate GcsReceiver ojects, we don't consume them.
|
||||
if ((iproc->obj != NULL) && (iproc->objId != GCSRECEIVER_OBJID))
|
||||
{
|
||||
// We treat the ObjectPersistence object differently
|
||||
if(iproc->objId == OBJECTPERSISTENCE_OBJID)
|
||||
{
|
||||
// Unpack object, if the instance does not exist it will be created!
|
||||
UAVObjUnpack(iproc->obj, iproc->instId, connection->rxBuffer);
|
||||
|
||||
if (h->buffer == NULL)
|
||||
return NULL;
|
||||
// Get the ObjectPersistence object.
|
||||
ObjectPersistenceData obj_per;
|
||||
ObjectPersistenceGet(&obj_per);
|
||||
|
||||
return h;
|
||||
}
|
||||
// Is this concerning or setting object?
|
||||
if (obj_per.ObjectID == OPLINKSETTINGS_OBJID)
|
||||
{
|
||||
// Queue up the ACK.
|
||||
queueEvent(data->uavtalkEventQueue, (void*)iproc->obj, iproc->instId, EV_SEND_ACK);
|
||||
|
||||
static bool BufferedRead(BufferedReadHandle h, uint8_t *value, uint32_t timeout_ms)
|
||||
{
|
||||
// Read some data if required.
|
||||
if(h->index == h->data_length)
|
||||
{
|
||||
uint32_t rx_bytes = PIOS_COM_ReceiveBuffer(h->com_port, h->buffer, h->length, timeout_ms);
|
||||
if (rx_bytes == 0)
|
||||
return false;
|
||||
h->index = 0;
|
||||
h->data_length = rx_bytes;
|
||||
}
|
||||
// Is this a save, load, or delete?
|
||||
bool success = true;
|
||||
switch (obj_per.Operation)
|
||||
{
|
||||
case OBJECTPERSISTENCE_OPERATION_LOAD:
|
||||
{
|
||||
#if defined(PIOS_INCLUDE_FLASH_EEPROM)
|
||||
// Load the settings.
|
||||
OPLinkSettingsData oplinkSettings;
|
||||
if (PIOS_EEPROM_Load((uint8_t*)&oplinkSettings, sizeof(OPLinkSettingsData)) == 0)
|
||||
OPLinkSettingsSet(&oplinkSettings);
|
||||
else
|
||||
success = false;
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
case OBJECTPERSISTENCE_OPERATION_SAVE:
|
||||
{
|
||||
#if defined(PIOS_INCLUDE_FLASH_EEPROM)
|
||||
// Save the settings.
|
||||
OPLinkSettingsData oplinkSettings;
|
||||
OPLinkSettingsGet(&oplinkSettings);
|
||||
int32_t ret = PIOS_EEPROM_Save((uint8_t*)&oplinkSettings, sizeof(OPLinkSettingsData));
|
||||
if (ret != 0)
|
||||
success = false;
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
case OBJECTPERSISTENCE_OPERATION_DELETE:
|
||||
{
|
||||
#if defined(PIOS_INCLUDE_FLASH_EEPROM)
|
||||
// Erase the settings.
|
||||
OPLinkSettingsData oplinkSettings;
|
||||
uint8_t *ptr = (uint8_t*)&oplinkSettings;
|
||||
memset(ptr, 0, sizeof(OPLinkSettingsData));
|
||||
int32_t ret = PIOS_EEPROM_Save(ptr, sizeof(OPLinkSettingsData));
|
||||
if (ret != 0)
|
||||
success = false;
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if (success == true)
|
||||
{
|
||||
obj_per.Operation = OBJECTPERSISTENCE_OPERATION_COMPLETED;
|
||||
ObjectPersistenceSet(&obj_per);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (iproc->type)
|
||||
{
|
||||
case UAVTALK_TYPE_OBJ:
|
||||
// Unpack object, if the instance does not exist it will be created!
|
||||
UAVObjUnpack(iproc->obj, iproc->instId, connection->rxBuffer);
|
||||
break;
|
||||
case UAVTALK_TYPE_OBJ_REQ:
|
||||
// Queue up an object send request.
|
||||
queueEvent(data->uavtalkEventQueue, (void*)iproc->obj, iproc->instId, EV_UPDATE_REQ);
|
||||
break;
|
||||
case UAVTALK_TYPE_OBJ_ACK:
|
||||
if (UAVObjUnpack(iproc->obj, iproc->instId, connection->rxBuffer) == 0)
|
||||
// Queue up an ACK
|
||||
queueEvent(data->uavtalkEventQueue, (void*)iproc->obj, iproc->instId, EV_SEND_ACK);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Return the next byte.
|
||||
*value = h->buffer[h->index++];
|
||||
return true;
|
||||
}
|
||||
} else if(state == UAVTALK_STATE_ERROR) {
|
||||
data->UAVTalkErrors++;
|
||||
|
||||
static void BufferedReadSetCom(BufferedReadHandle h, uint32_t com_port)
|
||||
{
|
||||
h->com_port = com_port;
|
||||
// Send a NACK if required.
|
||||
if((iproc->obj) && (iproc->type == UAVTALK_TYPE_OBJ_ACK))
|
||||
// Queue up a NACK
|
||||
queueEvent(data->uavtalkEventQueue, iproc->obj, iproc->instId, EV_SEND_NACK);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -844,95 +439,165 @@ static void queueEvent(xQueueHandle queue, void *obj, uint16_t instId, UAVObjEve
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the telemetry settings, called on startup.
|
||||
* FIXME: This should be in the TelemetrySettings object. But objects
|
||||
* have too much overhead yet. Also the telemetry has no any specific
|
||||
* settings, etc. Thus the HwSettings object which contains the
|
||||
* telemetry port speed is used for now.
|
||||
* Configure the output port based on a configuration event from the remote coordinator.
|
||||
* \param[in] com_port The com port to configure
|
||||
* \param[in] com_speed The com port speed
|
||||
*/
|
||||
static void configureComCallback(OPLinkSettingsOutputConnectionOptions com_port, OPLinkSettingsComSpeedOptions com_speed)
|
||||
{
|
||||
|
||||
// Get the settings.
|
||||
OPLinkSettingsData oplinkSettings;
|
||||
OPLinkSettingsGet(&oplinkSettings);
|
||||
|
||||
// Set the output telemetry port and speed.
|
||||
switch (com_port)
|
||||
{
|
||||
case OPLINKSETTINGS_OUTPUTCONNECTION_REMOTEHID:
|
||||
oplinkSettings.InputConnection = OPLINKSETTINGS_INPUTCONNECTION_HID;
|
||||
break;
|
||||
case OPLINKSETTINGS_OUTPUTCONNECTION_REMOTEVCP:
|
||||
oplinkSettings.InputConnection = OPLINKSETTINGS_INPUTCONNECTION_VCP;
|
||||
break;
|
||||
case OPLINKSETTINGS_OUTPUTCONNECTION_REMOTETELEMETRY:
|
||||
oplinkSettings.InputConnection = OPLINKSETTINGS_INPUTCONNECTION_TELEMETRY;
|
||||
break;
|
||||
case OPLINKSETTINGS_OUTPUTCONNECTION_REMOTEFLEXI:
|
||||
oplinkSettings.InputConnection = OPLINKSETTINGS_INPUTCONNECTION_FLEXI;
|
||||
break;
|
||||
case OPLINKSETTINGS_OUTPUTCONNECTION_TELEMETRY:
|
||||
oplinkSettings.InputConnection = OPLINKSETTINGS_INPUTCONNECTION_HID;
|
||||
break;
|
||||
case OPLINKSETTINGS_OUTPUTCONNECTION_FLEXI:
|
||||
oplinkSettings.InputConnection = OPLINKSETTINGS_INPUTCONNECTION_HID;
|
||||
break;
|
||||
}
|
||||
oplinkSettings.ComSpeed = com_speed;
|
||||
|
||||
// A non-coordinator modem should not set a remote telemetry connection.
|
||||
oplinkSettings.OutputConnection = OPLINKSETTINGS_OUTPUTCONNECTION_REMOTEHID;
|
||||
|
||||
// Update the OPLinkSettings object.
|
||||
OPLinkSettingsSet(&oplinkSettings);
|
||||
|
||||
// Perform the update.
|
||||
updateSettings();
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the oplink settings, called on startup.
|
||||
*/
|
||||
static void updateSettings()
|
||||
{
|
||||
|
||||
// Get the settings.
|
||||
PipXSettingsData pipxSettings;
|
||||
PipXSettingsGet(&pipxSettings);
|
||||
OPLinkSettingsData oplinkSettings;
|
||||
OPLinkSettingsGet(&oplinkSettings);
|
||||
|
||||
// Initialize the destination ID
|
||||
data->destination_id = pipxSettings.PairID ? pipxSettings.PairID : 0xffffffff;
|
||||
|
||||
if (PIOS_COM_TELEMETRY) {
|
||||
switch (pipxSettings.TelemetrySpeed) {
|
||||
case PIPXSETTINGS_TELEMETRYSPEED_2400:
|
||||
PIOS_COM_ChangeBaud(PIOS_COM_TELEMETRY, 2400);
|
||||
bool is_coordinator = (oplinkSettings.Coordinator == OPLINKSETTINGS_COORDINATOR_TRUE);
|
||||
if (is_coordinator)
|
||||
{
|
||||
// Set the remote com configuration parameters
|
||||
PIOS_RFM22B_SetRemoteComConfig(pios_rfm22b_id, oplinkSettings.OutputConnection, oplinkSettings.ComSpeed);
|
||||
|
||||
// Configure the RFM22B device as coordinator or not
|
||||
PIOS_RFM22B_SetCoordinator(pios_rfm22b_id, true);
|
||||
|
||||
// Set the frequencies.
|
||||
PIOS_RFM22B_SetFrequencyRange(pios_rfm22b_id, oplinkSettings.MinFrequency, oplinkSettings.MaxFrequency);
|
||||
|
||||
// Set the maximum radio RF power.
|
||||
switch (oplinkSettings.MaxRFPower)
|
||||
{
|
||||
case OPLINKSETTINGS_MAXRFPOWER_125:
|
||||
PIOS_RFM22B_SetTxPower(pios_rfm22b_id, RFM22_tx_pwr_txpow_0);
|
||||
break;
|
||||
case PIPXSETTINGS_TELEMETRYSPEED_4800:
|
||||
PIOS_COM_ChangeBaud(PIOS_COM_TELEMETRY, 4800);
|
||||
case OPLINKSETTINGS_MAXRFPOWER_16:
|
||||
PIOS_RFM22B_SetTxPower(pios_rfm22b_id, RFM22_tx_pwr_txpow_1);
|
||||
break;
|
||||
case PIPXSETTINGS_TELEMETRYSPEED_9600:
|
||||
PIOS_COM_ChangeBaud(PIOS_COM_TELEMETRY, 9600);
|
||||
case OPLINKSETTINGS_MAXRFPOWER_316:
|
||||
PIOS_RFM22B_SetTxPower(pios_rfm22b_id, RFM22_tx_pwr_txpow_2);
|
||||
break;
|
||||
case PIPXSETTINGS_TELEMETRYSPEED_19200:
|
||||
PIOS_COM_ChangeBaud(PIOS_COM_TELEMETRY, 19200);
|
||||
case OPLINKSETTINGS_MAXRFPOWER_63:
|
||||
PIOS_RFM22B_SetTxPower(pios_rfm22b_id, RFM22_tx_pwr_txpow_3);
|
||||
break;
|
||||
case PIPXSETTINGS_TELEMETRYSPEED_38400:
|
||||
PIOS_COM_ChangeBaud(PIOS_COM_TELEMETRY, 38400);
|
||||
case OPLINKSETTINGS_MAXRFPOWER_126:
|
||||
PIOS_RFM22B_SetTxPower(pios_rfm22b_id, RFM22_tx_pwr_txpow_4);
|
||||
break;
|
||||
case PIPXSETTINGS_TELEMETRYSPEED_57600:
|
||||
PIOS_COM_ChangeBaud(PIOS_COM_TELEMETRY, 57600);
|
||||
case OPLINKSETTINGS_MAXRFPOWER_25:
|
||||
PIOS_RFM22B_SetTxPower(pios_rfm22b_id, RFM22_tx_pwr_txpow_5);
|
||||
break;
|
||||
case PIPXSETTINGS_TELEMETRYSPEED_115200:
|
||||
PIOS_COM_ChangeBaud(PIOS_COM_TELEMETRY, 115200);
|
||||
case OPLINKSETTINGS_MAXRFPOWER_50:
|
||||
PIOS_RFM22B_SetTxPower(pios_rfm22b_id, RFM22_tx_pwr_txpow_6);
|
||||
break;
|
||||
case OPLINKSETTINGS_MAXRFPOWER_100:
|
||||
PIOS_RFM22B_SetTxPower(pios_rfm22b_id, RFM22_tx_pwr_txpow_7);
|
||||
break;
|
||||
}
|
||||
|
||||
// Set the radio destination ID.
|
||||
PIOS_RFM22B_SetDestinationId(pios_rfm22b_id, oplinkSettings.PairID);
|
||||
}
|
||||
if (PIOS_COM_FLEXI) {
|
||||
switch (pipxSettings.FlexiSpeed) {
|
||||
case PIPXSETTINGS_TELEMETRYSPEED_2400:
|
||||
PIOS_COM_ChangeBaud(PIOS_COM_FLEXI, 2400);
|
||||
break;
|
||||
case PIPXSETTINGS_TELEMETRYSPEED_4800:
|
||||
PIOS_COM_ChangeBaud(PIOS_COM_FLEXI, 4800);
|
||||
break;
|
||||
case PIPXSETTINGS_TELEMETRYSPEED_9600:
|
||||
PIOS_COM_ChangeBaud(PIOS_COM_FLEXI, 9600);
|
||||
break;
|
||||
case PIPXSETTINGS_TELEMETRYSPEED_19200:
|
||||
PIOS_COM_ChangeBaud(PIOS_COM_FLEXI, 19200);
|
||||
break;
|
||||
case PIPXSETTINGS_TELEMETRYSPEED_38400:
|
||||
PIOS_COM_ChangeBaud(PIOS_COM_FLEXI, 38400);
|
||||
break;
|
||||
case PIPXSETTINGS_TELEMETRYSPEED_57600:
|
||||
PIOS_COM_ChangeBaud(PIOS_COM_FLEXI, 57600);
|
||||
break;
|
||||
case PIPXSETTINGS_TELEMETRYSPEED_115200:
|
||||
PIOS_COM_ChangeBaud(PIOS_COM_FLEXI, 115200);
|
||||
break;
|
||||
}
|
||||
|
||||
// Determine what com ports we're using.
|
||||
switch (oplinkSettings.InputConnection)
|
||||
{
|
||||
case OPLINKSETTINGS_INPUTCONNECTION_VCP:
|
||||
PIOS_COM_TELEMETRY = PIOS_COM_TELEM_VCP;
|
||||
break;
|
||||
case OPLINKSETTINGS_INPUTCONNECTION_TELEMETRY:
|
||||
PIOS_COM_TELEMETRY = PIOS_COM_TELEM_UART_TELEM;
|
||||
break;
|
||||
case OPLINKSETTINGS_INPUTCONNECTION_FLEXI:
|
||||
PIOS_COM_TELEMETRY = PIOS_COM_TELEM_UART_FLEXI;
|
||||
break;
|
||||
default:
|
||||
PIOS_COM_TELEMETRY = 0;
|
||||
break;
|
||||
}
|
||||
if (PIOS_COM_VCP) {
|
||||
switch (pipxSettings.VCPSpeed) {
|
||||
case PIPXSETTINGS_TELEMETRYSPEED_2400:
|
||||
PIOS_COM_ChangeBaud(PIOS_COM_VCP, 2400);
|
||||
break;
|
||||
case PIPXSETTINGS_TELEMETRYSPEED_4800:
|
||||
PIOS_COM_ChangeBaud(PIOS_COM_VCP, 4800);
|
||||
break;
|
||||
case PIPXSETTINGS_TELEMETRYSPEED_9600:
|
||||
PIOS_COM_ChangeBaud(PIOS_COM_VCP, 9600);
|
||||
break;
|
||||
case PIPXSETTINGS_TELEMETRYSPEED_19200:
|
||||
PIOS_COM_ChangeBaud(PIOS_COM_VCP, 19200);
|
||||
break;
|
||||
case PIPXSETTINGS_TELEMETRYSPEED_38400:
|
||||
PIOS_COM_ChangeBaud(PIOS_COM_VCP, 38400);
|
||||
break;
|
||||
case PIPXSETTINGS_TELEMETRYSPEED_57600:
|
||||
PIOS_COM_ChangeBaud(PIOS_COM_VCP, 57600);
|
||||
break;
|
||||
case PIPXSETTINGS_TELEMETRYSPEED_115200:
|
||||
PIOS_COM_ChangeBaud(PIOS_COM_VCP, 115200);
|
||||
break;
|
||||
}
|
||||
|
||||
switch (oplinkSettings.OutputConnection)
|
||||
{
|
||||
case OPLINKSETTINGS_OUTPUTCONNECTION_FLEXI:
|
||||
PIOS_COM_RADIO = PIOS_COM_TELEM_UART_FLEXI;
|
||||
break;
|
||||
case OPLINKSETTINGS_OUTPUTCONNECTION_TELEMETRY:
|
||||
PIOS_COM_RADIO = PIOS_COM_TELEM_UART_TELEM;
|
||||
break;
|
||||
default:
|
||||
PIOS_COM_RADIO = PIOS_COM_RFM22B;
|
||||
break;
|
||||
}
|
||||
|
||||
// Configure the com port speeds.
|
||||
switch (oplinkSettings.ComSpeed) {
|
||||
case OPLINKSETTINGS_COMSPEED_2400:
|
||||
if (is_coordinator && PIOS_COM_RADIO) PIOS_COM_ChangeBaud(PIOS_COM_RADIO, 2400);
|
||||
if (PIOS_COM_TELEMETRY) PIOS_COM_ChangeBaud(PIOS_COM_TELEMETRY, 2400);
|
||||
break;
|
||||
case OPLINKSETTINGS_COMSPEED_4800:
|
||||
if (is_coordinator && PIOS_COM_RADIO) PIOS_COM_ChangeBaud(PIOS_COM_RADIO, 4800);
|
||||
if (PIOS_COM_TELEMETRY) PIOS_COM_ChangeBaud(PIOS_COM_TELEMETRY, 4800);
|
||||
break;
|
||||
case OPLINKSETTINGS_COMSPEED_9600:
|
||||
if (is_coordinator && PIOS_COM_RADIO) PIOS_COM_ChangeBaud(PIOS_COM_RADIO, 9600);
|
||||
if (PIOS_COM_TELEMETRY) PIOS_COM_ChangeBaud(PIOS_COM_TELEMETRY, 9600);
|
||||
break;
|
||||
case OPLINKSETTINGS_COMSPEED_19200:
|
||||
if (is_coordinator && PIOS_COM_RADIO) PIOS_COM_ChangeBaud(PIOS_COM_RADIO, 19200);
|
||||
if (PIOS_COM_TELEMETRY) PIOS_COM_ChangeBaud(PIOS_COM_TELEMETRY, 19200);
|
||||
break;
|
||||
case OPLINKSETTINGS_COMSPEED_38400:
|
||||
if (is_coordinator && PIOS_COM_RADIO) PIOS_COM_ChangeBaud(PIOS_COM_RADIO, 38400);
|
||||
if (PIOS_COM_TELEMETRY) PIOS_COM_ChangeBaud(PIOS_COM_TELEMETRY, 38400);
|
||||
break;
|
||||
case OPLINKSETTINGS_COMSPEED_57600:
|
||||
if (is_coordinator && PIOS_COM_RADIO) PIOS_COM_ChangeBaud(PIOS_COM_RADIO, 57600);
|
||||
if (PIOS_COM_TELEMETRY) PIOS_COM_ChangeBaud(PIOS_COM_TELEMETRY, 57600);
|
||||
break;
|
||||
case OPLINKSETTINGS_COMSPEED_115200:
|
||||
if (is_coordinator && PIOS_COM_RADIO) PIOS_COM_ChangeBaud(PIOS_COM_RADIO, 115200);
|
||||
if (PIOS_COM_TELEMETRY) PIOS_COM_ChangeBaud(PIOS_COM_TELEMETRY, 115200);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -79,6 +79,7 @@ uint8_t max_axislock_rate = 0;
|
||||
float weak_leveling_kp = 0;
|
||||
uint8_t weak_leveling_max = 0;
|
||||
bool lowThrottleZeroIntegral;
|
||||
bool lowThrottleZeroAxis[MAX_AXES];
|
||||
float vbar_decay = 0.991f;
|
||||
struct pid pids[PID_MAX];
|
||||
|
||||
@ -357,6 +358,18 @@ static void stabilizationTask(void* parameters)
|
||||
actuatorDesired.UpdateTime = dT * 1000;
|
||||
actuatorDesired.Throttle = stabDesired.Throttle;
|
||||
|
||||
// Suppress desired output while disarmed or throttle low, for configured axis
|
||||
if (flightStatus.Armed != FLIGHTSTATUS_ARMED_ARMED || stabDesired.Throttle < 0) {
|
||||
if (lowThrottleZeroAxis[ROLL])
|
||||
actuatorDesired.Roll = 0.0f;
|
||||
|
||||
if (lowThrottleZeroAxis[PITCH])
|
||||
actuatorDesired.Pitch = 0.0f;
|
||||
|
||||
if (lowThrottleZeroAxis[YAW])
|
||||
actuatorDesired.Yaw = 0.0f;
|
||||
}
|
||||
|
||||
if(PARSE_FLIGHT_MODE(flightStatus.FlightMode) != FLIGHTMODE_MANUAL) {
|
||||
ActuatorDesiredSet(&actuatorDesired);
|
||||
} else {
|
||||
@ -460,7 +473,12 @@ static void SettingsUpdatedCb(UAVObjEvent * ev)
|
||||
|
||||
// Whether to zero the PID integrals while throttle is low
|
||||
lowThrottleZeroIntegral = settings.LowThrottleZeroIntegral == STABILIZATIONSETTINGS_LOWTHROTTLEZEROINTEGRAL_TRUE;
|
||||
|
||||
|
||||
// Whether to suppress (zero) the StabilizationDesired output for each axis while disarmed or throttle is low
|
||||
lowThrottleZeroAxis[ROLL] = settings.LowThrottleZeroAxis[STABILIZATIONSETTINGS_LOWTHROTTLEZEROAXIS_ROLL] == STABILIZATIONSETTINGS_LOWTHROTTLEZEROAXIS_TRUE;
|
||||
lowThrottleZeroAxis[PITCH] = settings.LowThrottleZeroAxis[STABILIZATIONSETTINGS_LOWTHROTTLEZEROAXIS_PITCH] == STABILIZATIONSETTINGS_LOWTHROTTLEZEROAXIS_TRUE;
|
||||
lowThrottleZeroAxis[YAW] = settings.LowThrottleZeroAxis[STABILIZATIONSETTINGS_LOWTHROTTLEZEROAXIS_YAW] == STABILIZATIONSETTINGS_LOWTHROTTLEZEROAXIS_TRUE;
|
||||
|
||||
// The dT has some jitter iteration to iteration that we don't want to
|
||||
// make thie result unpredictable. Still, it's nicer to specify the constant
|
||||
// based on a time (in ms) rather than a fixed multiplier. The error between
|
||||
|
@ -35,10 +35,6 @@
|
||||
#include "flighttelemetrystats.h"
|
||||
#include "gcstelemetrystats.h"
|
||||
#include "hwsettings.h"
|
||||
#if defined(PIOS_PACKET_HANDLER)
|
||||
#include "pipxstatus.h"
|
||||
#include "packet_handler.h"
|
||||
#endif
|
||||
|
||||
// Private constants
|
||||
#define MAX_QUEUE_SIZE TELEM_QUEUE_SIZE
|
||||
@ -78,16 +74,12 @@ static void telemetryRxTask(void *parameters);
|
||||
static int32_t transmitData(uint8_t * data, int32_t length);
|
||||
static void registerObject(UAVObjHandle obj);
|
||||
static void updateObject(UAVObjHandle obj, int32_t eventType);
|
||||
static int32_t addObject(UAVObjHandle obj);
|
||||
static int32_t setUpdatePeriod(UAVObjHandle obj, int32_t updatePeriodMs);
|
||||
static void processObjEvent(UAVObjEvent * ev);
|
||||
static void updateTelemetryStats();
|
||||
static void gcsTelemetryStatsUpdated();
|
||||
static void updateSettings();
|
||||
static uint32_t getComPort();
|
||||
#ifdef PIOS_PACKET_HANDLER
|
||||
static void receivePacketData(uint8_t *buf, uint8_t len, int8_t rssi, int8_t afc);
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Initialise the telemetry module
|
||||
@ -101,13 +93,6 @@ int32_t TelemetryStart(void)
|
||||
|
||||
// Listen to objects of interest
|
||||
GCSTelemetryStatsConnectQueue(priorityQueue);
|
||||
|
||||
// Register to receive data from the radio packet handler.
|
||||
// This must be after the radio module is initialized.
|
||||
#ifdef PIOS_PACKET_HANDLER
|
||||
if (PIOS_PACKET_HANDLER)
|
||||
PHRegisterDataHandler(PIOS_PACKET_HANDLER, receivePacketData);
|
||||
#endif
|
||||
|
||||
// Start telemetry tasks
|
||||
xTaskCreate(telemetryTxTask, (signed char *)"TelTx", STACK_SIZE_BYTES/4, NULL, TASK_PRIORITY_TX, &telemetryTxTaskHandle);
|
||||
@ -169,11 +154,31 @@ MODULE_INITCALL(TelemetryInitialize, TelemetryStart)
|
||||
*/
|
||||
static void registerObject(UAVObjHandle obj)
|
||||
{
|
||||
// Setup object for periodic updates
|
||||
addObject(obj);
|
||||
if (UAVObjIsMetaobject(obj)) {
|
||||
/* Only connect change notifications for meta objects. No periodic updates */
|
||||
UAVObjConnectQueue(obj, priorityQueue, EV_MASK_ALL_UPDATES);
|
||||
return;
|
||||
} else {
|
||||
UAVObjMetadata metadata;
|
||||
UAVObjUpdateMode updateMode;
|
||||
UAVObjGetMetadata(obj, &metadata);
|
||||
updateMode = UAVObjGetTelemetryUpdateMode(&metadata);
|
||||
|
||||
// Setup object for telemetry updates
|
||||
updateObject(obj, EV_NONE);
|
||||
/* Only create a periodic event for objects that are periodic */
|
||||
if ((updateMode == UPDATEMODE_PERIODIC) ||
|
||||
(updateMode == UPDATEMODE_THROTTLED)) {
|
||||
// Setup object for periodic updates
|
||||
UAVObjEvent ev = {
|
||||
.obj = obj,
|
||||
.instId = UAVOBJ_ALL_INSTANCES,
|
||||
.event = EV_UPDATED_PERIODIC,
|
||||
};
|
||||
EventPeriodicQueueCreate(&ev, queue, 0);
|
||||
}
|
||||
|
||||
// Setup object for telemetry updates
|
||||
updateObject(obj, EV_NONE);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -186,30 +191,35 @@ static void updateObject(UAVObjHandle obj, int32_t eventType)
|
||||
UAVObjUpdateMode updateMode;
|
||||
int32_t eventMask;
|
||||
|
||||
if (UAVObjIsMetaobject(obj)) {
|
||||
/* This function updates the periodic updates for the object.
|
||||
* Meta Objects cannot have periodic updates.
|
||||
*/
|
||||
PIOS_Assert(false);
|
||||
return;
|
||||
}
|
||||
|
||||
// Get metadata
|
||||
UAVObjGetMetadata(obj, &metadata);
|
||||
updateMode = UAVObjGetTelemetryUpdateMode(&metadata);
|
||||
|
||||
// Setup object depending on update mode
|
||||
if (updateMode == UPDATEMODE_PERIODIC) {
|
||||
switch (updateMode) {
|
||||
case UPDATEMODE_PERIODIC:
|
||||
// Set update period
|
||||
setUpdatePeriod(obj, metadata.telemetryUpdatePeriod);
|
||||
// Connect queue
|
||||
eventMask = EV_UPDATED_PERIODIC | EV_UPDATED_MANUAL | EV_UPDATE_REQ;
|
||||
if (UAVObjIsMetaobject(obj)) {
|
||||
eventMask |= EV_UNPACKED; // we also need to act on remote updates (unpack events)
|
||||
}
|
||||
UAVObjConnectQueue(obj, priorityQueue, eventMask);
|
||||
} else if (updateMode == UPDATEMODE_ONCHANGE) {
|
||||
break;
|
||||
case UPDATEMODE_ONCHANGE:
|
||||
// Set update period
|
||||
setUpdatePeriod(obj, 0);
|
||||
// Connect queue
|
||||
eventMask = EV_UPDATED | EV_UPDATED_MANUAL | EV_UPDATE_REQ;
|
||||
if (UAVObjIsMetaobject(obj)) {
|
||||
eventMask |= EV_UNPACKED; // we also need to act on remote updates (unpack events)
|
||||
}
|
||||
UAVObjConnectQueue(obj, priorityQueue, eventMask);
|
||||
} else if (updateMode == UPDATEMODE_THROTTLED) {
|
||||
break;
|
||||
case UPDATEMODE_THROTTLED:
|
||||
if ((eventType == EV_UPDATED_PERIODIC) || (eventType == EV_NONE)) {
|
||||
// If we received a periodic update, we can change back to update on change
|
||||
eventMask = EV_UPDATED | EV_UPDATED_MANUAL | EV_UPDATE_REQ;
|
||||
@ -220,19 +230,15 @@ static void updateObject(UAVObjHandle obj, int32_t eventType)
|
||||
// Otherwise, we just received an object update, so switch to periodic for the timeout period to prevent more updates
|
||||
eventMask = EV_UPDATED_PERIODIC | EV_UPDATED_MANUAL | EV_UPDATE_REQ;
|
||||
}
|
||||
if (UAVObjIsMetaobject(obj)) {
|
||||
eventMask |= EV_UNPACKED; // we also need to act on remote updates (unpack events)
|
||||
}
|
||||
UAVObjConnectQueue(obj, priorityQueue, eventMask);
|
||||
} else if (updateMode == UPDATEMODE_MANUAL) {
|
||||
break;
|
||||
case UPDATEMODE_MANUAL:
|
||||
// Set update period
|
||||
setUpdatePeriod(obj, 0);
|
||||
// Connect queue
|
||||
eventMask = EV_UPDATED_MANUAL | EV_UPDATE_REQ;
|
||||
if (UAVObjIsMetaobject(obj)) {
|
||||
eventMask |= EV_UNPACKED; // we also need to act on remote updates (unpack events)
|
||||
}
|
||||
UAVObjConnectQueue(obj, priorityQueue, eventMask);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -261,11 +267,6 @@ static void processObjEvent(UAVObjEvent * ev)
|
||||
retries = 0;
|
||||
success = -1;
|
||||
if (ev->event == EV_UPDATED || ev->event == EV_UPDATED_MANUAL || ((ev->event == EV_UPDATED_PERIODIC) && (updateMode != UPDATEMODE_THROTTLED))) {
|
||||
#ifdef PIOS_PACKET_HANDLER
|
||||
// Don't send PipXStatus objects over the radio link.
|
||||
if (PIOS_PACKET_HANDLER && (ev->obj == PipXStatusHandle()) && (getComPort() == 0))
|
||||
return;
|
||||
#endif
|
||||
// Send update to GCS (with retries)
|
||||
while (retries < MAX_RETRIES && success == -1) {
|
||||
success = UAVTalkSendObject(uavTalkCon, ev->obj, ev->instId, UAVObjGetTelemetryAcked(&metadata), REQ_TIMEOUT_MS); // call blocks until ack is received or timeout
|
||||
@ -291,11 +292,11 @@ static void processObjEvent(UAVObjEvent * ev)
|
||||
// If this is a metaobject then make necessary telemetry updates
|
||||
if (UAVObjIsMetaobject(ev->obj)) {
|
||||
updateObject(UAVObjGetLinkedObj(ev->obj), EV_NONE); // linked object will be the actual object the metadata are for
|
||||
}
|
||||
|
||||
if((updateMode == UPDATEMODE_THROTTLED) && !UAVObjIsMetaobject(ev->obj)) {
|
||||
// If this is UPDATEMODE_THROTTLED, the event mask changes on every event.
|
||||
updateObject(ev->obj, ev->event);
|
||||
} else {
|
||||
if (updateMode == UPDATEMODE_THROTTLED) {
|
||||
// If this is UPDATEMODE_THROTTLED, the event mask changes on every event.
|
||||
updateObject(ev->obj, ev->event);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -374,34 +375,12 @@ static int32_t transmitData(uint8_t * data, int32_t length)
|
||||
{
|
||||
uint32_t outputPort = getComPort();
|
||||
|
||||
if (outputPort) {
|
||||
if (outputPort)
|
||||
return PIOS_COM_SendBuffer(outputPort, data, length);
|
||||
}
|
||||
#ifdef PIOS_PACKET_HANDLER
|
||||
if (PIOS_PACKET_HANDLER)
|
||||
if (PHTransmitData(PIOS_PACKET_HANDLER, data, length))
|
||||
return length;
|
||||
#endif
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Setup object for periodic updates.
|
||||
* \param[in] obj The object to update
|
||||
* \return 0 Success
|
||||
* \return -1 Failure
|
||||
*/
|
||||
static int32_t addObject(UAVObjHandle obj)
|
||||
{
|
||||
UAVObjEvent ev;
|
||||
|
||||
// Add object for periodic updates
|
||||
ev.obj = obj;
|
||||
ev.instId = UAVOBJ_ALL_INSTANCES;
|
||||
ev.event = EV_UPDATED_PERIODIC;
|
||||
return EventPeriodicQueueCreate(&ev, queue, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set update period of object (it must be already setup for periodic updates)
|
||||
* \param[in] obj The object to update
|
||||
@ -569,30 +548,20 @@ static void updateSettings()
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine input/output com port (USB takes priority over telemetry port)
|
||||
* Determine input/output com port as highest priority available
|
||||
*/
|
||||
static uint32_t getComPort() {
|
||||
#if defined(PIOS_INCLUDE_USB)
|
||||
if (PIOS_USB_CheckAvailable(0) && PIOS_COM_TELEM_USB)
|
||||
if ( PIOS_COM_Available(PIOS_COM_TELEM_USB) )
|
||||
return PIOS_COM_TELEM_USB;
|
||||
else
|
||||
#endif /* PIOS_INCLUDE_USB */
|
||||
return telemetryPort;
|
||||
if ( PIOS_COM_Available(telemetryPort) )
|
||||
return telemetryPort;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef PIOS_PACKET_HANDLER
|
||||
/**
|
||||
* Receive a packet
|
||||
* \param[in] buf The received data buffer
|
||||
* \param[in] length Length of buffer
|
||||
*/
|
||||
static void receivePacketData(uint8_t *buf, uint8_t len, int8_t rssi, int8_t afc)
|
||||
{
|
||||
for (uint8_t i = 0; i < len; ++i)
|
||||
UAVTalkProcessInputStream(uavTalkCon, buf[i]);
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @}
|
||||
* @}
|
||||
|
@ -41,6 +41,7 @@ struct pios_com_driver {
|
||||
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);
|
||||
bool (*available)(uint32_t id);
|
||||
};
|
||||
|
||||
/* Public Functions */
|
||||
@ -55,7 +56,7 @@ 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);
|
||||
extern bool PIOS_COM_Available(uint32_t com_id);
|
||||
|
||||
#endif /* PIOS_COM_H */
|
||||
|
||||
|
@ -497,21 +497,24 @@ uint16_t PIOS_COM_ReceiveBuffer(uint32_t com_id, uint8_t * buf, uint16_t buf_len
|
||||
}
|
||||
|
||||
/**
|
||||
* 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)
|
||||
* Query if a com port is available for use. That can be
|
||||
* used to check a link is established even if the device
|
||||
* is valid.
|
||||
*/
|
||||
bool PIOS_COM_Available(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);
|
||||
return false;
|
||||
}
|
||||
|
||||
PIOS_Assert(com_dev->has_rx);
|
||||
return (fifoBuf_getUsed(&com_dev->rx));
|
||||
// If a driver does not provide a query method assume always
|
||||
// available if valid
|
||||
if (com_dev->driver->available == NULL)
|
||||
return true;
|
||||
|
||||
return (com_dev->driver->available)(com_dev->lower_id);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -41,6 +41,7 @@ struct pios_com_driver {
|
||||
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);
|
||||
bool (*available)(uint32_t id);
|
||||
};
|
||||
|
||||
/* Public Functions */
|
||||
@ -55,7 +56,7 @@ 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);
|
||||
extern bool PIOS_COM_Available(uint32_t com_id);
|
||||
|
||||
#endif /* PIOS_COM_H */
|
||||
|
||||
|
@ -497,21 +497,24 @@ uint16_t PIOS_COM_ReceiveBuffer(uint32_t com_id, uint8_t * buf, uint16_t buf_len
|
||||
}
|
||||
|
||||
/**
|
||||
* 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)
|
||||
* Query if a com port is available for use. That can be
|
||||
* used to check a link is established even if the device
|
||||
* is valid.
|
||||
*/
|
||||
bool PIOS_COM_Available(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);
|
||||
return false;
|
||||
}
|
||||
|
||||
PIOS_Assert(com_dev->has_rx);
|
||||
return (fifoBuf_getUsed(&com_dev->rx));
|
||||
// If a driver does not provide a query method assume always
|
||||
// available if valid
|
||||
if (com_dev->driver->available == NULL)
|
||||
return true;
|
||||
|
||||
return (com_dev->driver->available)(com_dev->lower_id);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -71,12 +71,10 @@ TIM4 | RC In 1 | Servo 3 | Servo 2 | Servo 1
|
||||
//------------------------
|
||||
#define PIOS_WATCHDOG_TIMEOUT 500
|
||||
#define PIOS_WDG_REGISTER BKP_DR4
|
||||
#define PIOS_WDG_COMGCS 0x0001
|
||||
#define PIOS_WDG_COMUAVTALK 0x0002
|
||||
#define PIOS_WDG_RADIORECEIVE 0x0004
|
||||
#define PIOS_WDG_SENDDATA 0x0008
|
||||
#define PIOS_WDG_TRANSCOMM 0x0008
|
||||
#define PIOS_WDG_PPMINPUT 0x0010
|
||||
#define PIOS_WDG_TELEMETRY 0x0001
|
||||
#define PIOS_WDG_RADIORX 0x0002
|
||||
#define PIOS_WDG_RADIOTX 0x0004
|
||||
#define PIOS_WDG_RFM22B 0x0008
|
||||
|
||||
//------------------------
|
||||
// TELEMETRY
|
||||
@ -90,6 +88,12 @@ TIM4 | RC In 1 | Servo 3 | Servo 2 | Servo 1
|
||||
#define PIOS_LED_LINK 1
|
||||
#define PIOS_LED_RX 2
|
||||
#define PIOS_LED_TX 3
|
||||
#ifdef PIOS_RFM22B_DEBUG_ON_TELEM
|
||||
#define PIOS_LED_D1 4
|
||||
#define PIOS_LED_D2 5
|
||||
#define PIOS_LED_D3 6
|
||||
#define PIOS_LED_D4 7
|
||||
#endif
|
||||
|
||||
#define PIOS_LED_HEARTBEAT PIOS_LED_USB
|
||||
#define PIOS_LED_ALARM PIOS_LED_TX
|
||||
@ -110,6 +114,24 @@ TIM4 | RC In 1 | Servo 3 | Servo 2 | Servo 1
|
||||
#define TX_LED_OFF PIOS_LED_Off(PIOS_LED_TX)
|
||||
#define TX_LED_TOGGLE PIOS_LED_Toggle(PIOS_LED_TX)
|
||||
|
||||
#ifdef PIOS_RFM22B_DEBUG_ON_TELEM
|
||||
#define D1_LED_ON PIOS_LED_On(PIOS_LED_D1)
|
||||
#define D1_LED_OFF PIOS_LED_Off(PIOS_LED_D1)
|
||||
#define D1_LED_TOGGLE PIOS_LED_Toggle(PIOS_LED_D1)
|
||||
|
||||
#define D2_LED_ON PIOS_LED_On(PIOS_LED_D2)
|
||||
#define D2_LED_OFF PIOS_LED_Off(PIOS_LED_D2)
|
||||
#define D2_LED_TOGGLE PIOS_LED_Toggle(PIOS_LED_D2)
|
||||
|
||||
#define D3_LED_ON PIOS_LED_On(PIOS_LED_D3)
|
||||
#define D3_LED_OFF PIOS_LED_Off(PIOS_LED_D3)
|
||||
#define D3_LED_TOGGLE PIOS_LED_Toggle(PIOS_LED_D3)
|
||||
|
||||
#define D4_LED_ON PIOS_LED_On(PIOS_LED_D4)
|
||||
#define D4_LED_OFF PIOS_LED_Off(PIOS_LED_D4)
|
||||
#define D4_LED_TOGGLE PIOS_LED_Toggle(PIOS_LED_D4)
|
||||
#endif
|
||||
|
||||
//-------------------------
|
||||
// System Settings
|
||||
//-------------------------
|
||||
@ -151,29 +173,24 @@ extern uint32_t pios_i2c_flexi_adapter_id;
|
||||
#define PIOS_COM_MAX_DEVS 5
|
||||
|
||||
extern uint32_t pios_com_telem_usb_id;
|
||||
extern uint32_t pios_com_telem_vcp_id;
|
||||
extern uint32_t pios_com_telem_uart_telem_id;
|
||||
extern uint32_t pios_com_telem_uart_flexi_id;
|
||||
extern uint32_t pios_com_telemetry_id;
|
||||
extern uint32_t pios_com_flexi_id;
|
||||
extern uint32_t pios_com_vcp_id;
|
||||
extern uint32_t pios_com_uavtalk_com_id;
|
||||
extern uint32_t pios_com_gcs_com_id;
|
||||
extern uint32_t pios_com_trans_com_id;
|
||||
extern uint32_t pios_com_debug_id;
|
||||
extern uint32_t pios_com_rfm22b_id;
|
||||
extern uint32_t pios_com_radio_id;
|
||||
extern uint32_t pios_ppm_rcvr_id;
|
||||
#define PIOS_COM_USB_HID (pios_com_telem_usb_id)
|
||||
#define PIOS_COM_TELEM_USB (pios_com_telem_usb_id)
|
||||
#define PIOS_COM_TELEM_VCP (pios_com_telem_vcp_id)
|
||||
#define PIOS_COM_TELEM_UART_FLEXI (pios_com_telem_uart_flexi_id)
|
||||
#define PIOS_COM_TELEM_UART_TELEM (pios_com_telem_uart_telem_id)
|
||||
#define PIOS_COM_TELEMETRY (pios_com_telemetry_id)
|
||||
#define PIOS_COM_FLEXI (pios_com_flexi_id)
|
||||
#define PIOS_COM_VCP (pios_com_vcp_id)
|
||||
#define PIOS_COM_UAVTALK (pios_com_uavtalk_com_id)
|
||||
#define PIOS_COM_GCS (pios_com_gcs_com_id)
|
||||
#define PIOS_COM_TRANS_COM (pios_com_trans_com_id)
|
||||
#define PIOS_COM_DEBUG (pios_com_debug_id)
|
||||
#define PIOS_COM_RADIO (pios_com_rfm22b_id)
|
||||
#define PIOS_COM_TELEM_USB PIOS_COM_USB_HID
|
||||
#define PIOS_COM_RFM22B (pios_com_rfm22b_id)
|
||||
#define PIOS_COM_RADIO (pios_com_radio_id)
|
||||
#define PIOS_PPM_RECEIVER (pios_ppm_rcvr_id)
|
||||
|
||||
#define DEBUG_LEVEL 2
|
||||
#if DEBUG_LEVEL > 0
|
||||
#if DEBUG_LEVEL > 1000
|
||||
#define DEBUG_PRINTF(level, ...) {if(level <= DEBUG_LEVEL && PIOS_COM_DEBUG > 0) { PIOS_COM_SendFormattedStringNonBlocking(PIOS_COM_DEBUG, __VA_ARGS__); }}
|
||||
#else
|
||||
#define DEBUG_PRINTF(...)
|
||||
@ -230,8 +247,7 @@ extern uint32_t pios_ppm_rcvr_id;
|
||||
// Receiver PPM input
|
||||
//-------------------------
|
||||
#define PIOS_PPM_MAX_DEVS 1
|
||||
#define PIOS_PPM_NUM_INPUTS 12
|
||||
#define PIOS_PPM_PACKET_UPDATE_PERIOD_MS 25
|
||||
#define PIOS_PPM_NUM_INPUTS 8
|
||||
|
||||
//-------------------------
|
||||
// Servo outputs
|
||||
@ -268,13 +284,8 @@ extern uint32_t pios_ppm_rcvr_id;
|
||||
//-------------------------
|
||||
|
||||
#if defined(PIOS_INCLUDE_RFM22B)
|
||||
#define PIOS_COM_RFM22B_RF_RX_BUF_LEN 256
|
||||
#define PIOS_COM_RFM22B_RF_TX_BUF_LEN 256
|
||||
extern uint32_t pios_com_rfm22b_id;
|
||||
#define PIOS_COM_RADIO (pios_com_rfm22b_id)
|
||||
extern uint32_t pios_spi_rfm22b_id;
|
||||
#define PIOS_RFM22_SPI_PORT (pios_spi_rfm22b_id)
|
||||
#define RFM22_EXT_INT_USE
|
||||
extern uint32_t pios_rfm22b_id;
|
||||
#endif /* PIOS_INCLUDE_RFM22B */
|
||||
|
||||
|
@ -33,7 +33,7 @@
|
||||
|
||||
#if defined(PIOS_INCLUDE_DEBUG_CONSOLE)
|
||||
#define DEBUG_LEVEL 0
|
||||
#define DEBUG_PRINTF(level, ...) {if(level <= DEBUG_LEVEL && pios_com_aux_id > 0) { PIOS_COM_SendFormattedStringNonBlocking(pios_com_aux_id, __VA_ARGS__); }}
|
||||
#define DEBUG_PRINTF(level, ...) {if(level <= DEBUG_LEVEL && pios_com_debug_id > 0) { PIOS_COM_SendFormattedStringNonBlocking(pios_com_debug_id, __VA_ARGS__); }}
|
||||
#else
|
||||
#define DEBUG_PRINTF(level, ...)
|
||||
#endif /* PIOS_INCLUDE_DEBUG_CONSOLE */
|
||||
@ -143,10 +143,7 @@ extern uint32_t pios_com_debug_id;
|
||||
#endif /* PIOS_INCLUDE_DEBUG_CONSOLE */
|
||||
|
||||
#if defined(PIOS_INCLUDE_RFM22B)
|
||||
#define PIOS_COM_RFM22B_RF_RX_BUF_LEN 512
|
||||
#define PIOS_COM_RFM22B_RF_TX_BUF_LEN 512
|
||||
extern uint32_t pios_com_rfm22b_id;
|
||||
#define PIOS_COM_RADIO (pios_com_rfm22b_id)
|
||||
extern uint32_t pios_rfm22b_id;
|
||||
extern uint32_t pios_spi_telem_flash_id;
|
||||
#define PIOS_RFM22_SPI_PORT (pios_spi_telem_flash_id)
|
||||
#endif /* PIOS_INCLUDE_RFM22B */
|
||||
@ -217,6 +214,7 @@ extern uint32_t pios_packet_handler;
|
||||
#define PIOS_RCVR_MAX_DEVS 3
|
||||
#define PIOS_RCVR_MAX_CHANNELS 12
|
||||
#define PIOS_GCSRCVR_TIMEOUT_MS 100
|
||||
#define PIOS_RFM22B_RCVR_TIMEOUT_MS 100
|
||||
|
||||
//-------------------------
|
||||
// Receiver PPM input
|
||||
|
@ -503,6 +503,27 @@ uint16_t PIOS_COM_ReceiveBuffer(uint32_t com_id, uint8_t * buf, uint16_t buf_len
|
||||
return (bytes_from_fifo);
|
||||
}
|
||||
|
||||
/**
|
||||
* Query if a com port is available for use. That can be
|
||||
* used to check a link is established even if the device
|
||||
* is valid.
|
||||
*/
|
||||
bool PIOS_COM_Available(uint32_t com_id)
|
||||
{
|
||||
struct pios_com_dev * com_dev = (struct pios_com_dev *)com_id;
|
||||
|
||||
if (!PIOS_COM_validate(com_dev)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// If a driver does not provide a query method assume always
|
||||
// available if valid
|
||||
if (com_dev->driver->available == NULL)
|
||||
return true;
|
||||
|
||||
return (com_dev->driver->available)(com_dev->lower_id);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/**
|
||||
|
@ -196,7 +196,6 @@ int32_t PIOS_Flash_Jedec_Init(uint32_t spi_id, uint32_t slave_num, const struct
|
||||
*/
|
||||
int32_t PIOS_Flash_Jedec_StartTransaction()
|
||||
{
|
||||
return 0;
|
||||
#if defined(FLASH_FREERTOS)
|
||||
if(PIOS_Flash_Jedec_Validate(flash_dev) != 0)
|
||||
return -1;
|
||||
@ -213,7 +212,6 @@ int32_t PIOS_Flash_Jedec_StartTransaction()
|
||||
*/
|
||||
int32_t PIOS_Flash_Jedec_EndTransaction()
|
||||
{
|
||||
return 0;
|
||||
#if defined(FLASH_FREERTOS)
|
||||
if(PIOS_Flash_Jedec_Validate(flash_dev) != 0)
|
||||
return -1;
|
||||
|
@ -272,7 +272,7 @@ static int32_t PIOS_MPU6000_SetReg(uint8_t reg, uint8_t data)
|
||||
/**
|
||||
* @brief Read current X, Z, Y values (in that order)
|
||||
* \param[out] int16_t array of size 3 to store X, Z, and Y magnetometer readings
|
||||
* \returns The number of samples remaining in the fifo
|
||||
* \returns 0 if succesful
|
||||
*/
|
||||
int32_t PIOS_MPU6000_ReadGyros(struct pios_mpu6000_data * data)
|
||||
{
|
||||
|
@ -59,17 +59,33 @@
|
||||
/* Local Defines */
|
||||
#define STACK_SIZE_BYTES 200
|
||||
#define TASK_PRIORITY (tskIDLE_PRIORITY + 2)
|
||||
#define ISR_TIMEOUT 5 // ms
|
||||
#define ISR_TIMEOUT 2 // ms
|
||||
#define EVENT_QUEUE_SIZE 5
|
||||
#define PACKET_QUEUE_SIZE 3
|
||||
#define RFM22B_DEFAULT_RX_DATARATE RFM22_datarate_64000
|
||||
#define RFM22B_DEFAULT_RX_DATARATE RFM22_datarate_9600
|
||||
#define RFM22B_DEFAULT_FREQUENCY 434000000
|
||||
#define RFM22B_DEFAULT_MIN_FREQUENCY (RFM22B_DEFAULT_FREQUENCY - 2000000)
|
||||
#define RFM22B_DEFAULT_MAX_FREQUENCY (RFM22B_DEFAULT_FREQUENCY + 2000000)
|
||||
#define RFM22B_DEFAULT_TX_POWER RFM22_tx_pwr_txpow_7
|
||||
#define RFM22B_LINK_QUALITY_THRESHOLD 20
|
||||
|
||||
// The maximum amount of time since the last message received to consider the connection broken.
|
||||
#define DISCONNECT_TIMEOUT_MS 1000 // ms
|
||||
|
||||
// The maximum amount of time without activity before initiating a reset.
|
||||
#define PIOS_RFM22B_SUPERVISOR_TIMEOUT 100 // ms
|
||||
|
||||
// The time between updates over the radio link.
|
||||
// The time between connection attempts when not connected
|
||||
#define CONNECT_ATTEMPT_PERIOD_MS 250 // ms
|
||||
|
||||
// The time between updates for sending stats the radio link.
|
||||
#define RADIOSTATS_UPDATE_PERIOD_MS 250
|
||||
|
||||
// The number of stats updates that a modem can miss before it's considered disconnected
|
||||
#define MAX_RADIOSTATS_MISS_COUNT 3
|
||||
|
||||
// The time between PPM updates
|
||||
#define PPM_UPDATE_PERIOD_MS 40
|
||||
|
||||
// this is too adjust the RF module so that it is on frequency
|
||||
#define OSC_LOAD_CAP 0x7F // cap = 12.5pf .. default
|
||||
#define OSC_LOAD_CAP_1 0x7D // board 1
|
||||
@ -119,156 +135,6 @@
|
||||
// AFC enabled
|
||||
|
||||
/* Local type definitions */
|
||||
enum pios_rfm22b_dev_magic {
|
||||
PIOS_RFM22B_DEV_MAGIC = 0x68e971b6,
|
||||
};
|
||||
|
||||
enum pios_rfm22b_state {
|
||||
RFM22B_STATE_UNINITIALIZED,
|
||||
RFM22B_STATE_INITIALIZING,
|
||||
RFM22B_STATE_RX_MODE,
|
||||
RFM22B_STATE_WAIT_PREAMBLE,
|
||||
RFM22B_STATE_WAIT_SYNC,
|
||||
RFM22B_STATE_RX_DATA,
|
||||
RFM22B_STATE_TX_START,
|
||||
RFM22B_STATE_TX_DATA,
|
||||
RFM22B_STATE_TIMEOUT,
|
||||
RFM22B_STATE_ERROR,
|
||||
RFM22B_STATE_FATAL_ERROR,
|
||||
|
||||
RFM22B_STATE_NUM_STATES // Must be last
|
||||
};
|
||||
|
||||
enum pios_rfm22b_event {
|
||||
RFM22B_EVENT_INITIALIZE,
|
||||
RFM22B_EVENT_INITIALIZED,
|
||||
RFM22B_EVENT_INT_RECEIVED,
|
||||
RFM22B_EVENT_RX_MODE,
|
||||
RFM22B_EVENT_PREAMBLE_DETECTED,
|
||||
RFM22B_EVENT_SYNC_DETECTED,
|
||||
RFM22B_EVENT_RX_COMPLETE,
|
||||
RFM22B_EVENT_SEND_PACKET,
|
||||
RFM22B_EVENT_TX_START,
|
||||
RFM22B_EVENT_TX_STARTED,
|
||||
RFM22B_EVENT_TX_COMPLETE,
|
||||
RFM22B_EVENT_TIMEOUT,
|
||||
RFM22B_EVENT_ERROR,
|
||||
RFM22B_EVENT_FATAL_ERROR,
|
||||
|
||||
RFM22B_EVENT_NUM_EVENTS // Must be last
|
||||
};
|
||||
|
||||
struct pios_rfm22b_dev {
|
||||
enum pios_rfm22b_dev_magic magic;
|
||||
struct pios_rfm22b_cfg cfg;
|
||||
|
||||
uint32_t spi_id;
|
||||
uint32_t slave_num;
|
||||
|
||||
// The device ID
|
||||
uint32_t deviceID;
|
||||
|
||||
// The destination ID
|
||||
uint32_t destination_id;
|
||||
|
||||
// The task handle
|
||||
xTaskHandle taskHandle;
|
||||
|
||||
// ISR pending
|
||||
xSemaphoreHandle isrPending;
|
||||
|
||||
// Receive packet complete
|
||||
xSemaphoreHandle rxsem;
|
||||
|
||||
// The COM callback functions.
|
||||
pios_com_callback rx_in_cb;
|
||||
uint32_t rx_in_context;
|
||||
pios_com_callback tx_out_cb;
|
||||
uint32_t tx_out_context;
|
||||
|
||||
// the transmit power to use for data transmissions
|
||||
uint8_t tx_power;
|
||||
|
||||
// The RF datarate lookup index.
|
||||
uint8_t datarate;
|
||||
|
||||
// The state machine state and the current event
|
||||
enum pios_rfm22b_state state;
|
||||
// The event queue handle
|
||||
xQueueHandle eventQueue;
|
||||
|
||||
// device status register
|
||||
uint8_t device_status;
|
||||
// interrupt status register 1
|
||||
uint8_t int_status1;
|
||||
// interrupt status register 2
|
||||
uint8_t int_status2;
|
||||
// ezmac status register
|
||||
uint8_t ezmac_status;
|
||||
|
||||
// The packet transmission counts
|
||||
uint32_t tx_packet_count;
|
||||
uint32_t rx_packet_count;
|
||||
|
||||
// The dropped packet counters
|
||||
uint8_t slow_block;
|
||||
uint8_t fast_block;
|
||||
uint8_t slow_good_packets;
|
||||
uint8_t fast_good_packets;
|
||||
uint8_t slow_corrected_packets;
|
||||
uint8_t fast_corrected_packets;
|
||||
uint8_t slow_error_packets;
|
||||
uint8_t fast_error_packets;
|
||||
uint8_t slow_link_quality;
|
||||
uint8_t fast_link_quality;
|
||||
|
||||
// Stats
|
||||
uint16_t resets;
|
||||
uint16_t timeouts;
|
||||
uint16_t errors;
|
||||
// the current RSSI (register value)
|
||||
uint8_t rssi;
|
||||
// RSSI in dBm
|
||||
int8_t rssi_dBm;
|
||||
|
||||
// The packet queue handle
|
||||
xQueueHandle packetQueue;
|
||||
|
||||
// The current tx packet
|
||||
PHPacketHandle tx_packet;
|
||||
// the tx data read index
|
||||
uint16_t tx_data_rd;
|
||||
// the tx data write index
|
||||
uint16_t tx_data_wr;
|
||||
|
||||
// The current rx packet
|
||||
PHPacketHandle rx_packet;
|
||||
// The previous rx packet
|
||||
PHPacketHandle rx_packet_prev;
|
||||
// The next rx packet
|
||||
PHPacketHandle rx_packet_next;
|
||||
// the receive buffer write index
|
||||
uint16_t rx_buffer_wr;
|
||||
// the receive buffer write index
|
||||
uint16_t rx_packet_len;
|
||||
|
||||
// The frequency hopping step size
|
||||
float frequency_step_size;
|
||||
// current frequency hop channel
|
||||
uint8_t frequency_hop_channel;
|
||||
// the frequency hop step size
|
||||
uint8_t frequency_hop_step_size_reg;
|
||||
// afc correction reading (in Hz)
|
||||
int32_t afc_correction_Hz;
|
||||
int8_t rx_packet_start_afc_Hz;
|
||||
|
||||
// The status packet
|
||||
PHStatusPacket status_packet;
|
||||
|
||||
// The maximum time (ms) that it should take to transmit / receive a packet.
|
||||
uint32_t max_packet_time;
|
||||
portTickType packet_start_ticks;
|
||||
};
|
||||
|
||||
struct pios_rfm22b_transition {
|
||||
enum pios_rfm22b_event (*entry_fn) (struct pios_rfm22b_dev *rfm22b_dev);
|
||||
@ -302,48 +168,53 @@ static const uint8_t OUT_FF[64] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
|
||||
|
||||
/* Local function forwared declarations */
|
||||
static void PIOS_RFM22B_Task(void *parameters);
|
||||
static void PIOS_RFM22B_InjectEvent(struct pios_rfm22b_dev *rfm22b_dev, enum pios_rfm22b_event event, bool inISR);
|
||||
static bool rfm22_readStatus(struct pios_rfm22b_dev *rfm22b_dev);
|
||||
static void rfm22_setDatarate(struct pios_rfm22b_dev * rfm22b_dev, enum rfm22b_datarate datarate, bool data_whitening);
|
||||
static enum pios_rfm22b_event rfm22_init(struct pios_rfm22b_dev *rfm22b_dev);
|
||||
static enum pios_rfm22b_event rfm22_setRxMode(struct pios_rfm22b_dev *rfm22b_dev);
|
||||
static enum pios_rfm22b_event rfm22_detectPreamble(struct pios_rfm22b_dev *rfm22b_dev);
|
||||
static enum pios_rfm22b_event rfm22_detectSync(struct pios_rfm22b_dev *rfm22b_dev);
|
||||
static enum pios_rfm22b_event rfm22_rxData(struct pios_rfm22b_dev *rfm22b_dev);
|
||||
static enum pios_rfm22b_event rfm22_init(struct pios_rfm22b_dev *rfm22b_dev);
|
||||
static enum pios_rfm22b_event rfm22_rxFailure(struct pios_rfm22b_dev *rfm22b_dev);
|
||||
static enum pios_rfm22b_event rfm22_receiveStatus(struct pios_rfm22b_dev *rfm22b_dev);
|
||||
static enum pios_rfm22b_event rfm22_receiveAck(struct pios_rfm22b_dev *rfm22b_dev);
|
||||
static enum pios_rfm22b_event rfm22_receiveNack(struct pios_rfm22b_dev *rfm22b_dev);
|
||||
static enum pios_rfm22b_event rfm22_sendAck(struct pios_rfm22b_dev *rfm22b_dev);
|
||||
static enum pios_rfm22b_event rfm22_sendNack(struct pios_rfm22b_dev *rfm22b_dev);
|
||||
static enum pios_rfm22b_event rfm22_requestConnection(struct pios_rfm22b_dev *rfm22b_dev);
|
||||
static enum pios_rfm22b_event rfm22_initConnection(struct pios_rfm22b_dev *rfm22b_dev);
|
||||
static enum pios_rfm22b_event rfm22_acceptConnection(struct pios_rfm22b_dev *rfm22b_dev);
|
||||
static enum pios_rfm22b_event rfm22_txStart(struct pios_rfm22b_dev *rfm22b_dev);
|
||||
static enum pios_rfm22b_event rfm22_txData(struct pios_rfm22b_dev *rfm22b_dev);
|
||||
static enum pios_rfm22b_event rfm22_txFailure(struct pios_rfm22b_dev *rfm22b_dev);
|
||||
static enum pios_rfm22b_event rfm22_process_state_transition(struct pios_rfm22b_dev *rfm22b_dev, enum pios_rfm22b_event event);
|
||||
static void rfm22_process_event(struct pios_rfm22b_dev *rfm22b_dev, enum pios_rfm22b_event event);
|
||||
static enum pios_rfm22b_event rfm22_timeout(struct pios_rfm22b_dev *rfm22b_dev);
|
||||
static enum pios_rfm22b_event rfm22_error(struct pios_rfm22b_dev *rfm22b_dev);
|
||||
static enum pios_rfm22b_event rfm22_fatal_error(struct pios_rfm22b_dev *rfm22b_dev);
|
||||
static bool rfm22_sendStatus(struct pios_rfm22b_dev *rfm22b_dev);
|
||||
static void rfm22_sendStatus(struct pios_rfm22b_dev *rfm22b_dev);
|
||||
static void rfm22_sendPPM(struct pios_rfm22b_dev *rfm22b_dev);
|
||||
static void rfm22b_add_rx_status(struct pios_rfm22b_dev *rfm22b_dev, enum pios_rfm22b_rx_packet_status status);
|
||||
static bool rfm22_receivePacket(struct pios_rfm22b_dev *rfm22b_dev, PHPacketHandle p, uint16_t rx_len);
|
||||
static void rfm22_setNominalCarrierFrequency(struct pios_rfm22b_dev *rfm22b_dev, uint32_t frequency_hz);
|
||||
static void rfm22_calculateLinkQuality(struct pios_rfm22b_dev *rfm22b_dev);
|
||||
static bool rfm22_ready_to_send(struct pios_rfm22b_dev *rfm22b_dev);
|
||||
static void rfm22_setConnectionParameters(struct pios_rfm22b_dev *rfm22b_dev);
|
||||
static void rfm22_clearLEDs();
|
||||
|
||||
// SPI read/write functions
|
||||
static void rfm22_assertCs();
|
||||
static void rfm22_deassertCs();
|
||||
static void rfm22_claimBus();
|
||||
static void rfm22_releaseBus();
|
||||
static void rfm22_write(uint8_t addr, uint8_t data);
|
||||
static uint8_t rfm22_read(uint8_t addr);
|
||||
static uint8_t rfm22_read_noclaim(uint8_t addr);
|
||||
|
||||
/* Provide a COM driver */
|
||||
static void PIOS_RFM22B_ChangeBaud(uint32_t rfm22b_id, uint32_t baud);
|
||||
static void PIOS_RFM22B_RegisterRxCallback(uint32_t rfm22b_id, pios_com_callback rx_in_cb, uint32_t context);
|
||||
static void PIOS_RFM22B_RegisterTxCallback(uint32_t rfm22b_id, pios_com_callback tx_out_cb, uint32_t context);
|
||||
static void PIOS_RFM22B_TxStart(uint32_t rfm22b_id, uint16_t tx_bytes_avail);
|
||||
static void PIOS_RFM22B_RxStart(uint32_t rfm22b_id, uint16_t rx_bytes_avail);
|
||||
|
||||
/* Local variables */
|
||||
const struct pios_com_driver pios_rfm22b_com_driver = {
|
||||
.set_baud = PIOS_RFM22B_ChangeBaud,
|
||||
.tx_start = PIOS_RFM22B_TxStart,
|
||||
.rx_start = PIOS_RFM22B_RxStart,
|
||||
.bind_tx_cb = PIOS_RFM22B_RegisterTxCallback,
|
||||
.bind_rx_cb = PIOS_RFM22B_RegisterRxCallback,
|
||||
};
|
||||
static void rfm22_assertCs(struct pios_rfm22b_dev *rfm22b_dev);
|
||||
static void rfm22_deassertCs(struct pios_rfm22b_dev *rfm22b_dev);
|
||||
static void rfm22_claimBus(struct pios_rfm22b_dev *rfm22b_dev);
|
||||
static void rfm22_releaseBus(struct pios_rfm22b_dev *rfm22b_dev);
|
||||
static void rfm22_write(struct pios_rfm22b_dev *rfm22b_dev, uint8_t addr, uint8_t data);
|
||||
static uint8_t rfm22_read(struct pios_rfm22b_dev *rfm22b_dev, uint8_t addr);
|
||||
static uint8_t rfm22_read_noclaim(struct pios_rfm22b_dev *rfm22b_dev, uint8_t addr);
|
||||
|
||||
/* Te state transition table */
|
||||
const static struct pios_rfm22b_transition rfm22b_transitions[RFM22B_STATE_NUM_STATES] = {
|
||||
|
||||
// Initialization thread
|
||||
[RFM22B_STATE_UNINITIALIZED] = {
|
||||
.entry_fn = 0,
|
||||
.next_state = {
|
||||
@ -354,31 +225,68 @@ const static struct pios_rfm22b_transition rfm22b_transitions[RFM22B_STATE_NUM_S
|
||||
[RFM22B_STATE_INITIALIZING] = {
|
||||
.entry_fn = rfm22_init,
|
||||
.next_state = {
|
||||
[RFM22B_EVENT_INITIALIZED] = RFM22B_STATE_TX_START,
|
||||
[RFM22B_EVENT_INITIALIZED] = RFM22B_STATE_INITIATING_CONNECTION,
|
||||
[RFM22B_EVENT_INITIALIZE] = RFM22B_STATE_INITIALIZING,
|
||||
[RFM22B_EVENT_ERROR] = RFM22B_STATE_ERROR,
|
||||
[RFM22B_EVENT_FATAL_ERROR] = RFM22B_STATE_FATAL_ERROR,
|
||||
},
|
||||
},
|
||||
[RFM22B_STATE_INITIATING_CONNECTION] = {
|
||||
.entry_fn = rfm22_initConnection,
|
||||
.next_state = {
|
||||
[RFM22B_EVENT_REQUEST_CONNECTION] = RFM22B_STATE_REQUESTING_CONNECTION,
|
||||
[RFM22B_EVENT_WAIT_FOR_CONNECTION] = RFM22B_STATE_RX_MODE,
|
||||
[RFM22B_EVENT_TIMEOUT] = RFM22B_STATE_TIMEOUT,
|
||||
[RFM22B_EVENT_ERROR] = RFM22B_STATE_ERROR,
|
||||
[RFM22B_EVENT_INITIALIZE] = RFM22B_STATE_INITIALIZING,
|
||||
[RFM22B_EVENT_FATAL_ERROR] = RFM22B_STATE_FATAL_ERROR,
|
||||
},
|
||||
},
|
||||
[RFM22B_STATE_REQUESTING_CONNECTION] = {
|
||||
.entry_fn = rfm22_requestConnection,
|
||||
.next_state = {
|
||||
[RFM22B_EVENT_TX_START] = RFM22B_STATE_TX_START,
|
||||
[RFM22B_EVENT_TIMEOUT] = RFM22B_STATE_TIMEOUT,
|
||||
[RFM22B_EVENT_ERROR] = RFM22B_STATE_ERROR,
|
||||
[RFM22B_EVENT_INITIALIZE] = RFM22B_STATE_INITIALIZING,
|
||||
[RFM22B_EVENT_FATAL_ERROR] = RFM22B_STATE_FATAL_ERROR,
|
||||
},
|
||||
},
|
||||
[RFM22B_STATE_ACCEPTING_CONNECTION] = {
|
||||
.entry_fn = rfm22_acceptConnection,
|
||||
.next_state = {
|
||||
[RFM22B_EVENT_CONNECTION_ACCEPTED] = RFM22B_STATE_SENDING_ACK,
|
||||
[RFM22B_EVENT_TIMEOUT] = RFM22B_STATE_TIMEOUT,
|
||||
[RFM22B_EVENT_ERROR] = RFM22B_STATE_ERROR,
|
||||
[RFM22B_EVENT_INITIALIZE] = RFM22B_STATE_INITIALIZING,
|
||||
[RFM22B_EVENT_FATAL_ERROR] = RFM22B_STATE_FATAL_ERROR,
|
||||
},
|
||||
},
|
||||
|
||||
[RFM22B_STATE_RX_MODE] = {
|
||||
.entry_fn = rfm22_setRxMode,
|
||||
.next_state = {
|
||||
[RFM22B_EVENT_INT_RECEIVED] = RFM22B_STATE_WAIT_PREAMBLE,
|
||||
[RFM22B_EVENT_SEND_PACKET] = RFM22B_STATE_TX_START,
|
||||
[RFM22B_EVENT_TX_START] = RFM22B_STATE_TX_START,
|
||||
[RFM22B_EVENT_ACK_TIMEOUT] = RFM22B_STATE_RECEIVING_NACK,
|
||||
[RFM22B_EVENT_FAILURE] = RFM22B_STATE_RX_FAILURE,
|
||||
[RFM22B_EVENT_TIMEOUT] = RFM22B_STATE_TIMEOUT,
|
||||
[RFM22B_EVENT_ERROR] = RFM22B_STATE_ERROR,
|
||||
[RFM22B_EVENT_INITIALIZE] = RFM22B_STATE_INITIALIZING,
|
||||
[RFM22B_EVENT_FATAL_ERROR] = RFM22B_STATE_FATAL_ERROR,
|
||||
},
|
||||
},
|
||||
[RFM22B_STATE_WAIT_PREAMBLE] = {
|
||||
.entry_fn = rfm22_detectPreamble,
|
||||
.next_state = {
|
||||
[RFM22B_EVENT_INT_RECEIVED] = RFM22B_STATE_WAIT_PREAMBLE,
|
||||
[RFM22B_EVENT_PREAMBLE_DETECTED] = RFM22B_STATE_WAIT_SYNC,
|
||||
[RFM22B_EVENT_SEND_PACKET] = RFM22B_STATE_TX_START,
|
||||
[RFM22B_EVENT_TX_START] = RFM22B_STATE_TX_START,
|
||||
[RFM22B_EVENT_ACK_TIMEOUT] = RFM22B_STATE_RECEIVING_NACK,
|
||||
[RFM22B_EVENT_INT_RECEIVED] = RFM22B_STATE_WAIT_PREAMBLE,
|
||||
[RFM22B_EVENT_FAILURE] = RFM22B_STATE_RX_FAILURE,
|
||||
[RFM22B_EVENT_TIMEOUT] = RFM22B_STATE_TIMEOUT,
|
||||
[RFM22B_EVENT_ERROR] = RFM22B_STATE_ERROR,
|
||||
[RFM22B_EVENT_INITIALIZE] = RFM22B_STATE_INITIALIZING,
|
||||
[RFM22B_EVENT_FATAL_ERROR] = RFM22B_STATE_FATAL_ERROR,
|
||||
},
|
||||
},
|
||||
@ -387,9 +295,10 @@ const static struct pios_rfm22b_transition rfm22b_transitions[RFM22B_STATE_NUM_S
|
||||
.next_state = {
|
||||
[RFM22B_EVENT_INT_RECEIVED] = RFM22B_STATE_WAIT_SYNC,
|
||||
[RFM22B_EVENT_SYNC_DETECTED] = RFM22B_STATE_RX_DATA,
|
||||
[RFM22B_EVENT_TX_START] = RFM22B_STATE_TX_START,
|
||||
[RFM22B_EVENT_FAILURE] = RFM22B_STATE_RX_FAILURE,
|
||||
[RFM22B_EVENT_TIMEOUT] = RFM22B_STATE_TIMEOUT,
|
||||
[RFM22B_EVENT_ERROR] = RFM22B_STATE_ERROR,
|
||||
[RFM22B_EVENT_INITIALIZE] = RFM22B_STATE_INITIALIZING,
|
||||
[RFM22B_EVENT_FATAL_ERROR] = RFM22B_STATE_FATAL_ERROR,
|
||||
},
|
||||
},
|
||||
@ -397,9 +306,57 @@ const static struct pios_rfm22b_transition rfm22b_transitions[RFM22B_STATE_NUM_S
|
||||
.entry_fn = rfm22_rxData,
|
||||
.next_state = {
|
||||
[RFM22B_EVENT_INT_RECEIVED] = RFM22B_STATE_RX_DATA,
|
||||
[RFM22B_EVENT_RX_COMPLETE] = RFM22B_STATE_TX_START,
|
||||
[RFM22B_EVENT_RX_COMPLETE] = RFM22B_STATE_SENDING_ACK,
|
||||
[RFM22B_EVENT_RX_ERROR] = RFM22B_STATE_SENDING_NACK,
|
||||
[RFM22B_EVENT_STATUS_RECEIVED] = RFM22B_STATE_RECEIVING_STATUS,
|
||||
[RFM22B_EVENT_CONNECTION_REQUESTED] = RFM22B_STATE_ACCEPTING_CONNECTION,
|
||||
[RFM22B_EVENT_PACKET_ACKED] = RFM22B_STATE_RECEIVING_ACK,
|
||||
[RFM22B_EVENT_PACKET_NACKED] = RFM22B_STATE_RECEIVING_NACK,
|
||||
[RFM22B_EVENT_FAILURE] = RFM22B_STATE_RX_FAILURE,
|
||||
[RFM22B_EVENT_TIMEOUT] = RFM22B_STATE_TIMEOUT,
|
||||
[RFM22B_EVENT_ERROR] = RFM22B_STATE_ERROR,
|
||||
[RFM22B_EVENT_INITIALIZE] = RFM22B_STATE_INITIALIZING,
|
||||
[RFM22B_EVENT_FATAL_ERROR] = RFM22B_STATE_FATAL_ERROR,
|
||||
},
|
||||
},
|
||||
[RFM22B_STATE_RX_FAILURE] = {
|
||||
.entry_fn = rfm22_rxFailure,
|
||||
.next_state = {
|
||||
[RFM22B_EVENT_RX_MODE] = RFM22B_STATE_RX_MODE,
|
||||
[RFM22B_EVENT_TIMEOUT] = RFM22B_STATE_TIMEOUT,
|
||||
[RFM22B_EVENT_ERROR] = RFM22B_STATE_ERROR,
|
||||
[RFM22B_EVENT_INITIALIZE] = RFM22B_STATE_INITIALIZING,
|
||||
[RFM22B_EVENT_FATAL_ERROR] = RFM22B_STATE_FATAL_ERROR,
|
||||
},
|
||||
},
|
||||
[RFM22B_STATE_RECEIVING_ACK] = {
|
||||
.entry_fn = rfm22_receiveAck,
|
||||
.next_state = {
|
||||
[RFM22B_EVENT_TX_START] = RFM22B_STATE_TX_START,
|
||||
[RFM22B_EVENT_RX_MODE] = RFM22B_STATE_RX_MODE,
|
||||
[RFM22B_EVENT_TIMEOUT] = RFM22B_STATE_TIMEOUT,
|
||||
[RFM22B_EVENT_ERROR] = RFM22B_STATE_ERROR,
|
||||
[RFM22B_EVENT_INITIALIZE] = RFM22B_STATE_INITIALIZING,
|
||||
[RFM22B_EVENT_FATAL_ERROR] = RFM22B_STATE_FATAL_ERROR,
|
||||
},
|
||||
},
|
||||
[RFM22B_STATE_RECEIVING_NACK] = {
|
||||
.entry_fn = rfm22_receiveNack,
|
||||
.next_state = {
|
||||
[RFM22B_EVENT_TX_START] = RFM22B_STATE_TX_START,
|
||||
[RFM22B_EVENT_TIMEOUT] = RFM22B_STATE_TIMEOUT,
|
||||
[RFM22B_EVENT_ERROR] = RFM22B_STATE_ERROR,
|
||||
[RFM22B_EVENT_INITIALIZE] = RFM22B_STATE_INITIALIZING,
|
||||
[RFM22B_EVENT_FATAL_ERROR] = RFM22B_STATE_FATAL_ERROR,
|
||||
},
|
||||
},
|
||||
[RFM22B_STATE_RECEIVING_STATUS] = {
|
||||
.entry_fn = rfm22_receiveStatus,
|
||||
.next_state = {
|
||||
[RFM22B_EVENT_RX_COMPLETE] = RFM22B_STATE_SENDING_ACK,
|
||||
[RFM22B_EVENT_TIMEOUT] = RFM22B_STATE_TIMEOUT,
|
||||
[RFM22B_EVENT_ERROR] = RFM22B_STATE_ERROR,
|
||||
[RFM22B_EVENT_INITIALIZE] = RFM22B_STATE_INITIALIZING,
|
||||
[RFM22B_EVENT_FATAL_ERROR] = RFM22B_STATE_FATAL_ERROR,
|
||||
},
|
||||
},
|
||||
@ -410,6 +367,7 @@ const static struct pios_rfm22b_transition rfm22b_transitions[RFM22B_STATE_NUM_S
|
||||
[RFM22B_EVENT_RX_MODE] = RFM22B_STATE_RX_MODE,
|
||||
[RFM22B_EVENT_TIMEOUT] = RFM22B_STATE_TIMEOUT,
|
||||
[RFM22B_EVENT_ERROR] = RFM22B_STATE_ERROR,
|
||||
[RFM22B_EVENT_INITIALIZE] = RFM22B_STATE_INITIALIZING,
|
||||
[RFM22B_EVENT_FATAL_ERROR] = RFM22B_STATE_FATAL_ERROR,
|
||||
},
|
||||
},
|
||||
@ -417,9 +375,41 @@ const static struct pios_rfm22b_transition rfm22b_transitions[RFM22B_STATE_NUM_S
|
||||
.entry_fn = rfm22_txData,
|
||||
.next_state = {
|
||||
[RFM22B_EVENT_INT_RECEIVED] = RFM22B_STATE_TX_DATA,
|
||||
[RFM22B_EVENT_TX_COMPLETE] = RFM22B_STATE_TX_START,
|
||||
[RFM22B_EVENT_RX_MODE] = RFM22B_STATE_RX_MODE,
|
||||
[RFM22B_EVENT_FAILURE] = RFM22B_STATE_TX_FAILURE,
|
||||
[RFM22B_EVENT_TIMEOUT] = RFM22B_STATE_TIMEOUT,
|
||||
[RFM22B_EVENT_ERROR] = RFM22B_STATE_ERROR,
|
||||
[RFM22B_EVENT_INITIALIZE] = RFM22B_STATE_INITIALIZING,
|
||||
[RFM22B_EVENT_FATAL_ERROR] = RFM22B_STATE_FATAL_ERROR,
|
||||
},
|
||||
},
|
||||
[RFM22B_STATE_TX_FAILURE] = {
|
||||
.entry_fn = rfm22_txFailure,
|
||||
.next_state = {
|
||||
[RFM22B_EVENT_TX_START] = RFM22B_STATE_TX_START,
|
||||
[RFM22B_EVENT_TIMEOUT] = RFM22B_STATE_TIMEOUT,
|
||||
[RFM22B_EVENT_ERROR] = RFM22B_STATE_ERROR,
|
||||
[RFM22B_EVENT_INITIALIZE] = RFM22B_STATE_INITIALIZING,
|
||||
[RFM22B_EVENT_FATAL_ERROR] = RFM22B_STATE_FATAL_ERROR,
|
||||
},
|
||||
},
|
||||
[RFM22B_STATE_SENDING_ACK] = {
|
||||
.entry_fn = rfm22_sendAck,
|
||||
.next_state = {
|
||||
[RFM22B_EVENT_TX_START] = RFM22B_STATE_TX_START,
|
||||
[RFM22B_EVENT_INITIALIZE] = RFM22B_STATE_INITIALIZING,
|
||||
[RFM22B_EVENT_ERROR] = RFM22B_STATE_ERROR,
|
||||
[RFM22B_EVENT_INITIALIZE] = RFM22B_STATE_INITIALIZING,
|
||||
[RFM22B_EVENT_FATAL_ERROR] = RFM22B_STATE_FATAL_ERROR,
|
||||
},
|
||||
},
|
||||
[RFM22B_STATE_SENDING_NACK] = {
|
||||
.entry_fn = rfm22_sendNack,
|
||||
.next_state = {
|
||||
[RFM22B_EVENT_TX_START] = RFM22B_STATE_TX_START,
|
||||
[RFM22B_EVENT_INITIALIZE] = RFM22B_STATE_INITIALIZING,
|
||||
[RFM22B_EVENT_ERROR] = RFM22B_STATE_ERROR,
|
||||
[RFM22B_EVENT_INITIALIZE] = RFM22B_STATE_INITIALIZING,
|
||||
[RFM22B_EVENT_FATAL_ERROR] = RFM22B_STATE_FATAL_ERROR,
|
||||
},
|
||||
},
|
||||
@ -429,6 +419,7 @@ const static struct pios_rfm22b_transition rfm22b_transitions[RFM22B_STATE_NUM_S
|
||||
[RFM22B_EVENT_TX_START] = RFM22B_STATE_TX_START,
|
||||
[RFM22B_EVENT_INITIALIZE] = RFM22B_STATE_INITIALIZING,
|
||||
[RFM22B_EVENT_ERROR] = RFM22B_STATE_ERROR,
|
||||
[RFM22B_EVENT_INITIALIZE] = RFM22B_STATE_INITIALIZING,
|
||||
[RFM22B_EVENT_FATAL_ERROR] = RFM22B_STATE_FATAL_ERROR,
|
||||
},
|
||||
},
|
||||
@ -437,14 +428,13 @@ const static struct pios_rfm22b_transition rfm22b_transitions[RFM22B_STATE_NUM_S
|
||||
.next_state = {
|
||||
[RFM22B_EVENT_INITIALIZE] = RFM22B_STATE_INITIALIZING,
|
||||
[RFM22B_EVENT_ERROR] = RFM22B_STATE_ERROR,
|
||||
[RFM22B_EVENT_INITIALIZE] = RFM22B_STATE_INITIALIZING,
|
||||
[RFM22B_EVENT_FATAL_ERROR] = RFM22B_STATE_FATAL_ERROR,
|
||||
},
|
||||
},
|
||||
[RFM22B_STATE_FATAL_ERROR] = {
|
||||
.entry_fn = rfm22_fatal_error,
|
||||
.next_state = {
|
||||
[RFM22B_EVENT_ERROR] = RFM22B_STATE_ERROR,
|
||||
[RFM22B_EVENT_FATAL_ERROR] = RFM22B_STATE_FATAL_ERROR,
|
||||
},
|
||||
},
|
||||
};
|
||||
@ -509,7 +499,15 @@ static const uint8_t ss_reg_70[] = { 0x24, 0x2D}; // rfm22_modulation_mode_cont
|
||||
static const uint8_t ss_reg_71[] = { 0x2B, 0x23}; // rfm22_modulation_mode_control2
|
||||
|
||||
|
||||
static bool PIOS_RFM22B_validate(struct pios_rfm22b_dev * rfm22b_dev)
|
||||
static inline uint32_t timeDifferenceMs(portTickType start_time, portTickType end_time)
|
||||
{
|
||||
if(end_time >= start_time)
|
||||
return (end_time - start_time) * portTICK_RATE_MS;
|
||||
// Rollover
|
||||
return ((portMAX_DELAY - start_time) + end_time) * portTICK_RATE_MS;
|
||||
}
|
||||
|
||||
bool PIOS_RFM22B_validate(struct pios_rfm22b_dev * rfm22b_dev)
|
||||
{
|
||||
return (rfm22b_dev != NULL && rfm22b_dev->magic == PIOS_RFM22B_DEV_MAGIC);
|
||||
}
|
||||
@ -557,72 +555,45 @@ int32_t PIOS_RFM22B_Init(uint32_t *rfm22b_id, uint32_t spi_id, uint32_t slave_nu
|
||||
struct pios_rfm22b_dev * rfm22b_dev = (struct pios_rfm22b_dev *) PIOS_RFM22B_alloc();
|
||||
if (!rfm22b_dev)
|
||||
return(-1);
|
||||
*rfm22b_id = (uint32_t)rfm22b_dev;
|
||||
g_rfm22b_dev = rfm22b_dev;
|
||||
|
||||
// Store the SPI handle
|
||||
rfm22b_dev->slave_num = slave_num;
|
||||
rfm22b_dev->spi_id = spi_id;
|
||||
|
||||
// Set the state to initializing.
|
||||
rfm22b_dev->state = RFM22B_STATE_UNINITIALIZED;
|
||||
// Initialize our configuration parameters
|
||||
rfm22b_dev->coordinator = false;
|
||||
rfm22b_dev->send_ppm = false;
|
||||
rfm22b_dev->datarate = RFM22B_DEFAULT_RX_DATARATE;
|
||||
|
||||
// Initialize the com callbacks.
|
||||
rfm22b_dev->com_config_cb = NULL;
|
||||
rfm22b_dev->rx_in_cb = NULL;
|
||||
rfm22b_dev->tx_out_cb = NULL;
|
||||
|
||||
// Initialize the stats.
|
||||
rfm22b_dev->stats.packets_per_sec = 0;
|
||||
rfm22b_dev->stats.rx_good = 0;
|
||||
rfm22b_dev->stats.rx_corrected = 0;
|
||||
rfm22b_dev->stats.rx_error = 0;
|
||||
rfm22b_dev->stats.rx_missed = 0;
|
||||
rfm22b_dev->stats.tx_dropped = 0;
|
||||
rfm22b_dev->stats.tx_resent = 0;
|
||||
rfm22b_dev->stats.resets = 0;
|
||||
rfm22b_dev->stats.timeouts = 0;
|
||||
rfm22b_dev->stats.link_quality = 0;
|
||||
rfm22b_dev->stats.rssi = 0;
|
||||
|
||||
// Create the event queue
|
||||
rfm22b_dev->eventQueue = xQueueCreate(EVENT_QUEUE_SIZE, sizeof(enum pios_rfm22b_event));
|
||||
|
||||
// Initialize the register values.
|
||||
rfm22b_dev->device_status = 0;
|
||||
rfm22b_dev->int_status1 = 0;
|
||||
rfm22b_dev->int_status2 = 0;
|
||||
rfm22b_dev->ezmac_status = 0;
|
||||
|
||||
// Initlize the link stats.
|
||||
rfm22b_dev->slow_block = 0;
|
||||
rfm22b_dev->fast_block = 0;
|
||||
rfm22b_dev->slow_good_packets = 0;
|
||||
rfm22b_dev->fast_good_packets = 0;
|
||||
rfm22b_dev->slow_corrected_packets = 0;
|
||||
rfm22b_dev->fast_corrected_packets = 0;
|
||||
rfm22b_dev->slow_error_packets = 0;
|
||||
rfm22b_dev->fast_error_packets = 0;
|
||||
rfm22b_dev->slow_link_quality = 255;
|
||||
rfm22b_dev->fast_link_quality = 255;
|
||||
|
||||
// Initialize the stats.
|
||||
rfm22b_dev->resets = 0;
|
||||
rfm22b_dev->timeouts = 0;
|
||||
rfm22b_dev->errors = 0;
|
||||
rfm22b_dev->tx_packet_count = 0;
|
||||
rfm22b_dev->rx_packet_count = 0;
|
||||
rfm22b_dev->rssi = 0;
|
||||
rfm22b_dev->rssi_dBm = -127;
|
||||
|
||||
// Bind the configuration to the device instance
|
||||
rfm22b_dev->cfg = *cfg;
|
||||
rfm22b_dev->datarate = RFM22B_DEFAULT_RX_DATARATE;
|
||||
|
||||
// Initialize the packets.
|
||||
rfm22b_dev->rx_packet = NULL;
|
||||
rfm22b_dev->rx_packet_next = NULL;
|
||||
rfm22b_dev->rx_packet_prev = NULL;
|
||||
rfm22b_dev->rx_packet_len = 0;
|
||||
rfm22b_dev->tx_packet = NULL;
|
||||
|
||||
*rfm22b_id = (uint32_t)rfm22b_dev;
|
||||
g_rfm22b_dev = rfm22b_dev;
|
||||
|
||||
// Calculate the (approximate) maximum amount of time that it should take to transmit / receive a packet.
|
||||
rfm22b_dev->packet_start_ticks = 0;
|
||||
|
||||
// Create a semaphore to know if an ISR needs responding to
|
||||
vSemaphoreCreateBinary( rfm22b_dev->isrPending );
|
||||
|
||||
// Create a semaphore to know when an rx packet is available
|
||||
vSemaphoreCreateBinary( rfm22b_dev->rxsem );
|
||||
|
||||
// Create the packet queue.
|
||||
rfm22b_dev->packetQueue = xQueueCreate(PACKET_QUEUE_SIZE, sizeof(PHPacketHandle));
|
||||
|
||||
// Initialize the max tx power level.
|
||||
PIOS_RFM22B_SetTxPower(*rfm22b_id, cfg->maxTxPower);
|
||||
|
||||
// Create our (hopefully) unique 32 bit id from the processor serial number.
|
||||
uint8_t crcs[] = { 0, 0, 0, 0 };
|
||||
{
|
||||
@ -643,12 +614,18 @@ int32_t PIOS_RFM22B_Init(uint32_t *rfm22b_id, uint32_t spi_id, uint32_t slave_nu
|
||||
PIOS_WDG_RegisterFlag(PIOS_WDG_RFM22B);
|
||||
#endif /* PIOS_WDG_RFM22B */
|
||||
|
||||
// Start the driver task. This task controls the radio state machine and removed all of the IO from the IRQ handler.
|
||||
xTaskCreate(PIOS_RFM22B_Task, (signed char *)"PIOS_RFM22B_Task", STACK_SIZE_BYTES, (void*)rfm22b_dev, TASK_PRIORITY, &(rfm22b_dev->taskHandle));
|
||||
// Initialize the ECC library.
|
||||
initialize_ecc();
|
||||
|
||||
// Set the state to initializing.
|
||||
rfm22b_dev->state = RFM22B_STATE_UNINITIALIZED;
|
||||
|
||||
// Initialize the radio device.
|
||||
PIOS_RFM22B_InjectEvent(rfm22b_dev, RFM22B_EVENT_INITIALIZE, false);
|
||||
|
||||
// Start the driver task. This task controls the radio state machine and removed all of the IO from the IRQ handler.
|
||||
xTaskCreate(PIOS_RFM22B_Task, (signed char *)"PIOS_RFM22B_Task", STACK_SIZE_BYTES, (void*)rfm22b_dev, TASK_PRIORITY, &(rfm22b_dev->taskHandle));
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
@ -671,7 +648,7 @@ bool PIOS_RFM22_EXT_Int(void)
|
||||
* \param[in] event The event to inject
|
||||
* \param[in] inISR Is this being called from an interrrup service routine?
|
||||
*/
|
||||
static void PIOS_RFM22B_InjectEvent(struct pios_rfm22b_dev *rfm22b_dev, enum pios_rfm22b_event event, bool inISR)
|
||||
void PIOS_RFM22B_InjectEvent(struct pios_rfm22b_dev *rfm22b_dev, enum pios_rfm22b_event event, bool inISR)
|
||||
{
|
||||
|
||||
// Store the event.
|
||||
@ -697,184 +674,172 @@ static void PIOS_RFM22B_InjectEvent(struct pios_rfm22b_dev *rfm22b_dev, enum pio
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the unique device ID for th RFM22B device.
|
||||
* Returns the unique device ID for the RFM22B device.
|
||||
* \param[in] rfm22b_id The RFM22B device index.
|
||||
* \return The unique device ID
|
||||
*/
|
||||
uint32_t PIOS_RFM22B_DeviceID(uint32_t rfm22b_id)
|
||||
{
|
||||
struct pios_rfm22b_dev *rfm22b_dev = (struct pios_rfm22b_dev *)rfm22b_id;
|
||||
if(PIOS_RFM22B_validate(rfm22b_dev))
|
||||
if (PIOS_RFM22B_validate(rfm22b_dev))
|
||||
return rfm22b_dev->deviceID;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the radio device transmit power.
|
||||
* \param[in] rfm22b_id The RFM22B device index.
|
||||
* \param[in] tx_pwr The transmit power.
|
||||
*/
|
||||
void PIOS_RFM22B_SetTxPower(uint32_t rfm22b_id, enum rfm22b_tx_power tx_pwr)
|
||||
{
|
||||
struct pios_rfm22b_dev *rfm22b_dev = (struct pios_rfm22b_dev *)rfm22b_id;
|
||||
if(!PIOS_RFM22B_validate(rfm22b_dev))
|
||||
if (!PIOS_RFM22B_validate(rfm22b_dev))
|
||||
return;
|
||||
rfm22b_dev->tx_power = tx_pwr;
|
||||
}
|
||||
|
||||
void PIOS_RFM22B_SetDestinationId(uint32_t rfm22b_id, uint32_t dest_id)
|
||||
/**
|
||||
* Sets the radio frequency range and value.
|
||||
* \param[in] rfm22b_id The RFM22B device index.
|
||||
* \param[in] min_frequency The minimum frequency.
|
||||
* \param[in] max_frequency The maximum frequency.
|
||||
*/
|
||||
void PIOS_RFM22B_SetFrequencyRange(uint32_t rfm22b_id, uint32_t min_frequency, uint32_t max_frequency)
|
||||
{
|
||||
struct pios_rfm22b_dev *rfm22b_dev = (struct pios_rfm22b_dev *)rfm22b_id;
|
||||
if(!PIOS_RFM22B_validate(rfm22b_dev))
|
||||
if (!PIOS_RFM22B_validate(rfm22b_dev))
|
||||
return;
|
||||
rfm22b_dev->destination_id = (dest_id == 0) ? 0xffffffff : dest_id;
|
||||
}
|
||||
|
||||
uint16_t PIOS_RFM22B_Resets(uint32_t rfm22b_id)
|
||||
{
|
||||
struct pios_rfm22b_dev *rfm22b_dev = (struct pios_rfm22b_dev *)rfm22b_id;
|
||||
if(!PIOS_RFM22B_validate(rfm22b_dev))
|
||||
return 0;
|
||||
return rfm22b_dev->resets;
|
||||
}
|
||||
|
||||
uint16_t PIOS_RFM22B_Timeouts(uint32_t rfm22b_id)
|
||||
{
|
||||
struct pios_rfm22b_dev *rfm22b_dev = (struct pios_rfm22b_dev *)rfm22b_id;
|
||||
if(!PIOS_RFM22B_validate(rfm22b_dev))
|
||||
return 0;
|
||||
return rfm22b_dev->timeouts;
|
||||
}
|
||||
|
||||
uint8_t PIOS_RFM22B_LinkQuality(uint32_t rfm22b_id)
|
||||
{
|
||||
struct pios_rfm22b_dev *rfm22b_dev = (struct pios_rfm22b_dev *)rfm22b_id;
|
||||
if(!PIOS_RFM22B_validate(rfm22b_dev))
|
||||
return 0;
|
||||
return rfm22b_dev->slow_link_quality;
|
||||
}
|
||||
|
||||
int8_t PIOS_RFM22B_RSSI(uint32_t rfm22b_id)
|
||||
{
|
||||
struct pios_rfm22b_dev *rfm22b_dev = (struct pios_rfm22b_dev *)rfm22b_id;
|
||||
if(!PIOS_RFM22B_validate(rfm22b_dev))
|
||||
return 0;
|
||||
return rfm22b_dev->rssi_dBm;
|
||||
}
|
||||
|
||||
static void PIOS_RFM22B_RxStart(uint32_t rfm22b_id, uint16_t rx_bytes_avail)
|
||||
{
|
||||
struct pios_rfm22b_dev * rfm22b_dev = (struct pios_rfm22b_dev *)rfm22b_id;
|
||||
|
||||
bool valid = PIOS_RFM22B_validate(rfm22b_dev);
|
||||
PIOS_Assert(valid);
|
||||
|
||||
rfm22b_dev->min_frequency = min_frequency;
|
||||
rfm22b_dev->max_frequency = max_frequency;
|
||||
rfm22_setNominalCarrierFrequency(rfm22b_dev, (max_frequency - min_frequency) / 2);
|
||||
}
|
||||
|
||||
/**
|
||||
* Insert a packet on the packet queue for sending.
|
||||
* Note: If this finction succedds, the packet will be released by the driver, so no release is necessary.
|
||||
* If this function doesn't success, the caller is still responsible for the packet.
|
||||
* \param[in] rfm22b_id The rfm22b device.
|
||||
* \param[in] p The packet handle.
|
||||
* \param[in] max_delay The maximum time to delay waiting to queue the packet.
|
||||
* \return true on success, false on failue to queue the packet.
|
||||
* Sets the radio destination ID.
|
||||
* \param[in] rfm22b_id The RFM22B device index.
|
||||
* \param[in] dest_id The destination ID.
|
||||
*/
|
||||
bool PIOS_RFM22B_Send_Packet(uint32_t rfm22b_id, PHPacketHandle p, uint32_t max_delay)
|
||||
void PIOS_RFM22B_SetDestinationId(uint32_t rfm22b_id, uint32_t dest_id)
|
||||
{
|
||||
struct pios_rfm22b_dev *rfm22b_dev = (struct pios_rfm22b_dev *)rfm22b_id;
|
||||
if (!PIOS_RFM22B_validate(rfm22b_dev))
|
||||
return;
|
||||
rfm22b_dev->destination_id = (dest_id == 0) ? 0xffffffff : dest_id;
|
||||
// The first slot is reserved for our current pairID
|
||||
rfm22b_dev->pair_stats[0].pairID = dest_id;
|
||||
rfm22b_dev->pair_stats[0].rssi = -127;
|
||||
rfm22b_dev->pair_stats[0].afc_correction = 0;
|
||||
rfm22b_dev->pair_stats[0].lastContact = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Configures the radio as a coordinator or not.
|
||||
* \param[in] rfm22b_id The RFM22B device index.
|
||||
* \param[in] coordinator Sets as coordinator if true.
|
||||
*/
|
||||
void PIOS_RFM22B_SetCoordinator(uint32_t rfm22b_id, bool coordinator)
|
||||
{
|
||||
struct pios_rfm22b_dev *rfm22b_dev = (struct pios_rfm22b_dev *)rfm22b_id;
|
||||
if (!PIOS_RFM22B_validate(rfm22b_dev))
|
||||
return;
|
||||
rfm22b_dev->coordinator = coordinator;
|
||||
|
||||
// Re-initialize the radio device.
|
||||
PIOS_RFM22B_InjectEvent(rfm22b_dev, RFM22B_EVENT_INITIALIZE, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the remote com port configuration parameters.
|
||||
* \param[in] rfm22b_id The rfm22b device.
|
||||
* \param[in] com_port The remote com port
|
||||
* \param[in] com_speed The remote com port speed
|
||||
*/
|
||||
void PIOS_RFM22B_SetRemoteComConfig(uint32_t rfm22b_id, OPLinkSettingsOutputConnectionOptions com_port, OPLinkSettingsComSpeedOptions com_speed)
|
||||
{
|
||||
struct pios_rfm22b_dev *rfm22b_dev = (struct pios_rfm22b_dev *)rfm22b_id;
|
||||
if(!PIOS_RFM22B_validate(rfm22b_dev))
|
||||
return;
|
||||
rfm22b_dev->con_packet.port = com_port;
|
||||
rfm22b_dev->con_packet.com_speed = com_speed;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the com port configuration callback (to receive com configuration over the air)
|
||||
* \param[in] rfm22b_id The rfm22b device.
|
||||
* \param[in] cb A pointer to the callback function
|
||||
*/
|
||||
void PIOS_RFM22B_SetComConfigCallback(uint32_t rfm22b_id, PIOS_RFM22B_ComConfigCallback cb)
|
||||
{
|
||||
struct pios_rfm22b_dev *rfm22b_dev = (struct pios_rfm22b_dev *)rfm22b_id;
|
||||
if(!PIOS_RFM22B_validate(rfm22b_dev))
|
||||
return;
|
||||
rfm22b_dev->com_config_cb = cb;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the device statistics RFM22B device.
|
||||
* \param[in] rfm22b_id The RFM22B device index.
|
||||
* \param[out] stats The stats are returned in this structure
|
||||
*/
|
||||
void PIOS_RFM22B_GetStats(uint32_t rfm22b_id, struct rfm22b_stats *stats) {
|
||||
struct pios_rfm22b_dev *rfm22b_dev = (struct pios_rfm22b_dev *)rfm22b_id;
|
||||
if(!PIOS_RFM22B_validate(rfm22b_dev))
|
||||
return;
|
||||
|
||||
// Calculate the current link quality
|
||||
rfm22_calculateLinkQuality(rfm22b_dev);
|
||||
|
||||
// We are connected if our destination ID is in the pair stats.
|
||||
if (rfm22b_dev->destination_id != 0xffffffff)
|
||||
for (uint8_t i = 0; i < OPLINKSTATUS_PAIRIDS_NUMELEM; ++i)
|
||||
{
|
||||
if ((rfm22b_dev->pair_stats[i].pairID == rfm22b_dev->destination_id) &&
|
||||
(rfm22b_dev->pair_stats[i].rssi > -127))
|
||||
{
|
||||
rfm22b_dev->stats.rssi = rfm22b_dev->pair_stats[i].rssi;
|
||||
rfm22b_dev->stats.afc_correction = rfm22b_dev->pair_stats[i].afc_correction;
|
||||
break;
|
||||
}
|
||||
}
|
||||
*stats = rfm22b_dev->stats;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the stats of the oter radio devices that are in range.
|
||||
* \param[out] device_ids A pointer to the array to store the device IDs.
|
||||
* \param[out] RSSIs A pointer to the array to store the RSSI values in.
|
||||
* \param[in] mx_pairs The length of the pdevice_ids and RSSIs arrays.
|
||||
* \return The number of pair stats returned.
|
||||
*/
|
||||
uint8_t PIOS_RFM2B_GetPairStats(uint32_t rfm22b_id, uint32_t *device_ids, int8_t *RSSIs, uint8_t max_pairs)
|
||||
{
|
||||
struct pios_rfm22b_dev *rfm22b_dev = (struct pios_rfm22b_dev *)rfm22b_id;
|
||||
if (!PIOS_RFM22B_validate(rfm22b_dev))
|
||||
return 0;
|
||||
|
||||
uint8_t mp = (max_pairs >= OPLINKSTATUS_PAIRIDS_NUMELEM) ? max_pairs : OPLINKSTATUS_PAIRIDS_NUMELEM;
|
||||
for (uint8_t i = 0; i < mp; ++i)
|
||||
{
|
||||
device_ids[i] = rfm22b_dev->pair_stats[i].pairID;
|
||||
RSSIs[i] = rfm22b_dev->pair_stats[i].rssi;
|
||||
}
|
||||
|
||||
return mp;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check the radio device for a valid connection
|
||||
* \param[in] rfm22b_id The rfm22b device.
|
||||
* Returns true if there is a valid connection to paired radio, false otherwise.
|
||||
*/
|
||||
bool PIOS_RFM22B_LinkStatus(uint32_t rfm22b_id)
|
||||
{
|
||||
struct pios_rfm22b_dev *rfm22b_dev = (struct pios_rfm22b_dev *)rfm22b_id;
|
||||
if(!PIOS_RFM22B_validate(rfm22b_dev))
|
||||
return false;
|
||||
|
||||
// Store the packet handle in the packet queue
|
||||
if (xQueueSend(rfm22b_dev->packetQueue, &p, max_delay) != pdTRUE)
|
||||
return false;
|
||||
|
||||
// Inject a send packet event
|
||||
PIOS_RFM22B_InjectEvent(g_rfm22b_dev, RFM22B_EVENT_SEND_PACKET, false);
|
||||
|
||||
// Success
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Receive a packet from the radio.
|
||||
* \param[in] rfm22b_id The rfm22b device.
|
||||
* \param[in] pret A pointer to the packet handle.
|
||||
* \param[in] max_delay The maximum time to delay waiting for a packet.
|
||||
* \return The number of bytes received.
|
||||
*/
|
||||
uint32_t PIOS_RFM22B_Receive_Packet(uint32_t rfm22b_id, PHPacketHandle *pret, uint32_t max_delay)
|
||||
{
|
||||
struct pios_rfm22b_dev * rfm22b_dev = (struct pios_rfm22b_dev *)rfm22b_id;
|
||||
if (!PIOS_RFM22B_validate(rfm22b_dev))
|
||||
return 0;
|
||||
|
||||
// Allocate the next Rx packet
|
||||
if (rfm22b_dev->rx_packet_next == NULL)
|
||||
rfm22b_dev->rx_packet_next = PHGetRXPacket(pios_packet_handler);
|
||||
|
||||
// Block on the semephore until the a packet has been received.
|
||||
if (xSemaphoreTake(rfm22b_dev->rxsem, max_delay / portTICK_RATE_MS) != pdTRUE)
|
||||
return 0;
|
||||
|
||||
// Return the Rx packet if it's available.
|
||||
uint32_t rx_len = 0;
|
||||
if (rfm22b_dev->rx_packet_prev)
|
||||
{
|
||||
PHPacketHandle p = rfm22b_dev->rx_packet_prev;
|
||||
uint16_t len = PHPacketSizeECC(p);
|
||||
|
||||
// Attempt to correct any errors in the packet.
|
||||
decode_data((unsigned char*)p, len);
|
||||
|
||||
// Check if there were any errors
|
||||
bool rx_error = check_syndrome() != 0;
|
||||
if(rx_error)
|
||||
{
|
||||
|
||||
// We have an error. Try to correct it.
|
||||
if (correct_errors_erasures((unsigned char*)p, len, 0, 0) == 0)
|
||||
{
|
||||
// We couldn't correct the error, so drop the packet.
|
||||
rfm22b_dev->fast_error_packets++;
|
||||
PHReleaseRXPacket(pios_packet_handler, p);
|
||||
}
|
||||
else
|
||||
{
|
||||
// We corrected the error.
|
||||
rfm22b_dev->fast_corrected_packets++;
|
||||
rx_error = false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Return the packet if there were not uncorrectable errors.
|
||||
if (!rx_error)
|
||||
{
|
||||
rfm22b_dev->fast_good_packets++;
|
||||
*pret = p;
|
||||
rx_len = rfm22b_dev->rx_packet_len;
|
||||
|
||||
// Update the link statistics if necessary.
|
||||
uint8_t fast_block = (p->header.seq_num >> 2) & 0xff;
|
||||
uint8_t slow_block = (p->header.seq_num >> 4) & 0xff;
|
||||
if (rfm22b_dev->fast_block != fast_block)
|
||||
{
|
||||
rfm22b_dev->fast_link_quality = (uint8_t)(((4 + (uint16_t)rfm22b_dev->fast_good_packets - rfm22b_dev->fast_error_packets) << 5) - 1);
|
||||
rfm22b_dev->slow_good_packets += rfm22b_dev->fast_good_packets;
|
||||
rfm22b_dev->slow_corrected_packets += rfm22b_dev->fast_corrected_packets;
|
||||
rfm22b_dev->slow_error_packets += rfm22b_dev->fast_error_packets;
|
||||
rfm22b_dev->fast_good_packets = rfm22b_dev->fast_corrected_packets = rfm22b_dev->fast_error_packets = 0;
|
||||
rfm22b_dev->fast_block = fast_block;
|
||||
}
|
||||
if (rfm22b_dev->slow_block != slow_block)
|
||||
{
|
||||
rfm22b_dev->slow_link_quality = (uint8_t)(((16 + (uint16_t)rfm22b_dev->slow_good_packets - rfm22b_dev->slow_error_packets) << 3) - 1);
|
||||
rfm22b_dev->slow_good_packets = rfm22b_dev->slow_corrected_packets = rfm22b_dev->slow_error_packets = 0;
|
||||
rfm22b_dev->slow_block = slow_block;
|
||||
}
|
||||
}
|
||||
rfm22b_dev->rx_packet_prev = NULL;
|
||||
}
|
||||
|
||||
return rx_len;
|
||||
return (rfm22b_dev->stats.link_state == OPLINKSTATUS_LINKSTATE_CONNECTED) && (rfm22b_dev->stats.link_quality > RFM22B_LINK_QUALITY_THRESHOLD);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -887,6 +852,7 @@ static void PIOS_RFM22B_Task(void *parameters)
|
||||
return;
|
||||
portTickType lastEventTicks = xTaskGetTickCount();
|
||||
portTickType lastStatusTicks = lastEventTicks;
|
||||
portTickType lastPPMTicks = lastEventTicks;
|
||||
|
||||
while(1)
|
||||
{
|
||||
@ -896,7 +862,7 @@ static void PIOS_RFM22B_Task(void *parameters)
|
||||
#endif /* PIOS_WDG_RFM22B */
|
||||
|
||||
// Wait for a signal indicating an external interrupt or a pending send/receive request.
|
||||
if ( xSemaphoreTake(g_rfm22b_dev->isrPending, ISR_TIMEOUT / portTICK_RATE_MS) == pdTRUE ) {
|
||||
if (xSemaphoreTake(rfm22b_dev->isrPending, ISR_TIMEOUT / portTICK_RATE_MS) == pdTRUE) {
|
||||
lastEventTicks = xTaskGetTickCount();
|
||||
|
||||
// Process events through the state machine.
|
||||
@ -906,154 +872,197 @@ static void PIOS_RFM22B_Task(void *parameters)
|
||||
if ((event == RFM22B_EVENT_INT_RECEIVED) &&
|
||||
((rfm22b_dev->state == RFM22B_STATE_UNINITIALIZED) || (rfm22b_dev->state == RFM22B_STATE_INITIALIZING)))
|
||||
continue;
|
||||
|
||||
// Process all state transitions.
|
||||
while(event != RFM22B_EVENT_NUM_EVENTS)
|
||||
event = rfm22_process_state_transition(rfm22b_dev, event);
|
||||
rfm22_process_event(rfm22b_dev, event);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Has it been too long since the last event?
|
||||
portTickType curTicks = xTaskGetTickCount();
|
||||
if (curTicks < lastEventTicks)
|
||||
lastEventTicks = curTicks;
|
||||
portTickType ticksSinceEvent = curTicks - lastEventTicks;
|
||||
if ((ticksSinceEvent / portTICK_RATE_MS) > PIOS_RFM22B_SUPERVISOR_TIMEOUT)
|
||||
if (timeDifferenceMs(lastEventTicks, curTicks) > PIOS_RFM22B_SUPERVISOR_TIMEOUT)
|
||||
{
|
||||
// Transsition through an error event.
|
||||
enum pios_rfm22b_event event = RFM22B_EVENT_ERROR;
|
||||
while(event != RFM22B_EVENT_NUM_EVENTS)
|
||||
event = rfm22_process_state_transition(rfm22b_dev, event);
|
||||
rfm22_process_event(rfm22b_dev, RFM22B_EVENT_ERROR);
|
||||
|
||||
// Clear the event queue.
|
||||
enum pios_rfm22b_event event;
|
||||
while (xQueueReceive(rfm22b_dev->eventQueue, &event, 0) == pdTRUE)
|
||||
;
|
||||
lastEventTicks = xTaskGetTickCount();
|
||||
}
|
||||
}
|
||||
|
||||
// Have we locked up sending / receiving a packet?
|
||||
if (rfm22b_dev->packet_start_ticks > 0)
|
||||
portTickType curTicks = xTaskGetTickCount();
|
||||
// Have we been sending this packet too long?
|
||||
if ((rfm22b_dev->packet_start_ticks > 0) && (timeDifferenceMs(rfm22b_dev->packet_start_ticks, curTicks) > (rfm22b_dev->max_packet_time * 3)))
|
||||
rfm22_process_event(rfm22b_dev, RFM22B_EVENT_TIMEOUT);
|
||||
|
||||
// Have it been too long since we received a packet
|
||||
else if ((rfm22b_dev->rx_complete_ticks > 0) && (timeDifferenceMs(rfm22b_dev->rx_complete_ticks, curTicks) > DISCONNECT_TIMEOUT_MS))
|
||||
rfm22_process_event(rfm22b_dev, RFM22B_EVENT_ERROR);
|
||||
|
||||
else
|
||||
{
|
||||
portTickType cur_ticks = xTaskGetTickCount();
|
||||
|
||||
// Did the clock wrap around?
|
||||
if (cur_ticks < rfm22b_dev->packet_start_ticks)
|
||||
rfm22b_dev->packet_start_ticks = (cur_ticks > 0) ? cur_ticks : 1;
|
||||
|
||||
// Have we been sending this packet too long?
|
||||
if (((cur_ticks - rfm22b_dev->packet_start_ticks) / portTICK_RATE_MS) > (rfm22b_dev->max_packet_time * 3))
|
||||
|
||||
// Are we waiting for an ACK?
|
||||
if (rfm22b_dev->prev_tx_packet)
|
||||
{
|
||||
enum pios_rfm22b_event event = RFM22B_EVENT_TIMEOUT;
|
||||
while(event != RFM22B_EVENT_NUM_EVENTS)
|
||||
event = rfm22_process_state_transition(rfm22b_dev, event);
|
||||
|
||||
// Should we resend the packet?
|
||||
if (timeDifferenceMs(rfm22b_dev->tx_complete_ticks, curTicks) > rfm22b_dev->max_ack_delay)
|
||||
{
|
||||
rfm22b_dev->tx_complete_ticks = curTicks;
|
||||
rfm22_process_event(rfm22b_dev, RFM22B_EVENT_ACK_TIMEOUT);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
// Queue up a PPM packet if it's time.
|
||||
if (timeDifferenceMs(lastPPMTicks, curTicks) > PPM_UPDATE_PERIOD_MS)
|
||||
{
|
||||
rfm22_sendPPM(rfm22b_dev);
|
||||
lastPPMTicks = curTicks;
|
||||
}
|
||||
|
||||
// Queue up a status packet if it's time.
|
||||
if (timeDifferenceMs(lastStatusTicks, curTicks) > RADIOSTATS_UPDATE_PERIOD_MS)
|
||||
{
|
||||
rfm22_sendStatus(rfm22b_dev);
|
||||
lastStatusTicks = curTicks;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Queue up a status packet if it's time.
|
||||
portTickType curTicks = xTaskGetTickCount();
|
||||
// Rollover
|
||||
if (curTicks < lastStatusTicks)
|
||||
lastStatusTicks = curTicks;
|
||||
if (((curTicks - lastStatusTicks) / portTICK_RATE_MS) > RADIOSTATS_UPDATE_PERIOD_MS)
|
||||
if (rfm22_sendStatus(rfm22b_dev))
|
||||
lastStatusTicks = curTicks;
|
||||
// Send a packet if it's our time slice
|
||||
rfm22b_dev->time_to_send = (((curTicks - rfm22b_dev->time_to_send_offset) & 0x6) == 0);
|
||||
#ifdef PIOS_RFM22B_DEBUG_ON_TELEM
|
||||
if (rfm22b_dev->time_to_send)
|
||||
D4_LED_ON;
|
||||
else
|
||||
D4_LED_OFF;
|
||||
#endif
|
||||
if (rfm22b_dev->time_to_send)
|
||||
rfm22_process_event(rfm22b_dev, RFM22B_EVENT_TX_START);
|
||||
}
|
||||
}
|
||||
|
||||
static void PIOS_RFM22B_TxStart(uint32_t rfm22b_id, uint16_t tx_bytes_avail)
|
||||
// ************************************
|
||||
// radio datarate about 19200 Baud
|
||||
// radio frequency deviation 45kHz
|
||||
// radio receiver bandwidth 67kHz.
|
||||
//
|
||||
// Carson's rule:
|
||||
// The signal bandwidth is about 2(Delta-f + fm) ..
|
||||
//
|
||||
// Delta-f = frequency deviation
|
||||
// fm = maximum frequency of the signal
|
||||
//
|
||||
// This gives 2(45 + 9.6) = 109.2kHz.
|
||||
|
||||
static void rfm22_setDatarate(struct pios_rfm22b_dev * rfm22b_dev, enum rfm22b_datarate datarate, bool data_whitening)
|
||||
{
|
||||
struct pios_rfm22b_dev * rfm22b_dev = (struct pios_rfm22b_dev *)rfm22b_id;
|
||||
bool valid = PIOS_RFM22B_validate(rfm22b_dev);
|
||||
PIOS_Assert(valid);
|
||||
uint32_t datarate_bps = data_rate[datarate];
|
||||
rfm22b_dev->max_packet_time = (uint16_t)((float)(PIOS_PH_MAX_PACKET * 8 * 1000) / (float)(datarate_bps) + 0.5);
|
||||
if (rfm22b_dev->stats.link_state == OPLINKSTATUS_LINKSTATE_CONNECTED)
|
||||
{
|
||||
// Generate a pseudo-random number from 0-8 to add to the delay
|
||||
uint8_t random = PIOS_CRC_updateByte(0, (uint8_t)(xTaskGetTickCount() & 0xff)) & 0x03;
|
||||
rfm22b_dev->max_ack_delay = (uint16_t)((float)(sizeof(PHPacketHeader) * 8 * 1000) / (float)(datarate_bps) + 0.5) * 4 + random;
|
||||
}
|
||||
else
|
||||
rfm22b_dev->max_ack_delay = CONNECT_ATTEMPT_PERIOD_MS;
|
||||
|
||||
#ifdef NEVER
|
||||
// Get some data to send
|
||||
bool need_yield = false;
|
||||
if(tx_pre_buffer_size == 0)
|
||||
tx_pre_buffer_size = (rfm22b_dev->tx_out_cb)(rfm22b_dev->tx_out_context, tx_pre_buffer,
|
||||
TX_BUFFER_SIZE, NULL, &need_yield);
|
||||
// rfm22_if_filter_bandwidth
|
||||
rfm22_write(rfm22b_dev, 0x1C, reg_1C[datarate]);
|
||||
|
||||
// Inject a send packet event
|
||||
PIOS_RFM22B_InjectEvent(g_rfm22b_dev, RFM22B_EVENT_TX_START, false);
|
||||
#endif
|
||||
// rfm22_afc_loop_gearshift_override
|
||||
rfm22_write(rfm22b_dev, 0x1D, reg_1D[datarate]);
|
||||
// RFM22_afc_timing_control
|
||||
rfm22_write(rfm22b_dev, 0x1E, reg_1E[datarate]);
|
||||
|
||||
// RFM22_clk_recovery_gearshift_override
|
||||
rfm22_write(rfm22b_dev, 0x1F, reg_1F[datarate]);
|
||||
// rfm22_clk_recovery_oversampling_ratio
|
||||
rfm22_write(rfm22b_dev, 0x20, reg_20[datarate]);
|
||||
// rfm22_clk_recovery_offset2
|
||||
rfm22_write(rfm22b_dev, 0x21, reg_21[datarate]);
|
||||
// rfm22_clk_recovery_offset1
|
||||
rfm22_write(rfm22b_dev, 0x22, reg_22[datarate]);
|
||||
// rfm22_clk_recovery_offset0
|
||||
rfm22_write(rfm22b_dev, 0x23, reg_23[datarate]);
|
||||
// rfm22_clk_recovery_timing_loop_gain1
|
||||
rfm22_write(rfm22b_dev, 0x24, reg_24[datarate]);
|
||||
// rfm22_clk_recovery_timing_loop_gain0
|
||||
rfm22_write(rfm22b_dev, 0x25, reg_25[datarate]);
|
||||
|
||||
// rfm22_afc_limiter
|
||||
rfm22_write(rfm22b_dev, 0x2A, reg_2A[datarate]);
|
||||
|
||||
// rfm22_tx_data_rate1
|
||||
rfm22_write(rfm22b_dev, 0x6E, reg_6E[datarate]);
|
||||
// rfm22_tx_data_rate0
|
||||
rfm22_write(rfm22b_dev, 0x6F, reg_6F[datarate]);
|
||||
|
||||
if (!data_whitening)
|
||||
// rfm22_modulation_mode_control1
|
||||
rfm22_write(rfm22b_dev, 0x70, reg_70[datarate] & ~RFM22_mmc1_enwhite);
|
||||
else
|
||||
// rfm22_modulation_mode_control1
|
||||
rfm22_write(rfm22b_dev, 0x70, reg_70[datarate] | RFM22_mmc1_enwhite);
|
||||
|
||||
// rfm22_modulation_mode_control2
|
||||
rfm22_write(rfm22b_dev, 0x71, reg_71[datarate]);
|
||||
|
||||
// rfm22_frequency_deviation
|
||||
rfm22_write(rfm22b_dev, 0x72, reg_72[datarate]);
|
||||
|
||||
rfm22_write(rfm22b_dev, RFM22_ook_counter_value1, 0x00);
|
||||
rfm22_write(rfm22b_dev, RFM22_ook_counter_value2, 0x00);
|
||||
}
|
||||
|
||||
/**
|
||||
* Changes the baud rate of the RFM22B peripheral without re-initialising.
|
||||
* \param[in] rfm22b_id RFM22B name (GPS, TELEM, AUX)
|
||||
* \param[in] baud Requested baud rate
|
||||
*/
|
||||
static void PIOS_RFM22B_ChangeBaud(uint32_t rfm22b_id, uint32_t baud)
|
||||
void PIOS_RFM22B_SetDatarate(uint32_t rfm22b_id, enum rfm22b_datarate datarate, bool data_whitening)
|
||||
{
|
||||
struct pios_rfm22b_dev * rfm22b_dev = (struct pios_rfm22b_dev *)rfm22b_id;
|
||||
if(!PIOS_RFM22B_validate(rfm22b_dev))
|
||||
return;
|
||||
rfm22b_dev->datarate = datarate;
|
||||
|
||||
bool valid = PIOS_RFM22B_validate(rfm22b_dev);
|
||||
PIOS_Assert(valid);
|
||||
|
||||
}
|
||||
|
||||
static void PIOS_RFM22B_RegisterRxCallback(uint32_t rfm22b_id, pios_com_callback rx_in_cb, uint32_t context)
|
||||
{
|
||||
struct pios_rfm22b_dev * rfm22b_dev = (struct pios_rfm22b_dev *)rfm22b_id;
|
||||
|
||||
bool valid = PIOS_RFM22B_validate(rfm22b_dev);
|
||||
PIOS_Assert(valid);
|
||||
|
||||
/*
|
||||
* Order is important in these assignments since ISR uses _cb
|
||||
* field to determine if it's ok to dereference _cb and _context
|
||||
*/
|
||||
rfm22b_dev->rx_in_context = context;
|
||||
rfm22b_dev->rx_in_cb = rx_in_cb;
|
||||
}
|
||||
|
||||
static void PIOS_RFM22B_RegisterTxCallback(uint32_t rfm22b_id, pios_com_callback tx_out_cb, uint32_t context)
|
||||
{
|
||||
struct pios_rfm22b_dev * rfm22b_dev = (struct pios_rfm22b_dev *)rfm22b_id;
|
||||
|
||||
bool valid = PIOS_RFM22B_validate(rfm22b_dev);
|
||||
PIOS_Assert(valid);
|
||||
|
||||
/*
|
||||
* Order is important in these assignments since ISR uses _cb
|
||||
* field to determine if it's ok to dereference _cb and _context
|
||||
*/
|
||||
rfm22b_dev->tx_out_context = context;
|
||||
rfm22b_dev->tx_out_cb = tx_out_cb;
|
||||
// Re-initialize the radio device.
|
||||
PIOS_RFM22B_InjectEvent(rfm22b_dev, RFM22B_EVENT_INITIALIZE, false);
|
||||
}
|
||||
|
||||
// ************************************
|
||||
// SPI read/write
|
||||
|
||||
//! Assert the CS line
|
||||
static void rfm22_assertCs()
|
||||
static void rfm22_assertCs(struct pios_rfm22b_dev *rfm22b_dev)
|
||||
{
|
||||
PIOS_DELAY_WaituS(1);
|
||||
if(PIOS_RFM22B_validate(g_rfm22b_dev) && g_rfm22b_dev->spi_id != 0)
|
||||
PIOS_SPI_RC_PinSet(g_rfm22b_dev->spi_id, g_rfm22b_dev->slave_num, 0);
|
||||
if(rfm22b_dev->spi_id != 0)
|
||||
PIOS_SPI_RC_PinSet(rfm22b_dev->spi_id, rfm22b_dev->slave_num, 0);
|
||||
}
|
||||
|
||||
//! Deassert the CS line
|
||||
static void rfm22_deassertCs()
|
||||
static void rfm22_deassertCs(struct pios_rfm22b_dev *rfm22b_dev)
|
||||
{
|
||||
if(PIOS_RFM22B_validate(g_rfm22b_dev) && g_rfm22b_dev->spi_id != 0)
|
||||
PIOS_SPI_RC_PinSet(g_rfm22b_dev->spi_id, g_rfm22b_dev->slave_num, 1);
|
||||
if(rfm22b_dev->spi_id != 0)
|
||||
PIOS_SPI_RC_PinSet(rfm22b_dev->spi_id, rfm22b_dev->slave_num, 1);
|
||||
}
|
||||
|
||||
//! Claim the SPI bus semaphore
|
||||
static void rfm22_claimBus()
|
||||
static void rfm22_claimBus(struct pios_rfm22b_dev *rfm22b_dev)
|
||||
{
|
||||
if(PIOS_RFM22B_validate(g_rfm22b_dev) && g_rfm22b_dev->spi_id != 0)
|
||||
PIOS_SPI_ClaimBus(g_rfm22b_dev->spi_id);
|
||||
if(rfm22b_dev->spi_id != 0)
|
||||
PIOS_SPI_ClaimBus(rfm22b_dev->spi_id);
|
||||
}
|
||||
|
||||
//! Release the SPI bus semaphore
|
||||
static void rfm22_releaseBus()
|
||||
static void rfm22_releaseBus(struct pios_rfm22b_dev *rfm22b_dev)
|
||||
{
|
||||
if(PIOS_RFM22B_validate(g_rfm22b_dev) && g_rfm22b_dev->spi_id != 0)
|
||||
PIOS_SPI_ReleaseBus(g_rfm22b_dev->spi_id);
|
||||
if(rfm22b_dev->spi_id != 0)
|
||||
PIOS_SPI_ReleaseBus(rfm22b_dev->spi_id);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1061,16 +1070,14 @@ static void rfm22_releaseBus()
|
||||
* @param[in] addr The address to write to
|
||||
* @param[in] data The datat to write to that address
|
||||
*/
|
||||
static void rfm22_write(uint8_t addr, uint8_t data)
|
||||
static void rfm22_write(struct pios_rfm22b_dev *rfm22b_dev, uint8_t addr, uint8_t data)
|
||||
{
|
||||
if(PIOS_RFM22B_validate(g_rfm22b_dev)) {
|
||||
rfm22_claimBus();
|
||||
rfm22_assertCs();
|
||||
uint8_t buf[2] = {addr | 0x80, data};
|
||||
PIOS_SPI_TransferBlock(g_rfm22b_dev->spi_id, buf, NULL, sizeof(buf), NULL);
|
||||
rfm22_deassertCs();
|
||||
rfm22_releaseBus();
|
||||
}
|
||||
rfm22_claimBus(rfm22b_dev);
|
||||
rfm22_assertCs(rfm22b_dev);
|
||||
uint8_t buf[2] = {addr | 0x80, data};
|
||||
PIOS_SPI_TransferBlock(rfm22b_dev->spi_id, buf, NULL, sizeof(buf), NULL);
|
||||
rfm22_deassertCs(rfm22b_dev);
|
||||
rfm22_releaseBus(rfm22b_dev);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1078,14 +1085,12 @@ static void rfm22_write(uint8_t addr, uint8_t data)
|
||||
* toggle the NSS line
|
||||
* @param[in] addr The address of the RFM22b register to write
|
||||
* @param[in] data The data to write to that register
|
||||
static void rfm22_write_noclaim(uint8_t addr, uint8_t data)
|
||||
static void rfm22_write_noclaim(struct pios_rfm22b_dev *rfm22b_dev, uint8_t addr, uint8_t data)
|
||||
{
|
||||
uint8_t buf[2] = {addr | 0x80, data};
|
||||
if(PIOS_RFM22B_validate(g_rfm22b_dev)) {
|
||||
rfm22_assertCs();
|
||||
PIOS_SPI_TransferBlock(g_rfm22b_dev->spi_id, buf, NULL, sizeof(buf), NULL);
|
||||
rfm22_deassertCs();
|
||||
}
|
||||
rfm22_assertCs(rfm22b_dev);
|
||||
PIOS_SPI_TransferBlock(rfm22b_dev->spi_id, buf, NULL, sizeof(buf), NULL);
|
||||
rfm22_deassertCs(rfm22b_dev);
|
||||
}
|
||||
*/
|
||||
|
||||
@ -1095,17 +1100,15 @@ static void rfm22_write_noclaim(uint8_t addr, uint8_t data)
|
||||
* @param[in] addr The address to read from
|
||||
* @return Returns the result of the register read
|
||||
*/
|
||||
static uint8_t rfm22_read(uint8_t addr)
|
||||
static uint8_t rfm22_read(struct pios_rfm22b_dev *rfm22b_dev, uint8_t addr)
|
||||
{
|
||||
uint8_t in[2];
|
||||
uint8_t out[2] = {addr & 0x7f, 0xFF};
|
||||
if(PIOS_RFM22B_validate(g_rfm22b_dev)) {
|
||||
rfm22_claimBus();
|
||||
rfm22_assertCs();
|
||||
PIOS_SPI_TransferBlock(g_rfm22b_dev->spi_id, out, in, sizeof(out), NULL);
|
||||
rfm22_deassertCs();
|
||||
rfm22_releaseBus();
|
||||
}
|
||||
rfm22_claimBus(rfm22b_dev);
|
||||
rfm22_assertCs(rfm22b_dev);
|
||||
PIOS_SPI_TransferBlock(rfm22b_dev->spi_id, out, in, sizeof(out), NULL);
|
||||
rfm22_deassertCs(rfm22b_dev);
|
||||
rfm22_releaseBus(rfm22b_dev);
|
||||
return in[1];
|
||||
}
|
||||
|
||||
@ -1114,15 +1117,13 @@ static uint8_t rfm22_read(uint8_t addr)
|
||||
* @param[in] addr The address to read from
|
||||
* @return Returns the result of the register read
|
||||
*/
|
||||
static uint8_t rfm22_read_noclaim(uint8_t addr)
|
||||
static uint8_t rfm22_read_noclaim(struct pios_rfm22b_dev *rfm22b_dev, uint8_t addr)
|
||||
{
|
||||
uint8_t out[2] = {addr & 0x7F, 0xFF};
|
||||
uint8_t in[2];
|
||||
if (PIOS_RFM22B_validate(g_rfm22b_dev)) {
|
||||
rfm22_assertCs();
|
||||
PIOS_SPI_TransferBlock(g_rfm22b_dev->spi_id, out, in, sizeof(out), NULL);
|
||||
rfm22_deassertCs();
|
||||
}
|
||||
rfm22_assertCs(rfm22b_dev);
|
||||
PIOS_SPI_TransferBlock(rfm22b_dev->spi_id, out, in, sizeof(out), NULL);
|
||||
rfm22_deassertCs(rfm22b_dev);
|
||||
return in[1];
|
||||
}
|
||||
|
||||
@ -1159,16 +1160,21 @@ static enum pios_rfm22b_event rfm22_process_state_transition(struct pios_rfm22b_
|
||||
return RFM22B_EVENT_NUM_EVENTS;
|
||||
}
|
||||
|
||||
static void rfm22_process_event(struct pios_rfm22b_dev *rfm22b_dev, enum pios_rfm22b_event event)
|
||||
{
|
||||
// Process all state transitions.
|
||||
while(event != RFM22B_EVENT_NUM_EVENTS)
|
||||
event = rfm22_process_state_transition(rfm22b_dev, event);
|
||||
}
|
||||
|
||||
// ************************************
|
||||
|
||||
static void rfm22_setNominalCarrierFrequency(struct pios_rfm22b_dev *rfm22b_dev, uint32_t frequency_hz)
|
||||
{
|
||||
uint32_t min_frequency_hz = rfm22b_dev->cfg.minFrequencyHz;
|
||||
uint32_t max_frequency_hz = rfm22b_dev->cfg.maxFrequencyHz;
|
||||
if (frequency_hz < min_frequency_hz)
|
||||
frequency_hz = min_frequency_hz;
|
||||
else if (frequency_hz > max_frequency_hz)
|
||||
frequency_hz = max_frequency_hz;
|
||||
if (frequency_hz < rfm22b_dev->min_frequency)
|
||||
frequency_hz = rfm22b_dev->min_frequency;
|
||||
else if (frequency_hz > rfm22b_dev->max_frequency)
|
||||
frequency_hz = rfm22b_dev->max_frequency;
|
||||
|
||||
// holds the hbsel (1 or 2)
|
||||
uint8_t hbsel;
|
||||
@ -1192,126 +1198,89 @@ static void rfm22_setNominalCarrierFrequency(struct pios_rfm22b_dev *rfm22b_dev,
|
||||
rfm22b_dev->frequency_step_size = 156.25f * hbsel;
|
||||
|
||||
// frequency hopping channel (0-255)
|
||||
rfm22_write(RFM22_frequency_hopping_channel_select, rfm22b_dev->frequency_hop_channel);
|
||||
rfm22_write(rfm22b_dev, RFM22_frequency_hopping_channel_select, rfm22b_dev->frequency_hop_channel);
|
||||
|
||||
// no frequency offset
|
||||
rfm22_write(RFM22_frequency_offset1, 0);
|
||||
rfm22_write(rfm22b_dev, RFM22_frequency_offset1, 0);
|
||||
// no frequency offset
|
||||
rfm22_write(RFM22_frequency_offset2, 0);
|
||||
rfm22_write(rfm22b_dev, RFM22_frequency_offset2, 0);
|
||||
|
||||
// set the carrier frequency
|
||||
rfm22_write(RFM22_frequency_band_select, fb);
|
||||
rfm22_write(RFM22_nominal_carrier_frequency1, fc >> 8);
|
||||
rfm22_write(RFM22_nominal_carrier_frequency0, fc & 0xff);
|
||||
rfm22_write(rfm22b_dev, RFM22_frequency_band_select, fb);
|
||||
rfm22_write(rfm22b_dev, RFM22_nominal_carrier_frequency1, fc >> 8);
|
||||
rfm22_write(rfm22b_dev, RFM22_nominal_carrier_frequency0, fc & 0xff);
|
||||
}
|
||||
|
||||
void rfm22_setFreqHopChannel(uint8_t channel)
|
||||
/*
|
||||
static void rfm22_setFreqHopChannel(uint8_t channel)
|
||||
{ // set the frequency hopping channel
|
||||
g_rfm22b_dev->frequency_hop_channel = channel;
|
||||
rfm22_write(RFM22_frequency_hopping_channel_select, channel);
|
||||
rfm22_write(rfm22b_dev, RFM22_frequency_hopping_channel_select, channel);
|
||||
}
|
||||
|
||||
uint32_t rfm22_freqHopSize(void)
|
||||
static uint32_t rfm22_freqHopSize(void)
|
||||
{ // return the frequency hopping step size
|
||||
return ((uint32_t)g_rfm22b_dev->frequency_hop_step_size_reg * 10000);
|
||||
}
|
||||
|
||||
// ************************************
|
||||
// radio datarate about 19200 Baud
|
||||
// radio frequency deviation 45kHz
|
||||
// radio receiver bandwidth 67kHz.
|
||||
//
|
||||
// Carson's rule:
|
||||
// The signal bandwidth is about 2(Delta-f + fm) ..
|
||||
//
|
||||
// Delta-f = frequency deviation
|
||||
// fm = maximum frequency of the signal
|
||||
//
|
||||
// This gives 2(45 + 9.6) = 109.2kHz.
|
||||
|
||||
void RFM22_SetDatarate(uint32_t rfm22b_id, enum rfm22b_datarate datarate, bool data_whitening)
|
||||
{
|
||||
struct pios_rfm22b_dev * rfm22b_dev = (struct pios_rfm22b_dev *)rfm22b_id;
|
||||
if(!PIOS_RFM22B_validate(rfm22b_dev))
|
||||
return;
|
||||
|
||||
uint32_t datarate_bps = data_rate[datarate];
|
||||
rfm22b_dev->datarate = datarate;
|
||||
rfm22b_dev->max_packet_time = (uint16_t)((float)(PIOS_PH_MAX_PACKET * 8 * 1000) / (float)(datarate_bps) + 0.5);
|
||||
|
||||
// rfm22_if_filter_bandwidth
|
||||
rfm22_write(0x1C, reg_1C[datarate]);
|
||||
|
||||
// rfm22_afc_loop_gearshift_override
|
||||
rfm22_write(0x1D, reg_1D[datarate]);
|
||||
// RFM22_afc_timing_control
|
||||
rfm22_write(0x1E, reg_1E[datarate]);
|
||||
|
||||
// RFM22_clk_recovery_gearshift_override
|
||||
rfm22_write(0x1F, reg_1F[datarate]);
|
||||
// rfm22_clk_recovery_oversampling_ratio
|
||||
rfm22_write(0x20, reg_20[datarate]);
|
||||
// rfm22_clk_recovery_offset2
|
||||
rfm22_write(0x21, reg_21[datarate]);
|
||||
// rfm22_clk_recovery_offset1
|
||||
rfm22_write(0x22, reg_22[datarate]);
|
||||
// rfm22_clk_recovery_offset0
|
||||
rfm22_write(0x23, reg_23[datarate]);
|
||||
// rfm22_clk_recovery_timing_loop_gain1
|
||||
rfm22_write(0x24, reg_24[datarate]);
|
||||
// rfm22_clk_recovery_timing_loop_gain0
|
||||
rfm22_write(0x25, reg_25[datarate]);
|
||||
|
||||
// rfm22_afc_limiter
|
||||
rfm22_write(0x2A, reg_2A[datarate]);
|
||||
|
||||
/* This breaks all bit rates < 100000!
|
||||
if (datarate_bps < 100000)
|
||||
// rfm22_chargepump_current_trimming_override
|
||||
rfm22_write(0x58, 0x80);
|
||||
else
|
||||
// rfm22_chargepump_current_trimming_override
|
||||
rfm22_write(0x58, 0xC0);
|
||||
*/
|
||||
|
||||
// rfm22_tx_data_rate1
|
||||
rfm22_write(0x6E, reg_6E[datarate]);
|
||||
// rfm22_tx_data_rate0
|
||||
rfm22_write(0x6F, reg_6F[datarate]);
|
||||
static void rfm22_calculateLinkQuality(struct pios_rfm22b_dev *rfm22b_dev)
|
||||
{
|
||||
// Add the RX packet statistics
|
||||
rfm22b_dev->stats.rx_good = 0;
|
||||
rfm22b_dev->stats.rx_corrected = 0;
|
||||
rfm22b_dev->stats.rx_error = 0;
|
||||
rfm22b_dev->stats.tx_resent = 0;
|
||||
for (uint8_t i = 0; i < RFM22B_RX_PACKET_STATS_LEN; ++i)
|
||||
{
|
||||
uint32_t val = rfm22b_dev->rx_packet_stats[i];
|
||||
for (uint8_t j = 0; j < 16; ++j)
|
||||
{
|
||||
switch ((val >> (j * 2)) & 0x3)
|
||||
{
|
||||
case RFM22B_GOOD_RX_PACKET:
|
||||
rfm22b_dev->stats.rx_good++;
|
||||
break;
|
||||
case RFM22B_CORRECTED_RX_PACKET:
|
||||
rfm22b_dev->stats.rx_corrected++;
|
||||
break;
|
||||
case RFM22B_ERROR_RX_PACKET:
|
||||
rfm22b_dev->stats.rx_error++;
|
||||
break;
|
||||
case RFM22B_RESENT_TX_PACKET:
|
||||
rfm22b_dev->stats.tx_resent++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Enable data whitening
|
||||
// uint8_t txdtrtscale_bit = rfm22_read(RFM22_modulation_mode_control1) & RFM22_mmc1_txdtrtscale;
|
||||
// rfm22_write(RFM22_modulation_mode_control1, txdtrtscale_bit | RFM22_mmc1_enwhite);
|
||||
|
||||
if (!data_whitening)
|
||||
// rfm22_modulation_mode_control1
|
||||
rfm22_write(0x70, reg_70[datarate] & ~RFM22_mmc1_enwhite);
|
||||
else
|
||||
// rfm22_modulation_mode_control1
|
||||
rfm22_write(0x70, reg_70[datarate] | RFM22_mmc1_enwhite);
|
||||
|
||||
// rfm22_modulation_mode_control2
|
||||
rfm22_write(0x71, reg_71[datarate]);
|
||||
|
||||
// rfm22_frequency_deviation
|
||||
rfm22_write(0x72, reg_72[datarate]);
|
||||
|
||||
rfm22_write(RFM22_ook_counter_value1, 0x00);
|
||||
rfm22_write(RFM22_ook_counter_value2, 0x00);
|
||||
// Calculate the link quality metric, which is related to the number of good packets in relation to the number of bad packets.
|
||||
// Note: This assumes that the number of packets sampled for the stats is 64.
|
||||
// Using this equation, error and resent packets are counted as -2, and corrected packets are counted as -1.
|
||||
// The range is 0 (all error or resent packets) to 128 (all good packets).
|
||||
rfm22b_dev->stats.link_quality = 64 + rfm22b_dev->stats.rx_good - rfm22b_dev->stats.rx_error - rfm22b_dev->stats.tx_resent;
|
||||
}
|
||||
|
||||
// ************************************
|
||||
|
||||
static enum pios_rfm22b_event rfm22_setRxMode(struct pios_rfm22b_dev *rfm22b_dev)
|
||||
{
|
||||
// Are we already in Rx mode?
|
||||
if (rfm22b_dev->in_rx_mode)
|
||||
return RFM22B_EVENT_NUM_EVENTS;
|
||||
|
||||
rfm22b_dev->packet_start_ticks = 0;
|
||||
#ifdef PIOS_RFM22B_DEBUG_ON_TELEM
|
||||
D2_LED_ON;
|
||||
D3_LED_TOGGLE;
|
||||
#endif
|
||||
|
||||
// disable interrupts
|
||||
rfm22_write(RFM22_interrupt_enable1, 0x00);
|
||||
rfm22_write(RFM22_interrupt_enable2, 0x00);
|
||||
rfm22_write(rfm22b_dev, RFM22_interrupt_enable1, 0x00);
|
||||
rfm22_write(rfm22b_dev, RFM22_interrupt_enable2, 0x00);
|
||||
|
||||
// Switch to TUNE mode
|
||||
rfm22_write(RFM22_op_and_func_ctrl1, RFM22_opfc1_pllon);
|
||||
rfm22_write(rfm22b_dev, RFM22_op_and_func_ctrl1, RFM22_opfc1_pllon);
|
||||
|
||||
RX_LED_OFF;
|
||||
TX_LED_OFF;
|
||||
@ -1323,17 +1292,20 @@ static enum pios_rfm22b_event rfm22_setRxMode(struct pios_rfm22b_dev *rfm22b_dev
|
||||
rfm22b_dev->tx_data_rd = rfm22b_dev->tx_data_wr = 0;
|
||||
|
||||
// clear FIFOs
|
||||
rfm22_write(RFM22_op_and_func_ctrl2, RFM22_opfc2_ffclrrx | RFM22_opfc2_ffclrtx);
|
||||
rfm22_write(RFM22_op_and_func_ctrl2, 0x00);
|
||||
rfm22_write(rfm22b_dev, RFM22_op_and_func_ctrl2, RFM22_opfc2_ffclrrx | RFM22_opfc2_ffclrtx);
|
||||
rfm22_write(rfm22b_dev, RFM22_op_and_func_ctrl2, 0x00);
|
||||
|
||||
// enable RX interrupts
|
||||
rfm22_write(RFM22_interrupt_enable1, RFM22_ie1_encrcerror | RFM22_ie1_enpkvalid |
|
||||
rfm22_write(rfm22b_dev, RFM22_interrupt_enable1, RFM22_ie1_encrcerror | RFM22_ie1_enpkvalid |
|
||||
RFM22_ie1_enrxffafull | RFM22_ie1_enfferr);
|
||||
rfm22_write(RFM22_interrupt_enable2, RFM22_ie2_enpreainval | RFM22_ie2_enpreaval |
|
||||
rfm22_write(rfm22b_dev, RFM22_interrupt_enable2, RFM22_ie2_enpreainval | RFM22_ie2_enpreaval |
|
||||
RFM22_ie2_enswdet);
|
||||
|
||||
// enable the receiver
|
||||
rfm22_write(RFM22_op_and_func_ctrl1, RFM22_opfc1_pllon | RFM22_opfc1_rxon);
|
||||
rfm22_write(rfm22b_dev, RFM22_op_and_func_ctrl1, RFM22_opfc1_pllon | RFM22_opfc1_rxon);
|
||||
|
||||
// Indicate that we're in RX mode.
|
||||
rfm22b_dev->in_rx_mode = true;
|
||||
|
||||
// No event generated
|
||||
return RFM22B_EVENT_NUM_EVENTS;
|
||||
@ -1341,20 +1313,99 @@ static enum pios_rfm22b_event rfm22_setRxMode(struct pios_rfm22b_dev *rfm22b_dev
|
||||
|
||||
// ************************************
|
||||
|
||||
static bool rfm22_ready_to_send(struct pios_rfm22b_dev *rfm22b_dev)
|
||||
{
|
||||
// Is there a status of PPM packet ready to send?
|
||||
if (rfm22b_dev->prev_tx_packet || rfm22b_dev->send_ppm || rfm22b_dev->send_status)
|
||||
return true;
|
||||
|
||||
// Is there some data ready to sent?
|
||||
PHPacketHandle dp = &rfm22b_dev->data_packet;
|
||||
if (dp->header.data_size > 0)
|
||||
return true;
|
||||
bool need_yield = false;
|
||||
if (rfm22b_dev->tx_out_cb)
|
||||
dp->header.data_size = (rfm22b_dev->tx_out_cb)(rfm22b_dev->tx_out_context, dp->data, PH_MAX_DATA, NULL, &need_yield);
|
||||
if (dp->header.data_size > 0)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static enum pios_rfm22b_event rfm22_txStart(struct pios_rfm22b_dev *rfm22b_dev)
|
||||
{
|
||||
// See if there's a packet on the packet queue.
|
||||
PHPacketHandle p;
|
||||
if (xQueueReceive(rfm22b_dev->packetQueue, &p, 0) != pdTRUE)
|
||||
{
|
||||
// Clear the TX buffer.
|
||||
rfm22b_dev->tx_data_rd = rfm22b_dev->tx_data_wr = 0;
|
||||
PHPacketHandle p = NULL;
|
||||
|
||||
// Don't send if it's not our turn.
|
||||
if (!rfm22b_dev->time_to_send)
|
||||
return RFM22B_EVENT_RX_MODE;
|
||||
|
||||
// See if there's a packet ready to send.
|
||||
if (rfm22b_dev->tx_packet)
|
||||
p = rfm22b_dev->tx_packet;
|
||||
|
||||
// Are we waiting for an ACK?
|
||||
else
|
||||
{
|
||||
|
||||
// Don't send a packet if we're waiting for an ACK
|
||||
if (rfm22b_dev->prev_tx_packet)
|
||||
return RFM22B_EVENT_RX_MODE;
|
||||
|
||||
if (!p && rfm22b_dev->send_connection_request)
|
||||
{
|
||||
p = (PHPacketHandle)&(rfm22b_dev->con_packet);
|
||||
rfm22b_dev->send_connection_request = false;
|
||||
}
|
||||
|
||||
#ifdef PIOS_PPM_RECEIVER
|
||||
if (!p && rfm22b_dev->send_ppm)
|
||||
{
|
||||
p = (PHPacketHandle)&(rfm22b_dev->ppm_packet);
|
||||
rfm22b_dev->send_ppm = false;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!p && rfm22b_dev->send_status)
|
||||
{
|
||||
p = (PHPacketHandle)&(rfm22b_dev->status_packet);
|
||||
rfm22b_dev->send_status = false;
|
||||
}
|
||||
|
||||
if (!p)
|
||||
{
|
||||
// Try to get some data to send
|
||||
bool need_yield = false;
|
||||
p = &rfm22b_dev->data_packet;
|
||||
p->header.type = PACKET_TYPE_DATA;
|
||||
p->header.destination_id = rfm22b_dev->destination_id;
|
||||
if (rfm22b_dev->tx_out_cb && (p->header.data_size == 0))
|
||||
p->header.data_size = (rfm22b_dev->tx_out_cb)(rfm22b_dev->tx_out_context, p->data, PH_MAX_DATA, NULL, &need_yield);
|
||||
|
||||
// Don't send any data until we're connected.
|
||||
if (rfm22b_dev->stats.link_state != OPLINKSTATUS_LINKSTATE_CONNECTED)
|
||||
p->header.data_size = 0;
|
||||
if (p->header.data_size == 0)
|
||||
p = NULL;
|
||||
}
|
||||
|
||||
if (p)
|
||||
p->header.seq_num = rfm22b_dev->stats.tx_seq++;
|
||||
}
|
||||
if (!p)
|
||||
return RFM22B_EVENT_RX_MODE;
|
||||
|
||||
// We're transitioning out of Rx mode.
|
||||
rfm22b_dev->in_rx_mode = false;
|
||||
|
||||
#ifdef PIOS_RFM22B_DEBUG_ON_TELEM
|
||||
D1_LED_ON;
|
||||
D2_LED_OFF;
|
||||
D3_LED_TOGGLE;
|
||||
#endif
|
||||
|
||||
// Add the error correcting code.
|
||||
p->header.source_id = rfm22b_dev->deviceID;
|
||||
p->header.seq_num = rfm22b_dev->tx_packet_count++;
|
||||
encode_data((unsigned char*)p, PHPacketSize(p), (unsigned char*)p);
|
||||
|
||||
rfm22b_dev->tx_packet = p;
|
||||
@ -1363,11 +1414,11 @@ static enum pios_rfm22b_event rfm22_txStart(struct pios_rfm22b_dev *rfm22b_dev)
|
||||
rfm22b_dev->packet_start_ticks = 1;
|
||||
|
||||
// disable interrupts
|
||||
rfm22_write(RFM22_interrupt_enable1, 0x00);
|
||||
rfm22_write(RFM22_interrupt_enable2, 0x00);
|
||||
rfm22_write(rfm22b_dev, RFM22_interrupt_enable1, 0x00);
|
||||
rfm22_write(rfm22b_dev, RFM22_interrupt_enable2, 0x00);
|
||||
|
||||
// TUNE mode
|
||||
rfm22_write(RFM22_op_and_func_ctrl1, RFM22_opfc1_pllon);
|
||||
rfm22_write(rfm22b_dev, RFM22_op_and_func_ctrl1, RFM22_opfc1_pllon);
|
||||
|
||||
// Queue the data up for sending
|
||||
rfm22b_dev->tx_data_wr = PH_PACKET_SIZE(rfm22b_dev->tx_packet);
|
||||
@ -1377,77 +1428,105 @@ static enum pios_rfm22b_event rfm22_txStart(struct pios_rfm22b_dev *rfm22b_dev)
|
||||
// Set the destination address in the transmit header.
|
||||
// The destination address is the first 4 bytes of the message.
|
||||
uint8_t *tx_buffer = (uint8_t*)(rfm22b_dev->tx_packet);
|
||||
rfm22_write(RFM22_transmit_header0, tx_buffer[0]);
|
||||
rfm22_write(RFM22_transmit_header1, tx_buffer[1]);
|
||||
rfm22_write(RFM22_transmit_header2, tx_buffer[2]);
|
||||
rfm22_write(RFM22_transmit_header3, tx_buffer[3]);
|
||||
rfm22_write(rfm22b_dev, RFM22_transmit_header0, tx_buffer[0]);
|
||||
rfm22_write(rfm22b_dev, RFM22_transmit_header1, tx_buffer[1]);
|
||||
rfm22_write(rfm22b_dev, RFM22_transmit_header2, tx_buffer[2]);
|
||||
rfm22_write(rfm22b_dev, RFM22_transmit_header3, tx_buffer[3]);
|
||||
|
||||
// FIFO mode, GFSK modulation
|
||||
uint8_t fd_bit = rfm22_read(RFM22_modulation_mode_control2) & RFM22_mmc2_fd;
|
||||
rfm22_write(RFM22_modulation_mode_control2, fd_bit | RFM22_mmc2_dtmod_fifo |
|
||||
uint8_t fd_bit = rfm22_read(rfm22b_dev, RFM22_modulation_mode_control2) & RFM22_mmc2_fd;
|
||||
rfm22_write(rfm22b_dev, RFM22_modulation_mode_control2, fd_bit | RFM22_mmc2_dtmod_fifo |
|
||||
RFM22_mmc2_modtyp_gfsk);
|
||||
|
||||
// set the tx power
|
||||
rfm22_write(RFM22_tx_power, RFM22_tx_pwr_papeaken | RFM22_tx_pwr_papeaklvl_1 |
|
||||
RFM22_tx_pwr_papeaklvl_0 | RFM22_tx_pwr_lna_sw | g_rfm22b_dev->tx_power);
|
||||
rfm22_write(rfm22b_dev, RFM22_tx_power, RFM22_tx_pwr_papeaken | RFM22_tx_pwr_papeaklvl_1 |
|
||||
RFM22_tx_pwr_papeaklvl_0 | RFM22_tx_pwr_lna_sw | rfm22b_dev->tx_power);
|
||||
|
||||
// clear FIFOs
|
||||
rfm22_write(RFM22_op_and_func_ctrl2, RFM22_opfc2_ffclrrx | RFM22_opfc2_ffclrtx);
|
||||
rfm22_write(RFM22_op_and_func_ctrl2, 0x00);
|
||||
rfm22_write(rfm22b_dev, RFM22_op_and_func_ctrl2, RFM22_opfc2_ffclrrx | RFM22_opfc2_ffclrtx);
|
||||
rfm22_write(rfm22b_dev, RFM22_op_and_func_ctrl2, 0x00);
|
||||
|
||||
// *******************
|
||||
// add some data to the chips TX FIFO before enabling the transmitter
|
||||
|
||||
// set the total number of data bytes we are going to transmit
|
||||
rfm22_write(RFM22_transmit_packet_length, rfm22b_dev->tx_data_wr);
|
||||
rfm22_write(rfm22b_dev, RFM22_transmit_packet_length, rfm22b_dev->tx_data_wr);
|
||||
|
||||
// add some data
|
||||
rfm22_claimBus();
|
||||
rfm22_assertCs();
|
||||
PIOS_SPI_TransferByte(g_rfm22b_dev->spi_id, RFM22_fifo_access | 0x80);
|
||||
rfm22_claimBus(rfm22b_dev);
|
||||
rfm22_assertCs(rfm22b_dev);
|
||||
PIOS_SPI_TransferByte(rfm22b_dev->spi_id, RFM22_fifo_access | 0x80);
|
||||
int bytes_to_write = (rfm22b_dev->tx_data_wr - rfm22b_dev->tx_data_rd);
|
||||
bytes_to_write = (bytes_to_write > FIFO_SIZE) ? FIFO_SIZE: bytes_to_write;
|
||||
PIOS_SPI_TransferBlock(g_rfm22b_dev->spi_id, &tx_buffer[rfm22b_dev->tx_data_rd], NULL, bytes_to_write, NULL);
|
||||
PIOS_SPI_TransferBlock(rfm22b_dev->spi_id, &tx_buffer[rfm22b_dev->tx_data_rd], NULL, bytes_to_write, NULL);
|
||||
rfm22b_dev->tx_data_rd += bytes_to_write;
|
||||
rfm22_deassertCs();
|
||||
rfm22_releaseBus();
|
||||
rfm22_deassertCs(rfm22b_dev);
|
||||
rfm22_releaseBus(rfm22b_dev);
|
||||
|
||||
// enable TX interrupts
|
||||
rfm22_write(RFM22_interrupt_enable1, RFM22_ie1_enpksent | RFM22_ie1_entxffaem);
|
||||
rfm22_write(rfm22b_dev, RFM22_interrupt_enable1, RFM22_ie1_enpksent | RFM22_ie1_entxffaem);
|
||||
|
||||
// enable the transmitter
|
||||
rfm22_write(RFM22_op_and_func_ctrl1, RFM22_opfc1_pllon | RFM22_opfc1_txon);
|
||||
rfm22_write(rfm22b_dev, RFM22_op_and_func_ctrl1, RFM22_opfc1_pllon | RFM22_opfc1_txon);
|
||||
|
||||
TX_LED_ON;
|
||||
|
||||
return RFM22B_EVENT_TX_STARTED;
|
||||
return RFM22B_EVENT_NUM_EVENTS;
|
||||
}
|
||||
|
||||
static bool rfm22_sendStatus(struct pios_rfm22b_dev *rfm22b_dev)
|
||||
static void rfm22_sendStatus(struct pios_rfm22b_dev *rfm22b_dev)
|
||||
{
|
||||
PHPacketHandle sph = (PHPacketHandle)&(rfm22b_dev->status_packet);
|
||||
// Only send status if we're connected
|
||||
if (rfm22b_dev->stats.link_state != OPLINKSTATUS_LINKSTATE_CONNECTED)
|
||||
return;
|
||||
|
||||
// Update the link quality metric.
|
||||
rfm22_calculateLinkQuality(rfm22b_dev);
|
||||
|
||||
// Queue the status message
|
||||
rfm22b_dev->status_packet.header.destination_id = 0xffffffff; // Broadcast
|
||||
if (rfm22b_dev->stats.link_state == OPLINKSTATUS_LINKSTATE_CONNECTED)
|
||||
rfm22b_dev->status_packet.header.destination_id = rfm22b_dev->destination_id;
|
||||
else
|
||||
rfm22b_dev->status_packet.header.destination_id = 0xffffffff; // Broadcast
|
||||
rfm22b_dev->status_packet.header.type = PACKET_TYPE_STATUS;
|
||||
rfm22b_dev->status_packet.header.data_size = PH_STATUS_DATA_SIZE(&(rfm22b_dev->status_packet));
|
||||
rfm22b_dev->status_packet.errors = rfm22b_dev->errors;
|
||||
rfm22b_dev->status_packet.resets = rfm22b_dev->resets;
|
||||
rfm22b_dev->status_packet.retries = 0;
|
||||
rfm22b_dev->status_packet.uavtalk_errors = 0;
|
||||
rfm22b_dev->status_packet.dropped = 0;
|
||||
if (xQueueSend(rfm22b_dev->packetQueue, &sph, 0) != pdTRUE)
|
||||
return false;
|
||||
rfm22b_dev->status_packet.link_quality = rfm22b_dev->stats.link_quality;
|
||||
rfm22b_dev->status_packet.received_rssi = rfm22b_dev->rssi_dBm;
|
||||
rfm22b_dev->send_status = true;
|
||||
|
||||
// Process a SEND_PACKT event.
|
||||
enum pios_rfm22b_event event = RFM22B_EVENT_SEND_PACKET;
|
||||
while(event != RFM22B_EVENT_NUM_EVENTS)
|
||||
event = rfm22_process_state_transition(rfm22b_dev, event);
|
||||
|
||||
return true;
|
||||
return;
|
||||
}
|
||||
|
||||
// ************************************
|
||||
static void rfm22_sendPPM(struct pios_rfm22b_dev *rfm22b_dev)
|
||||
{
|
||||
#ifdef PIOS_PPM_RECEIVER
|
||||
// Only send PPM if we're connected
|
||||
if (rfm22b_dev->stats.link_state != OPLINKSTATUS_LINKSTATE_CONNECTED)
|
||||
return;
|
||||
|
||||
// Just return if the PPM receiver is not configured.
|
||||
if (PIOS_PPM_RECEIVER == 0)
|
||||
return;
|
||||
|
||||
// See if we have any valid channels.
|
||||
bool valid_input_detected = false;
|
||||
for (uint8_t i = 1; i <= PIOS_PPM_NUM_INPUTS; ++i)
|
||||
{
|
||||
rfm22b_dev->ppm_packet.channels[i - 1] = PIOS_RCVR_Read(PIOS_PPM_RECEIVER, i);
|
||||
if(rfm22b_dev->ppm_packet.channels[i - 1] != PIOS_RCVR_TIMEOUT)
|
||||
valid_input_detected = true;
|
||||
}
|
||||
|
||||
// Send the PPM packet if it's valid
|
||||
if (valid_input_detected)
|
||||
{
|
||||
rfm22b_dev->ppm_packet.header.destination_id = rfm22b_dev->destination_id;
|
||||
rfm22b_dev->ppm_packet.header.type = PACKET_TYPE_PPM;
|
||||
rfm22b_dev->ppm_packet.header.data_size = PH_PPM_DATA_SIZE(&(rfm22b_dev->ppm_packet));
|
||||
rfm22b_dev->send_ppm = true;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* Read the RFM22B interrupt and device status registers
|
||||
@ -1457,23 +1536,23 @@ static bool rfm22_readStatus(struct pios_rfm22b_dev *rfm22b_dev)
|
||||
{
|
||||
|
||||
// 1. Read the interrupt statuses with burst read
|
||||
rfm22_claimBus(); // Set RC and the semaphore
|
||||
rfm22_claimBus(rfm22b_dev); // Set RC and the semaphore
|
||||
uint8_t write_buf[3] = {RFM22_interrupt_status1 & 0x7f, 0xFF, 0xFF};
|
||||
uint8_t read_buf[3];
|
||||
rfm22_assertCs();
|
||||
PIOS_SPI_TransferBlock(g_rfm22b_dev->spi_id, write_buf, read_buf, sizeof(write_buf), NULL);
|
||||
rfm22_deassertCs();
|
||||
rfm22_assertCs(rfm22b_dev);
|
||||
PIOS_SPI_TransferBlock(rfm22b_dev->spi_id, write_buf, read_buf, sizeof(write_buf), NULL);
|
||||
rfm22_deassertCs(rfm22b_dev);
|
||||
rfm22b_dev->int_status1 = read_buf[1];
|
||||
rfm22b_dev->int_status2 = read_buf[2];
|
||||
|
||||
// Device status
|
||||
rfm22b_dev->device_status = rfm22_read_noclaim(RFM22_device_status);
|
||||
rfm22b_dev->device_status = rfm22_read_noclaim(rfm22b_dev, RFM22_device_status);
|
||||
|
||||
// EzMAC status
|
||||
rfm22b_dev->ezmac_status = rfm22_read_noclaim(RFM22_ezmac_status);
|
||||
rfm22b_dev->ezmac_status = rfm22_read_noclaim(rfm22b_dev, RFM22_ezmac_status);
|
||||
|
||||
// Release the bus
|
||||
rfm22_releaseBus();
|
||||
rfm22_releaseBus(rfm22b_dev);
|
||||
|
||||
// the RF module has gone and done a reset - we need to re-initialize the rf module
|
||||
if (rfm22b_dev->int_status2 & RFM22_is2_ipor)
|
||||
@ -1482,12 +1561,26 @@ static bool rfm22_readStatus(struct pios_rfm22b_dev *rfm22b_dev)
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a status value to the RX packet status array.
|
||||
* \param[in] rfm22b_dev The device structure
|
||||
* \param[in] status The packet status value
|
||||
*/
|
||||
static void rfm22b_add_rx_status(struct pios_rfm22b_dev *rfm22b_dev, enum pios_rfm22b_rx_packet_status status)
|
||||
{
|
||||
// Shift the status registers
|
||||
for (uint8_t i = RFM22B_RX_PACKET_STATS_LEN - 1; i > 0; --i)
|
||||
{
|
||||
rfm22b_dev->rx_packet_stats[i] = (rfm22b_dev->rx_packet_stats[i] << 2) | (rfm22b_dev->rx_packet_stats[i - 1] >> 30);
|
||||
}
|
||||
rfm22b_dev->rx_packet_stats[0] = (rfm22b_dev->rx_packet_stats[0] << 2) | status;
|
||||
}
|
||||
|
||||
static enum pios_rfm22b_event rfm22_detectPreamble(struct pios_rfm22b_dev *rfm22b_dev)
|
||||
{
|
||||
|
||||
// Read the device status registers
|
||||
if (!rfm22_readStatus(rfm22b_dev))
|
||||
return RFM22B_EVENT_ERROR;
|
||||
return RFM22B_EVENT_FAILURE;
|
||||
|
||||
// Valid preamble detected
|
||||
if (rfm22b_dev->int_status2 & RFM22_is2_ipreaval)
|
||||
@ -1496,6 +1589,10 @@ static enum pios_rfm22b_event rfm22_detectPreamble(struct pios_rfm22b_dev *rfm22
|
||||
if (rfm22b_dev->packet_start_ticks == 0)
|
||||
rfm22b_dev->packet_start_ticks = 1;
|
||||
RX_LED_ON;
|
||||
|
||||
#ifdef PIOS_RFM22B_DEBUG_ON_TELEM
|
||||
D3_LED_TOGGLE;
|
||||
#endif
|
||||
return RFM22B_EVENT_PREAMBLE_DETECTED;
|
||||
}
|
||||
|
||||
@ -1507,7 +1604,7 @@ static enum pios_rfm22b_event rfm22_detectSync(struct pios_rfm22b_dev *rfm22b_de
|
||||
|
||||
// Read the device status registers
|
||||
if (!rfm22_readStatus(rfm22b_dev))
|
||||
return RFM22B_EVENT_ERROR;
|
||||
return RFM22B_EVENT_FAILURE;
|
||||
|
||||
// Sync word detected
|
||||
if (rfm22b_dev->int_status2 & RFM22_is2_iswdet)
|
||||
@ -1516,152 +1613,232 @@ static enum pios_rfm22b_event rfm22_detectSync(struct pios_rfm22b_dev *rfm22b_de
|
||||
|
||||
// read the 10-bit signed afc correction value
|
||||
// bits 9 to 2
|
||||
uint16_t afc_correction = (uint16_t)rfm22_read(RFM22_afc_correction_read) << 8;
|
||||
uint16_t afc_correction = (uint16_t)rfm22_read(rfm22b_dev, RFM22_afc_correction_read) << 8;
|
||||
// bits 1 & 0
|
||||
afc_correction |= (uint16_t)rfm22_read(RFM22_ook_counter_value1) & 0x00c0;
|
||||
afc_correction |= (uint16_t)rfm22_read(rfm22b_dev, RFM22_ook_counter_value1) & 0x00c0;
|
||||
afc_correction >>= 6;
|
||||
// convert the afc value to Hz
|
||||
rfm22b_dev->afc_correction_Hz = (int32_t)(rfm22b_dev->frequency_step_size * afc_correction + 0.5f);
|
||||
int32_t afc_corr = (int32_t)(rfm22b_dev->frequency_step_size * afc_correction + 0.5f);
|
||||
rfm22b_dev->afc_correction_Hz = (afc_corr < -127) ? -127 : ((afc_corr > 127) ? 127 : afc_corr);
|
||||
|
||||
// read rx signal strength .. 45 = -100dBm, 205 = -20dBm
|
||||
rfm22b_dev->rssi = rfm22_read(RFM22_rssi);
|
||||
uint8_t rssi = rfm22_read(rfm22b_dev, RFM22_rssi);
|
||||
// convert to dBm
|
||||
rfm22b_dev->rssi_dBm = (int8_t)(rfm22b_dev->rssi >> 1) - 122;
|
||||
|
||||
// remember the afc value for this packet
|
||||
rfm22b_dev->rx_packet_start_afc_Hz = rfm22b_dev->afc_correction_Hz;
|
||||
rfm22b_dev->rssi_dBm = (int8_t)(rssi >> 1) - 122;
|
||||
|
||||
return RFM22B_EVENT_SYNC_DETECTED;
|
||||
}
|
||||
else if (rfm22b_dev->int_status2 & !RFM22_is2_ipreaval)
|
||||
{
|
||||
// Waiting for sync timed out.
|
||||
return RFM22B_EVENT_TX_START;
|
||||
}
|
||||
return RFM22B_EVENT_FAILURE;
|
||||
|
||||
return RFM22B_EVENT_NUM_EVENTS;
|
||||
}
|
||||
|
||||
static bool rfm22_receivePacket(struct pios_rfm22b_dev *rfm22b_dev, PHPacketHandle p, uint16_t rx_len)
|
||||
{
|
||||
|
||||
// Attempt to correct any errors in the packet.
|
||||
decode_data((unsigned char*)p, rx_len);
|
||||
|
||||
bool good_packet = check_syndrome() == 0;
|
||||
bool corrected_packet = false;
|
||||
// We have an error. Try to correct it.
|
||||
if(!good_packet && (correct_errors_erasures((unsigned char*)p, rx_len, 0, 0) != 0))
|
||||
// We corrected it
|
||||
corrected_packet = true;
|
||||
|
||||
// Add any missed packets into the stats.
|
||||
bool ack_nack_packet = ((p->header.type == PACKET_TYPE_ACK) || (p->header.type == PACKET_TYPE_ACK_RTS) || (p->header.type == PACKET_TYPE_NACK));
|
||||
if (!ack_nack_packet && (good_packet || corrected_packet))
|
||||
{
|
||||
uint16_t seq_num = p->header.seq_num;
|
||||
if (rfm22b_dev->stats.link_state == OPLINKSTATUS_LINKSTATE_CONNECTED)
|
||||
{
|
||||
static bool first_time = true;
|
||||
uint16_t missed_packets = 0;
|
||||
if (first_time)
|
||||
first_time = false;
|
||||
else
|
||||
{
|
||||
uint16_t prev_seq_num = rfm22b_dev->stats.rx_seq;
|
||||
if (seq_num > prev_seq_num)
|
||||
missed_packets = seq_num - prev_seq_num - 1;
|
||||
else if((seq_num == prev_seq_num) && (p->header.type == PACKET_TYPE_DATA))
|
||||
p->header.type = PACKET_TYPE_DUPLICATE_DATA;
|
||||
}
|
||||
rfm22b_dev->stats.rx_missed += missed_packets;
|
||||
}
|
||||
rfm22b_dev->stats.rx_seq = seq_num;
|
||||
}
|
||||
|
||||
// Set the packet status
|
||||
if (good_packet)
|
||||
rfm22b_add_rx_status(rfm22b_dev, RFM22B_GOOD_RX_PACKET);
|
||||
else if(corrected_packet)
|
||||
// We corrected the error.
|
||||
rfm22b_add_rx_status(rfm22b_dev, RFM22B_CORRECTED_RX_PACKET);
|
||||
else
|
||||
// We couldn't correct the error, so drop the packet.
|
||||
rfm22b_add_rx_status(rfm22b_dev, RFM22B_ERROR_RX_PACKET);
|
||||
|
||||
return (good_packet || corrected_packet);
|
||||
}
|
||||
|
||||
static enum pios_rfm22b_event rfm22_rxData(struct pios_rfm22b_dev *rfm22b_dev)
|
||||
{
|
||||
// Swap in the next packet buffer if required.
|
||||
if (rfm22b_dev->rx_packet == NULL)
|
||||
{
|
||||
if (rfm22b_dev->rx_packet_next != NULL)
|
||||
rfm22b_dev->rx_packet = rfm22b_dev->rx_packet_next;
|
||||
else
|
||||
return RFM22B_EVENT_ERROR;
|
||||
}
|
||||
uint8_t *rx_buffer = (uint8_t*)(rfm22b_dev->rx_packet);
|
||||
uint8_t *rx_buffer = (uint8_t*)&(rfm22b_dev->rx_packet);
|
||||
|
||||
// Read the device status registers
|
||||
if (!rfm22_readStatus(rfm22b_dev))
|
||||
return RFM22B_EVENT_ERROR;
|
||||
return RFM22B_EVENT_FAILURE;
|
||||
|
||||
// FIFO under/over flow error. Restart RX mode.
|
||||
if (rfm22b_dev->device_status & (RFM22_ds_ffunfl | RFM22_ds_ffovfl))
|
||||
return RFM22B_EVENT_ERROR;
|
||||
if (rfm22b_dev->int_status1 & RFM22_is1_ifferr)
|
||||
return RFM22B_EVENT_FAILURE;
|
||||
|
||||
// RX FIFO almost full, it needs emptying
|
||||
if (rfm22b_dev->int_status1 & RFM22_is1_irxffafull)
|
||||
{
|
||||
// read data from the rf chips FIFO buffer
|
||||
// read the total length of the packet data
|
||||
uint16_t len = rfm22_read(RFM22_received_packet_length);
|
||||
uint16_t len = rfm22_read(rfm22b_dev, RFM22_received_packet_length);
|
||||
|
||||
// The received packet is going to be larger than the specified length
|
||||
if ((rfm22b_dev->rx_buffer_wr + RX_FIFO_HI_WATERMARK) > len)
|
||||
return RFM22B_EVENT_ERROR;
|
||||
return RFM22B_EVENT_FAILURE;
|
||||
|
||||
// Another packet length error.
|
||||
if (((rfm22b_dev->rx_buffer_wr + RX_FIFO_HI_WATERMARK) >= len) && !(rfm22b_dev->int_status1 & RFM22_is1_ipkvalid))
|
||||
return RFM22B_EVENT_ERROR;
|
||||
return RFM22B_EVENT_FAILURE;
|
||||
|
||||
// Fetch the data from the RX FIFO
|
||||
rfm22_claimBus();
|
||||
rfm22_assertCs();
|
||||
rfm22_claimBus(rfm22b_dev);
|
||||
rfm22_assertCs(rfm22b_dev);
|
||||
PIOS_SPI_TransferByte(rfm22b_dev->spi_id,RFM22_fifo_access & 0x7F);
|
||||
rfm22b_dev->rx_buffer_wr += (PIOS_SPI_TransferBlock(rfm22b_dev->spi_id ,OUT_FF, (uint8_t *)&rx_buffer[rfm22b_dev->rx_buffer_wr], RX_FIFO_HI_WATERMARK, NULL) == 0) ? RX_FIFO_HI_WATERMARK : 0;
|
||||
rfm22_deassertCs();
|
||||
rfm22_releaseBus();
|
||||
rfm22_deassertCs(rfm22b_dev);
|
||||
rfm22_releaseBus(rfm22b_dev);
|
||||
}
|
||||
|
||||
// CRC error .. discard the received data
|
||||
if (rfm22b_dev->int_status1 & RFM22_is1_icrerror)
|
||||
return RFM22B_EVENT_ERROR;
|
||||
return RFM22B_EVENT_FAILURE;
|
||||
|
||||
// Valid packet received
|
||||
if (rfm22b_dev->int_status1 & RFM22_is1_ipkvalid)
|
||||
{
|
||||
|
||||
// read the total length of the packet data
|
||||
uint32_t len = rfm22_read(RFM22_received_packet_length);
|
||||
uint32_t len = rfm22_read(rfm22b_dev, RFM22_received_packet_length);
|
||||
|
||||
// their must still be data in the RX FIFO we need to get
|
||||
if (rfm22b_dev->rx_buffer_wr < len)
|
||||
{
|
||||
int32_t bytes_to_read = len - rfm22b_dev->rx_buffer_wr;
|
||||
// Fetch the data from the RX FIFO
|
||||
rfm22_claimBus();
|
||||
rfm22_assertCs();
|
||||
rfm22_claimBus(rfm22b_dev);
|
||||
rfm22_assertCs(rfm22b_dev);
|
||||
PIOS_SPI_TransferByte(rfm22b_dev->spi_id,RFM22_fifo_access & 0x7F);
|
||||
rfm22b_dev->rx_buffer_wr += (PIOS_SPI_TransferBlock(rfm22b_dev->spi_id,OUT_FF, (uint8_t *)&rx_buffer[rfm22b_dev->rx_buffer_wr], bytes_to_read, NULL) == 0) ? bytes_to_read : 0;
|
||||
rfm22_deassertCs();
|
||||
rfm22_releaseBus();
|
||||
rfm22_deassertCs(rfm22b_dev);
|
||||
rfm22_releaseBus(rfm22b_dev);
|
||||
}
|
||||
|
||||
if (rfm22b_dev->rx_buffer_wr != len)
|
||||
return RFM22B_EVENT_ERROR;
|
||||
return RFM22B_EVENT_FAILURE;
|
||||
|
||||
// we have a valid received packet
|
||||
|
||||
enum pios_rfm22b_event ret_event = RFM22B_EVENT_RX_COMPLETE;
|
||||
if (rfm22b_dev->rx_buffer_wr > 0)
|
||||
{
|
||||
// Add the rssi and afc to the end of the packet.
|
||||
rx_buffer[rfm22b_dev->rx_buffer_wr++] = rfm22b_dev->rssi_dBm;
|
||||
rx_buffer[rfm22b_dev->rx_buffer_wr++] = rfm22b_dev->rx_packet_start_afc_Hz;
|
||||
// Swap the Rx packets.
|
||||
if (rfm22b_dev->rx_packet_prev == NULL)
|
||||
rfm22b_dev->stats.rx_byte_count += rfm22b_dev->rx_buffer_wr;
|
||||
// Check the packet for errors.
|
||||
if (rfm22_receivePacket(rfm22b_dev, &(rfm22b_dev->rx_packet), rfm22b_dev->rx_buffer_wr))
|
||||
{
|
||||
rfm22b_dev->rx_packet_prev = rfm22b_dev->rx_packet;
|
||||
rfm22b_dev->rx_packet = rfm22b_dev->rx_packet_next;
|
||||
rfm22b_dev->rx_packet_len = rfm22b_dev->rx_buffer_wr;
|
||||
// Signal the receive thread.
|
||||
xSemaphoreGive(rfm22b_dev->rxsem);
|
||||
switch (rfm22b_dev->rx_packet.header.type)
|
||||
{
|
||||
case PACKET_TYPE_STATUS:
|
||||
ret_event = RFM22B_EVENT_STATUS_RECEIVED;
|
||||
break;
|
||||
case PACKET_TYPE_CON_REQUEST:
|
||||
ret_event = RFM22B_EVENT_CONNECTION_REQUESTED;
|
||||
break;
|
||||
case PACKET_TYPE_DATA:
|
||||
{
|
||||
// Send the data to the com port
|
||||
bool rx_need_yield;
|
||||
if (rfm22b_dev->rx_in_cb)
|
||||
(rfm22b_dev->rx_in_cb)(rfm22b_dev->rx_in_context, rfm22b_dev->rx_packet.data, rfm22b_dev->rx_packet.header.data_size, NULL, &rx_need_yield);
|
||||
break;
|
||||
}
|
||||
case PACKET_TYPE_DUPLICATE_DATA:
|
||||
break;
|
||||
case PACKET_TYPE_ACK:
|
||||
case PACKET_TYPE_ACK_RTS:
|
||||
ret_event = RFM22B_EVENT_PACKET_ACKED;
|
||||
break;
|
||||
case PACKET_TYPE_NACK:
|
||||
ret_event = RFM22B_EVENT_PACKET_NACKED;
|
||||
break;
|
||||
case PACKET_TYPE_PPM:
|
||||
{
|
||||
PHPpmPacketHandle ppmp = (PHPpmPacketHandle)&(rfm22b_dev->rx_packet);
|
||||
for (uint8_t i = 0; i < PIOS_RFM22B_RCVR_MAX_CHANNELS; ++i)
|
||||
rfm22b_dev->ppm_channel[i] = ppmp->channels[i];
|
||||
rfm22b_dev->ppm_fresh = true;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
ret_event = RFM22B_EVENT_RX_ERROR;
|
||||
rfm22b_dev->rx_buffer_wr = 0;
|
||||
rfm22b_dev->rx_complete_ticks = xTaskGetTickCount();
|
||||
if (rfm22b_dev->rx_complete_ticks == 0)
|
||||
rfm22b_dev->rx_complete_ticks = 1;
|
||||
#ifdef PIOS_RFM22B_DEBUG_ON_TELEM
|
||||
D2_LED_OFF;
|
||||
D3_LED_TOGGLE;
|
||||
#endif
|
||||
}
|
||||
|
||||
// We're finished with Rx mode
|
||||
rfm22b_dev->in_rx_mode = false;
|
||||
|
||||
// Start a new transaction
|
||||
rfm22b_dev->packet_start_ticks = 0;
|
||||
return RFM22B_EVENT_RX_COMPLETE;
|
||||
return ret_event;
|
||||
}
|
||||
|
||||
return RFM22B_EVENT_NUM_EVENTS;
|
||||
}
|
||||
|
||||
static enum pios_rfm22b_event rfm22_rxFailure(struct pios_rfm22b_dev *rfm22b_dev)
|
||||
{
|
||||
rfm22b_dev->stats.rx_failure++;
|
||||
rfm22b_dev->rx_buffer_wr = 0;
|
||||
rfm22b_dev->rx_complete_ticks = xTaskGetTickCount();
|
||||
rfm22b_dev->in_rx_mode = false;
|
||||
if (rfm22b_dev->rx_complete_ticks == 0)
|
||||
rfm22b_dev->rx_complete_ticks = 1;
|
||||
return RFM22B_EVENT_RX_MODE;
|
||||
}
|
||||
|
||||
static enum pios_rfm22b_event rfm22_txData(struct pios_rfm22b_dev *rfm22b_dev)
|
||||
{
|
||||
enum pios_rfm22b_event ret_event = RFM22B_EVENT_NUM_EVENTS;
|
||||
|
||||
// Read the device status registers
|
||||
if (!rfm22_readStatus(rfm22b_dev))
|
||||
{
|
||||
// Free the tx packet
|
||||
PHReleaseTXPacket(pios_packet_handler, rfm22b_dev->tx_packet);
|
||||
rfm22b_dev->tx_packet = 0;
|
||||
rfm22b_dev->tx_data_wr = rfm22b_dev->tx_data_rd = 0;
|
||||
return RFM22B_EVENT_ERROR;
|
||||
}
|
||||
return RFM22B_EVENT_FAILURE;
|
||||
|
||||
// FIFO under/over flow error. Back to RX mode.
|
||||
if (rfm22b_dev->device_status & (RFM22_ds_ffunfl | RFM22_ds_ffovfl))
|
||||
{
|
||||
// Free the tx packet
|
||||
PHReleaseTXPacket(pios_packet_handler, rfm22b_dev->tx_packet);
|
||||
rfm22b_dev->tx_packet = 0;
|
||||
rfm22b_dev->tx_data_wr = rfm22b_dev->tx_data_rd = 0;
|
||||
return RFM22B_EVENT_ERROR;
|
||||
}
|
||||
// FIFO under/over flow error.
|
||||
//if (rfm22b_dev->int_status1 & RFM22_is1_ifferr)
|
||||
//return RFM22B_EVENT_FAILURE;
|
||||
|
||||
// TX FIFO almost empty, it needs filling up
|
||||
if (rfm22b_dev->int_status1 & RFM22_is1_ixtffaem)
|
||||
@ -1669,62 +1846,267 @@ static enum pios_rfm22b_event rfm22_txData(struct pios_rfm22b_dev *rfm22b_dev)
|
||||
// top-up the rf chips TX FIFO buffer
|
||||
uint8_t *tx_buffer = (uint8_t*)(rfm22b_dev->tx_packet);
|
||||
uint16_t max_bytes = FIFO_SIZE - TX_FIFO_LO_WATERMARK - 1;
|
||||
rfm22_claimBus();
|
||||
rfm22_assertCs();
|
||||
PIOS_SPI_TransferByte(g_rfm22b_dev->spi_id, RFM22_fifo_access | 0x80);
|
||||
rfm22_claimBus(rfm22b_dev);
|
||||
rfm22_assertCs(rfm22b_dev);
|
||||
PIOS_SPI_TransferByte(rfm22b_dev->spi_id, RFM22_fifo_access | 0x80);
|
||||
int bytes_to_write = (rfm22b_dev->tx_data_wr - rfm22b_dev->tx_data_rd);
|
||||
bytes_to_write = (bytes_to_write > max_bytes) ? max_bytes: bytes_to_write;
|
||||
PIOS_SPI_TransferBlock(g_rfm22b_dev->spi_id, &tx_buffer[rfm22b_dev->tx_data_rd], NULL, bytes_to_write, NULL);
|
||||
PIOS_SPI_TransferBlock(rfm22b_dev->spi_id, &tx_buffer[rfm22b_dev->tx_data_rd], NULL, bytes_to_write, NULL);
|
||||
rfm22b_dev->tx_data_rd += bytes_to_write;
|
||||
rfm22_deassertCs();
|
||||
rfm22_releaseBus();
|
||||
rfm22_deassertCs(rfm22b_dev);
|
||||
rfm22_releaseBus(rfm22b_dev);
|
||||
}
|
||||
|
||||
// Packet has been sent
|
||||
else if (rfm22b_dev->int_status1 & RFM22_is1_ipksent)
|
||||
{
|
||||
// Free the tx packet
|
||||
PHReleaseTXPacket(pios_packet_handler, rfm22b_dev->tx_packet);
|
||||
rfm22b_dev->stats.tx_byte_count += PH_PACKET_SIZE(rfm22b_dev->tx_packet);
|
||||
|
||||
// Is this an ACK?
|
||||
bool is_ack = ((rfm22b_dev->tx_packet->header.type == PACKET_TYPE_ACK) || (rfm22b_dev->tx_packet->header.type == PACKET_TYPE_ACK_RTS));
|
||||
//ret_event = is_ack ? RFM22B_EVENT_TX_START : RFM22B_EVENT_RX_MODE;
|
||||
ret_event = RFM22B_EVENT_RX_MODE;
|
||||
if (is_ack)
|
||||
{
|
||||
// If this is an ACK for a connection request message we need to
|
||||
// configure this modem from the connection request message.
|
||||
if (rfm22b_dev->rx_packet.header.type == PACKET_TYPE_CON_REQUEST)
|
||||
rfm22_setConnectionParameters(rfm22b_dev);
|
||||
|
||||
}
|
||||
else if (rfm22b_dev->tx_packet->header.type != PACKET_TYPE_NACK)
|
||||
{
|
||||
// We need to wait for an ACK if this packet it not an ACK or NACK.
|
||||
rfm22b_dev->prev_tx_packet = rfm22b_dev->tx_packet;
|
||||
rfm22b_dev->tx_complete_ticks = xTaskGetTickCount();
|
||||
}
|
||||
// Set the Tx period
|
||||
portTickType curTicks = xTaskGetTickCount();
|
||||
if (rfm22b_dev->tx_packet->header.type == PACKET_TYPE_ACK)
|
||||
rfm22b_dev->time_to_send_offset = curTicks + 0x4;
|
||||
else if (rfm22b_dev->tx_packet->header.type == PACKET_TYPE_ACK_RTS)
|
||||
rfm22b_dev->time_to_send_offset = curTicks;
|
||||
rfm22b_dev->tx_packet = 0;
|
||||
rfm22b_dev->tx_data_wr = rfm22b_dev->tx_data_rd = 0;
|
||||
// Start a new transaction
|
||||
rfm22b_dev->packet_start_ticks = 0;
|
||||
return RFM22B_EVENT_TX_COMPLETE;
|
||||
|
||||
#ifdef PIOS_RFM22B_DEBUG_ON_TELEM
|
||||
D1_LED_OFF;
|
||||
D3_LED_TOGGLE;
|
||||
#endif
|
||||
}
|
||||
|
||||
return RFM22B_EVENT_NUM_EVENTS;
|
||||
return ret_event;
|
||||
}
|
||||
|
||||
// ************************************
|
||||
|
||||
// return the current mode
|
||||
int8_t rfm22_currentMode(void)
|
||||
static enum pios_rfm22b_event rfm22_txFailure(struct pios_rfm22b_dev *rfm22b_dev)
|
||||
{
|
||||
return g_rfm22b_dev->state;
|
||||
rfm22b_dev->stats.tx_failure++;
|
||||
rfm22b_dev->tx_data_wr = rfm22b_dev->tx_data_rd = 0;
|
||||
return RFM22B_EVENT_TX_START;
|
||||
}
|
||||
|
||||
// return true if we are transmitting
|
||||
bool rfm22_transmitting(void)
|
||||
/**
|
||||
* Send an ACK to a received packet.
|
||||
* \param[in] rfm22b_dev The device structure
|
||||
*/
|
||||
static enum pios_rfm22b_event rfm22_sendAck(struct pios_rfm22b_dev *rfm22b_dev)
|
||||
{
|
||||
return (g_rfm22b_dev->state == RFM22B_STATE_TX_DATA);
|
||||
PHAckNackPacketHandle aph = (PHAckNackPacketHandle)(&(rfm22b_dev->ack_nack_packet));
|
||||
aph->header.destination_id = rfm22b_dev->rx_packet.header.source_id;
|
||||
aph->header.type = rfm22_ready_to_send(rfm22b_dev) ? PACKET_TYPE_ACK_RTS : PACKET_TYPE_ACK;
|
||||
aph->header.data_size = PH_ACK_NACK_DATA_SIZE(aph);
|
||||
aph->header.seq_num = rfm22b_dev->rx_packet.header.seq_num;
|
||||
rfm22b_dev->tx_packet = (PHPacketHandle)aph;
|
||||
rfm22b_dev->time_to_send = true;
|
||||
return RFM22B_EVENT_TX_START;
|
||||
}
|
||||
|
||||
// return true if the channel is clear to transmit on
|
||||
bool rfm22_channelIsClear(void)
|
||||
/**
|
||||
* Send an NACK to a received packet.
|
||||
* \param[in] rfm22b_dev The device structure
|
||||
*/
|
||||
static enum pios_rfm22b_event rfm22_sendNack(struct pios_rfm22b_dev *rfm22b_dev)
|
||||
{
|
||||
if (g_rfm22b_dev->state != RFM22B_STATE_RX_MODE && g_rfm22b_dev->state != RFM22B_STATE_WAIT_PREAMBLE && g_rfm22b_dev->state != RFM22B_STATE_WAIT_SYNC)
|
||||
// we are receiving something or we are transmitting or we are scanning the spectrum
|
||||
return false;
|
||||
|
||||
return true;
|
||||
PHAckNackPacketHandle aph = (PHAckNackPacketHandle)(&(rfm22b_dev->ack_nack_packet));
|
||||
aph->header.destination_id = rfm22b_dev->rx_packet.header.source_id;
|
||||
aph->header.type = PACKET_TYPE_NACK;
|
||||
aph->header.data_size = PH_ACK_NACK_DATA_SIZE(aph);
|
||||
aph->header.seq_num = rfm22b_dev->rx_packet.header.seq_num;
|
||||
rfm22b_dev->tx_packet = (PHPacketHandle)aph;
|
||||
rfm22b_dev->time_to_send = true;
|
||||
return RFM22B_EVENT_TX_START;
|
||||
}
|
||||
|
||||
// ************************************
|
||||
// set/get the frequency calibration value
|
||||
|
||||
void rfm22_setFreqCalibration(uint8_t value)
|
||||
/**
|
||||
* Receive an ACK.
|
||||
* \param[in] rfm22b_dev The device structure
|
||||
*/
|
||||
static enum pios_rfm22b_event rfm22_receiveAck(struct pios_rfm22b_dev *rfm22b_dev)
|
||||
{
|
||||
rfm22_write(RFM22_xtal_osc_load_cap, value);
|
||||
PHPacketHandle prev = rfm22b_dev->prev_tx_packet;
|
||||
portTickType curTicks = xTaskGetTickCount();
|
||||
|
||||
// Clear the previous TX packet.
|
||||
rfm22b_dev->prev_tx_packet = NULL;
|
||||
|
||||
// Was this a connection request?
|
||||
switch (prev->header.type)
|
||||
{
|
||||
case PACKET_TYPE_CON_REQUEST:
|
||||
rfm22_setConnectionParameters(rfm22b_dev);
|
||||
break;
|
||||
case PACKET_TYPE_DATA:
|
||||
rfm22b_dev->data_packet.header.data_size = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
// Should we try to start another TX?
|
||||
if (rfm22b_dev->rx_packet.header.type == PACKET_TYPE_ACK)
|
||||
{
|
||||
rfm22b_dev->time_to_send_offset = curTicks;
|
||||
rfm22b_dev->time_to_send = true;
|
||||
return RFM22B_EVENT_TX_START;
|
||||
}
|
||||
else
|
||||
{
|
||||
rfm22b_dev->time_to_send_offset = curTicks + 0x4;
|
||||
return RFM22B_EVENT_RX_MODE;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Receive an MACK.
|
||||
* \param[in] rfm22b_dev The device structure
|
||||
*/
|
||||
static enum pios_rfm22b_event rfm22_receiveNack(struct pios_rfm22b_dev *rfm22b_dev)
|
||||
{
|
||||
// Resend the previous TX packet.
|
||||
rfm22b_dev->tx_packet = rfm22b_dev->prev_tx_packet;
|
||||
rfm22b_dev->prev_tx_packet = NULL;
|
||||
if (rfm22b_dev->stats.link_state == OPLINKSTATUS_LINKSTATE_CONNECTED)
|
||||
rfm22b_add_rx_status(rfm22b_dev, RFM22B_RESENT_TX_PACKET);
|
||||
rfm22b_dev->time_to_send = true;
|
||||
return RFM22B_EVENT_TX_START;
|
||||
}
|
||||
|
||||
/**
|
||||
* Receive a status packet
|
||||
* \param[in] rfm22b_dev The device structure
|
||||
*/
|
||||
static enum pios_rfm22b_event rfm22_receiveStatus(struct pios_rfm22b_dev *rfm22b_dev)
|
||||
{
|
||||
PHStatusPacketHandle status = (PHStatusPacketHandle)&(rfm22b_dev->rx_packet);
|
||||
int8_t rssi = rfm22b_dev->rssi_dBm;
|
||||
int8_t afc = rfm22b_dev->afc_correction_Hz;
|
||||
uint32_t id = status->header.source_id;
|
||||
bool found = false;
|
||||
// Have we seen this device recently?
|
||||
uint8_t id_idx = 0;
|
||||
for ( ; id_idx < OPLINKSTATUS_PAIRIDS_NUMELEM; ++id_idx)
|
||||
if(rfm22b_dev->pair_stats[id_idx].pairID == id)
|
||||
{
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
|
||||
// If we have seen it, update the RSSI and reset the last contact couter
|
||||
if(found)
|
||||
{
|
||||
rfm22b_dev->pair_stats[id_idx].rssi = rssi;
|
||||
rfm22b_dev->pair_stats[id_idx].afc_correction = afc;
|
||||
rfm22b_dev->pair_stats[id_idx].lastContact = 0;
|
||||
}
|
||||
|
||||
// If we haven't seen it, find a slot to put it in.
|
||||
if (!found)
|
||||
{
|
||||
uint8_t min_idx = 0;
|
||||
if(id != rfm22b_dev->destination_id)
|
||||
{
|
||||
int8_t min_rssi = rfm22b_dev->pair_stats[0].rssi;
|
||||
for (id_idx = 1; id_idx < OPLINKSTATUS_PAIRIDS_NUMELEM; ++id_idx)
|
||||
{
|
||||
if(rfm22b_dev->pair_stats[id_idx].rssi < min_rssi)
|
||||
{
|
||||
min_rssi = rfm22b_dev->pair_stats[id_idx].rssi;
|
||||
min_idx = id_idx;
|
||||
}
|
||||
}
|
||||
}
|
||||
rfm22b_dev->pair_stats[min_idx].pairID = id;
|
||||
rfm22b_dev->pair_stats[min_idx].rssi = rssi;
|
||||
rfm22b_dev->pair_stats[min_idx].afc_correction = afc;
|
||||
rfm22b_dev->pair_stats[min_idx].lastContact = 0;
|
||||
}
|
||||
|
||||
return RFM22B_EVENT_RX_COMPLETE;
|
||||
}
|
||||
|
||||
static enum pios_rfm22b_event rfm22_initConnection(struct pios_rfm22b_dev *rfm22b_dev)
|
||||
{
|
||||
if (rfm22b_dev->coordinator)
|
||||
return RFM22B_EVENT_REQUEST_CONNECTION;
|
||||
else
|
||||
return RFM22B_EVENT_WAIT_FOR_CONNECTION;
|
||||
}
|
||||
|
||||
static enum pios_rfm22b_event rfm22_requestConnection(struct pios_rfm22b_dev *rfm22b_dev)
|
||||
{
|
||||
PHConnectionPacketHandle cph = &(rfm22b_dev->con_packet);
|
||||
|
||||
// Set our connection state to requesting connection.
|
||||
rfm22b_dev->stats.link_state = OPLINKSTATUS_LINKSTATE_CONNECTING;
|
||||
|
||||
// Fill in the connection request
|
||||
cph->header.destination_id = rfm22b_dev->destination_id;
|
||||
cph->header.type = PACKET_TYPE_CON_REQUEST;
|
||||
cph->header.data_size = PH_CONNECTION_DATA_SIZE(&(rfm22b_dev->con_packet));
|
||||
cph->datarate = rfm22b_dev->datarate;
|
||||
cph->frequency_hz = rfm22b_dev->frequency_hz;
|
||||
cph->min_frequency = rfm22b_dev->min_frequency;
|
||||
cph->max_frequency = rfm22b_dev->max_frequency;
|
||||
cph->max_tx_power = rfm22b_dev->tx_power;
|
||||
rfm22b_dev->time_to_send = true;
|
||||
rfm22b_dev->send_connection_request = true;
|
||||
|
||||
return RFM22B_EVENT_TX_START;
|
||||
}
|
||||
|
||||
static void rfm22_setConnectionParameters(struct pios_rfm22b_dev *rfm22b_dev)
|
||||
{
|
||||
PHConnectionPacketHandle cph = &(rfm22b_dev->con_packet);
|
||||
|
||||
// Set our connection state to connected
|
||||
rfm22b_dev->stats.link_state = OPLINKSTATUS_LINKSTATE_CONNECTED;
|
||||
|
||||
// Configure this modem from the connection request message.
|
||||
rfm22_setDatarate(rfm22b_dev, cph->datarate, true);
|
||||
PIOS_RFM22B_SetTxPower((uint32_t)rfm22b_dev, cph->max_tx_power);
|
||||
rfm22b_dev->min_frequency = cph->min_frequency;
|
||||
rfm22b_dev->max_frequency = cph->max_frequency;
|
||||
rfm22_setNominalCarrierFrequency(rfm22b_dev, cph->frequency_hz);
|
||||
|
||||
// Call the com port configuration function
|
||||
if (rfm22b_dev->com_config_cb && !rfm22b_dev->coordinator)
|
||||
rfm22b_dev->com_config_cb(cph->port, cph->com_speed);
|
||||
}
|
||||
|
||||
static enum pios_rfm22b_event rfm22_acceptConnection(struct pios_rfm22b_dev *rfm22b_dev)
|
||||
{
|
||||
// Set our connection state to connected
|
||||
rfm22b_dev->stats.link_state = OPLINKSTATUS_LINKSTATE_CONNECTED;
|
||||
|
||||
// Copy the connection packet
|
||||
PHConnectionPacketHandle cph = (PHConnectionPacketHandle)(&(rfm22b_dev->rx_packet));
|
||||
PHConnectionPacketHandle lcph = (PHConnectionPacketHandle)(&(rfm22b_dev->con_packet));
|
||||
memcpy((uint8_t*)lcph, (uint8_t*)cph, PH_PACKET_SIZE((PHPacketHandle)cph));
|
||||
|
||||
// Set the destination ID to the source of the connection request message.
|
||||
PIOS_RFM22B_SetDestinationId((uint32_t)rfm22b_dev, cph->header.source_id);
|
||||
|
||||
return RFM22B_EVENT_CONNECTION_ACCEPTED;
|
||||
}
|
||||
|
||||
// ************************************
|
||||
@ -1732,13 +2114,49 @@ void rfm22_setFreqCalibration(uint8_t value)
|
||||
|
||||
static enum pios_rfm22b_event rfm22_init(struct pios_rfm22b_dev *rfm22b_dev)
|
||||
{
|
||||
uint32_t id = rfm22b_dev->deviceID;
|
||||
uint32_t min_frequency_hz = rfm22b_dev->cfg.minFrequencyHz;
|
||||
uint32_t max_frequency_hz = rfm22b_dev->cfg.maxFrequencyHz;
|
||||
uint32_t freq_hop_step_size = 50000;
|
||||
|
||||
// Initialize the register values.
|
||||
rfm22b_dev->device_status = 0;
|
||||
rfm22b_dev->int_status1 = 0;
|
||||
rfm22b_dev->int_status2 = 0;
|
||||
rfm22b_dev->ezmac_status = 0;
|
||||
|
||||
// Clean the LEDs
|
||||
rfm22_clearLEDs();
|
||||
|
||||
// Initialize the detected device statistics.
|
||||
for (uint8_t i = 0; i < OPLINKSTATUS_PAIRIDS_NUMELEM; ++i)
|
||||
{
|
||||
rfm22b_dev->pair_stats[i].pairID = 0;
|
||||
rfm22b_dev->pair_stats[i].rssi = -127;
|
||||
rfm22b_dev->pair_stats[i].afc_correction = 0;
|
||||
rfm22b_dev->pair_stats[i].lastContact = 0;
|
||||
}
|
||||
|
||||
// Initlize the link stats.
|
||||
for (uint8_t i = 0; i < RFM22B_RX_PACKET_STATS_LEN; ++i)
|
||||
rfm22b_dev->rx_packet_stats[i] = 0;
|
||||
|
||||
// Initialize the state
|
||||
rfm22b_dev->stats.link_state = OPLINKSTATUS_LINKSTATE_DISCONNECTED;
|
||||
rfm22b_dev->tx_power = RFM22B_DEFAULT_TX_POWER;
|
||||
rfm22b_dev->destination_id = 0xffffffff;
|
||||
rfm22b_dev->time_to_send = false;
|
||||
rfm22b_dev->time_to_send_offset = 0;
|
||||
rfm22b_dev->send_status = false;
|
||||
rfm22b_dev->send_connection_request = false;
|
||||
|
||||
// Initialize the packets.
|
||||
rfm22b_dev->rx_packet_len = 0;
|
||||
rfm22b_dev->tx_packet = NULL;
|
||||
rfm22b_dev->prev_tx_packet = NULL;
|
||||
rfm22b_dev->stats.tx_seq = 0;
|
||||
rfm22b_dev->stats.rx_seq = 0;
|
||||
rfm22b_dev->data_packet.header.data_size = 0;
|
||||
rfm22b_dev->in_rx_mode = false;
|
||||
|
||||
// software reset the RF chip .. following procedure according to Si4x3x Errata (rev. B)
|
||||
rfm22_write(RFM22_op_and_func_ctrl1, RFM22_opfc1_swres);
|
||||
rfm22_write(rfm22b_dev, RFM22_op_and_func_ctrl1, RFM22_opfc1_swres);
|
||||
|
||||
// wait 26ms
|
||||
PIOS_DELAY_WaitmS(26);
|
||||
@ -1749,22 +2167,22 @@ static enum pios_rfm22b_event rfm22_init(struct pios_rfm22b_dev *rfm22b_dev)
|
||||
PIOS_DELAY_WaitmS(1);
|
||||
|
||||
// read the status registers
|
||||
rfm22b_dev->int_status1 = rfm22_read(RFM22_interrupt_status1);
|
||||
rfm22b_dev->int_status2 = rfm22_read(RFM22_interrupt_status2);
|
||||
rfm22b_dev->int_status1 = rfm22_read(rfm22b_dev, RFM22_interrupt_status1);
|
||||
rfm22b_dev->int_status2 = rfm22_read(rfm22b_dev, RFM22_interrupt_status2);
|
||||
if (rfm22b_dev->int_status2 & RFM22_is2_ichiprdy) break;
|
||||
}
|
||||
|
||||
// ****************
|
||||
|
||||
// read status - clears interrupt
|
||||
rfm22b_dev->device_status = rfm22_read(RFM22_device_status);
|
||||
rfm22b_dev->int_status1 = rfm22_read(RFM22_interrupt_status1);
|
||||
rfm22b_dev->int_status2 = rfm22_read(RFM22_interrupt_status2);
|
||||
rfm22b_dev->ezmac_status = rfm22_read(RFM22_ezmac_status);
|
||||
rfm22b_dev->device_status = rfm22_read(rfm22b_dev, RFM22_device_status);
|
||||
rfm22b_dev->int_status1 = rfm22_read(rfm22b_dev, RFM22_interrupt_status1);
|
||||
rfm22b_dev->int_status2 = rfm22_read(rfm22b_dev, RFM22_interrupt_status2);
|
||||
rfm22b_dev->ezmac_status = rfm22_read(rfm22b_dev, RFM22_ezmac_status);
|
||||
|
||||
// disable all interrupts
|
||||
rfm22_write(RFM22_interrupt_enable1, 0x00);
|
||||
rfm22_write(RFM22_interrupt_enable2, 0x00);
|
||||
rfm22_write(rfm22b_dev, RFM22_interrupt_enable1, 0x00);
|
||||
rfm22_write(rfm22b_dev, RFM22_interrupt_enable2, 0x00);
|
||||
|
||||
// ****************
|
||||
|
||||
@ -1779,14 +2197,16 @@ static enum pios_rfm22b_event rfm22_init(struct pios_rfm22b_dev *rfm22b_dev)
|
||||
rfm22b_dev->afc_correction_Hz = 0;
|
||||
|
||||
rfm22b_dev->packet_start_ticks = 0;
|
||||
rfm22b_dev->tx_complete_ticks = 0;
|
||||
rfm22b_dev->rx_complete_ticks = 0;
|
||||
|
||||
// ****************
|
||||
// read the RF chip ID bytes
|
||||
|
||||
// read the device type
|
||||
uint8_t device_type = rfm22_read(RFM22_DEVICE_TYPE) & RFM22_DT_MASK;
|
||||
uint8_t device_type = rfm22_read(rfm22b_dev, RFM22_DEVICE_TYPE) & RFM22_DT_MASK;
|
||||
// read the device version
|
||||
uint8_t device_version = rfm22_read(RFM22_DEVICE_VERSION) & RFM22_DV_MASK;
|
||||
uint8_t device_version = rfm22_read(rfm22b_dev, RFM22_DEVICE_VERSION) & RFM22_DV_MASK;
|
||||
|
||||
#if defined(RFM22_DEBUG)
|
||||
DEBUG_PRINTF(2, "rf device type: %d\n\r", device_type);
|
||||
@ -1812,99 +2232,88 @@ static enum pios_rfm22b_event rfm22_init(struct pios_rfm22b_dev *rfm22b_dev)
|
||||
|
||||
// ****************
|
||||
// set the minimum and maximum carrier frequency allowed
|
||||
|
||||
if (min_frequency_hz < RFM22_MIN_CARRIER_FREQUENCY_HZ) min_frequency_hz = RFM22_MIN_CARRIER_FREQUENCY_HZ;
|
||||
else
|
||||
if (min_frequency_hz > RFM22_MAX_CARRIER_FREQUENCY_HZ) min_frequency_hz = RFM22_MAX_CARRIER_FREQUENCY_HZ;
|
||||
|
||||
if (max_frequency_hz < RFM22_MIN_CARRIER_FREQUENCY_HZ) max_frequency_hz = RFM22_MIN_CARRIER_FREQUENCY_HZ;
|
||||
else
|
||||
if (max_frequency_hz > RFM22_MAX_CARRIER_FREQUENCY_HZ) max_frequency_hz = RFM22_MAX_CARRIER_FREQUENCY_HZ;
|
||||
|
||||
if (min_frequency_hz > max_frequency_hz)
|
||||
{ // swap them over
|
||||
uint32_t tmp = min_frequency_hz;
|
||||
min_frequency_hz = max_frequency_hz;
|
||||
max_frequency_hz = tmp;
|
||||
}
|
||||
rfm22b_dev->min_frequency = RFM22B_DEFAULT_MIN_FREQUENCY;
|
||||
rfm22b_dev->max_frequency = RFM22B_DEFAULT_MAX_FREQUENCY;
|
||||
rfm22b_dev->frequency_hz = RFM22B_DEFAULT_FREQUENCY;
|
||||
|
||||
// ****************
|
||||
// calibrate our RF module to be exactly on frequency .. different for every module
|
||||
rfm22_write(RFM22_xtal_osc_load_cap, OSC_LOAD_CAP);
|
||||
rfm22_write(rfm22b_dev, RFM22_xtal_osc_load_cap, OSC_LOAD_CAP);
|
||||
|
||||
// ****************
|
||||
|
||||
// disable Low Duty Cycle Mode
|
||||
rfm22_write(RFM22_op_and_func_ctrl2, 0x00);
|
||||
rfm22_write(rfm22b_dev, RFM22_op_and_func_ctrl2, 0x00);
|
||||
|
||||
// 1MHz clock output
|
||||
rfm22_write(RFM22_cpu_output_clk, RFM22_coc_1MHz);
|
||||
rfm22_write(rfm22b_dev, RFM22_cpu_output_clk, RFM22_coc_1MHz);
|
||||
|
||||
// READY mode
|
||||
rfm22_write(RFM22_op_and_func_ctrl1, RFM22_opfc1_xton);
|
||||
rfm22_write(rfm22b_dev, RFM22_op_and_func_ctrl1, RFM22_opfc1_xton);
|
||||
|
||||
// choose the 3 GPIO pin functions
|
||||
// GPIO port use default value
|
||||
rfm22_write(RFM22_io_port_config, RFM22_io_port_default);
|
||||
rfm22_write(rfm22b_dev, RFM22_io_port_config, RFM22_io_port_default);
|
||||
if (rfm22b_dev->cfg.gpio_direction == GPIO0_TX_GPIO1_RX) {
|
||||
rfm22_write(RFM22_gpio0_config, RFM22_gpio0_config_drv3 | RFM22_gpio0_config_txstate); // GPIO0 = TX State (to control RF Switch)
|
||||
rfm22_write(RFM22_gpio1_config, RFM22_gpio1_config_drv3 | RFM22_gpio1_config_rxstate); // GPIO1 = RX State (to control RF Switch)
|
||||
rfm22_write(rfm22b_dev, RFM22_gpio0_config, RFM22_gpio0_config_drv3 | RFM22_gpio0_config_txstate); // GPIO0 = TX State (to control RF Switch)
|
||||
rfm22_write(rfm22b_dev, RFM22_gpio1_config, RFM22_gpio1_config_drv3 | RFM22_gpio1_config_rxstate); // GPIO1 = RX State (to control RF Switch)
|
||||
} else {
|
||||
rfm22_write(RFM22_gpio0_config, RFM22_gpio0_config_drv3 | RFM22_gpio0_config_rxstate); // GPIO0 = TX State (to control RF Switch)
|
||||
rfm22_write(RFM22_gpio1_config, RFM22_gpio1_config_drv3 | RFM22_gpio1_config_txstate); // GPIO1 = RX State (to control RF Switch)
|
||||
rfm22_write(rfm22b_dev, RFM22_gpio0_config, RFM22_gpio0_config_drv3 | RFM22_gpio0_config_rxstate); // GPIO0 = TX State (to control RF Switch)
|
||||
rfm22_write(rfm22b_dev, RFM22_gpio1_config, RFM22_gpio1_config_drv3 | RFM22_gpio1_config_txstate); // GPIO1 = RX State (to control RF Switch)
|
||||
}
|
||||
rfm22_write(RFM22_gpio2_config, RFM22_gpio2_config_drv3 | RFM22_gpio2_config_cca); // GPIO2 = Clear Channel Assessment
|
||||
rfm22_write(rfm22b_dev, RFM22_gpio2_config, RFM22_gpio2_config_drv3 | RFM22_gpio2_config_cca); // GPIO2 = Clear Channel Assessment
|
||||
|
||||
// ****************
|
||||
|
||||
// initialize the frequency hopping step size
|
||||
uint32_t freq_hop_step_size = 50000;
|
||||
freq_hop_step_size /= 10000; // in 10kHz increments
|
||||
if (freq_hop_step_size > 255) freq_hop_step_size = 255;
|
||||
rfm22b_dev->frequency_hop_step_size_reg = freq_hop_step_size;
|
||||
|
||||
// FIFO mode, GFSK modulation
|
||||
uint8_t fd_bit = rfm22_read(RFM22_modulation_mode_control2) & RFM22_mmc2_fd;
|
||||
rfm22_write(RFM22_modulation_mode_control2, RFM22_mmc2_trclk_clk_none | RFM22_mmc2_dtmod_fifo | fd_bit | RFM22_mmc2_modtyp_gfsk);
|
||||
uint8_t fd_bit = rfm22_read(rfm22b_dev, RFM22_modulation_mode_control2) & RFM22_mmc2_fd;
|
||||
rfm22_write(rfm22b_dev, RFM22_modulation_mode_control2, RFM22_mmc2_trclk_clk_none | RFM22_mmc2_dtmod_fifo | fd_bit | RFM22_mmc2_modtyp_gfsk);
|
||||
|
||||
// setup to read the internal temperature sensor
|
||||
|
||||
// ADC used to sample the temperature sensor
|
||||
uint8_t adc_config = RFM22_ac_adcsel_temp_sensor | RFM22_ac_adcref_bg;
|
||||
rfm22_write(RFM22_adc_config, adc_config);
|
||||
rfm22_write(rfm22b_dev, RFM22_adc_config, adc_config);
|
||||
|
||||
// adc offset
|
||||
rfm22_write(RFM22_adc_sensor_amp_offset, 0);
|
||||
rfm22_write(rfm22b_dev, RFM22_adc_sensor_amp_offset, 0);
|
||||
|
||||
// temp sensor calibration .. <20>40C to +64C 0.5C resolution
|
||||
rfm22_write(RFM22_temp_sensor_calib, RFM22_tsc_tsrange0 | RFM22_tsc_entsoffs);
|
||||
rfm22_write(rfm22b_dev, RFM22_temp_sensor_calib, RFM22_tsc_tsrange0 | RFM22_tsc_entsoffs);
|
||||
|
||||
// temp sensor offset
|
||||
rfm22_write(RFM22_temp_value_offset, 0);
|
||||
rfm22_write(rfm22b_dev, RFM22_temp_value_offset, 0);
|
||||
|
||||
// start an ADC conversion
|
||||
rfm22_write(RFM22_adc_config, adc_config | RFM22_ac_adcstartbusy);
|
||||
rfm22_write(rfm22b_dev, RFM22_adc_config, adc_config | RFM22_ac_adcstartbusy);
|
||||
|
||||
// set the RSSI threshold interrupt to about -90dBm
|
||||
rfm22_write(RFM22_rssi_threshold_clear_chan_indicator, (-90 + 122) * 2);
|
||||
rfm22_write(rfm22b_dev, RFM22_rssi_threshold_clear_chan_indicator, (-90 + 122) * 2);
|
||||
|
||||
// enable the internal Tx & Rx packet handlers (without CRC)
|
||||
rfm22_write(RFM22_data_access_control, RFM22_dac_enpacrx | RFM22_dac_enpactx);
|
||||
rfm22_write(rfm22b_dev, RFM22_data_access_control, RFM22_dac_enpacrx | RFM22_dac_enpactx);
|
||||
|
||||
// x-nibbles tx preamble
|
||||
rfm22_write(RFM22_preamble_length, TX_PREAMBLE_NIBBLES);
|
||||
rfm22_write(rfm22b_dev, RFM22_preamble_length, TX_PREAMBLE_NIBBLES);
|
||||
// x-nibbles rx preamble detection
|
||||
rfm22_write(RFM22_preamble_detection_ctrl1, RX_PREAMBLE_NIBBLES << 3);
|
||||
rfm22_write(rfm22b_dev, RFM22_preamble_detection_ctrl1, RX_PREAMBLE_NIBBLES << 3);
|
||||
|
||||
#ifdef PIOS_RFM22_NO_HEADER
|
||||
// header control - we are not using the header
|
||||
rfm22_write(RFM22_header_control1, RFM22_header_cntl1_bcen_none | RFM22_header_cntl1_hdch_none);
|
||||
rfm22_write(rfm22b_dev, RFM22_header_control1, RFM22_header_cntl1_bcen_none | RFM22_header_cntl1_hdch_none);
|
||||
|
||||
// no header bytes, synchronization word length 3, 2, 1 & 0 used, packet length included in header.
|
||||
rfm22_write(RFM22_header_control2, RFM22_header_cntl2_hdlen_none |
|
||||
rfm22_write(rfm22b_dev, RFM22_header_control2, RFM22_header_cntl2_hdlen_none |
|
||||
RFM22_header_cntl2_synclen_3210 | ((TX_PREAMBLE_NIBBLES >> 8) & 0x01));
|
||||
#else
|
||||
// header control - using a 4 by header with broadcast of 0xffffffff
|
||||
rfm22_write(RFM22_header_control1,
|
||||
rfm22_write(rfm22b_dev, RFM22_header_control1,
|
||||
RFM22_header_cntl1_bcen_0 |
|
||||
RFM22_header_cntl1_bcen_1 |
|
||||
RFM22_header_cntl1_bcen_2 |
|
||||
@ -1914,66 +2323,93 @@ static enum pios_rfm22b_event rfm22_init(struct pios_rfm22b_dev *rfm22b_dev)
|
||||
RFM22_header_cntl1_hdch_2 |
|
||||
RFM22_header_cntl1_hdch_3);
|
||||
// Check all bit of all bytes of the header
|
||||
rfm22_write(RFM22_header_enable0, 0xff);
|
||||
rfm22_write(RFM22_header_enable1, 0xff);
|
||||
rfm22_write(RFM22_header_enable2, 0xff);
|
||||
rfm22_write(RFM22_header_enable3, 0xff);
|
||||
rfm22_write(rfm22b_dev, RFM22_header_enable0, 0xff);
|
||||
rfm22_write(rfm22b_dev, RFM22_header_enable1, 0xff);
|
||||
rfm22_write(rfm22b_dev, RFM22_header_enable2, 0xff);
|
||||
rfm22_write(rfm22b_dev, RFM22_header_enable3, 0xff);
|
||||
// Set the ID to be checked
|
||||
rfm22_write(RFM22_check_header0, id & 0xff);
|
||||
rfm22_write(RFM22_check_header1, (id >> 8) & 0xff);
|
||||
rfm22_write(RFM22_check_header2, (id >> 16) & 0xff);
|
||||
rfm22_write(RFM22_check_header3, (id >> 24) & 0xff);
|
||||
uint32_t id = rfm22b_dev->deviceID;
|
||||
rfm22_write(rfm22b_dev, RFM22_check_header0, id & 0xff);
|
||||
rfm22_write(rfm22b_dev, RFM22_check_header1, (id >> 8) & 0xff);
|
||||
rfm22_write(rfm22b_dev, RFM22_check_header2, (id >> 16) & 0xff);
|
||||
rfm22_write(rfm22b_dev, RFM22_check_header3, (id >> 24) & 0xff);
|
||||
// 4 header bytes, synchronization word length 3, 2, 1 & 0 used, packet length included in header.
|
||||
rfm22_write(RFM22_header_control2,
|
||||
rfm22_write(rfm22b_dev, RFM22_header_control2,
|
||||
RFM22_header_cntl2_hdlen_3210 |
|
||||
RFM22_header_cntl2_synclen_3210 |
|
||||
((TX_PREAMBLE_NIBBLES >> 8) & 0x01));
|
||||
#endif
|
||||
|
||||
// sync word
|
||||
rfm22_write(RFM22_sync_word3, SYNC_BYTE_1);
|
||||
rfm22_write(RFM22_sync_word2, SYNC_BYTE_2);
|
||||
rfm22_write(RFM22_sync_word1, SYNC_BYTE_3);
|
||||
rfm22_write(RFM22_sync_word0, SYNC_BYTE_4);
|
||||
rfm22_write(rfm22b_dev, RFM22_sync_word3, SYNC_BYTE_1);
|
||||
rfm22_write(rfm22b_dev, RFM22_sync_word2, SYNC_BYTE_2);
|
||||
rfm22_write(rfm22b_dev, RFM22_sync_word1, SYNC_BYTE_3);
|
||||
rfm22_write(rfm22b_dev, RFM22_sync_word0, SYNC_BYTE_4);
|
||||
|
||||
rfm22_write(RFM22_agc_override1, RFM22_agc_ovr1_agcen);
|
||||
rfm22_write(rfm22b_dev, RFM22_agc_override1, RFM22_agc_ovr1_agcen);
|
||||
|
||||
// set frequency hopping channel step size (multiples of 10kHz)
|
||||
rfm22_write(RFM22_frequency_hopping_step_size, rfm22b_dev->frequency_hop_step_size_reg);
|
||||
|
||||
// set our nominal carrier frequency
|
||||
rfm22_setNominalCarrierFrequency(rfm22b_dev, (min_frequency_hz + max_frequency_hz) / 2);
|
||||
rfm22_write(rfm22b_dev, RFM22_frequency_hopping_step_size, rfm22b_dev->frequency_hop_step_size_reg);
|
||||
|
||||
// set the tx power
|
||||
rfm22_write(RFM22_tx_power, RFM22_tx_pwr_papeaken | RFM22_tx_pwr_papeaklvl_0 | RFM22_tx_pwr_lna_sw | rfm22b_dev->tx_power);
|
||||
rfm22_write(rfm22b_dev, RFM22_tx_power, RFM22_tx_pwr_papeaken | RFM22_tx_pwr_papeaklvl_0 | RFM22_tx_pwr_lna_sw | rfm22b_dev->tx_power);
|
||||
|
||||
// TX FIFO Almost Full Threshold (0 - 63)
|
||||
rfm22_write(RFM22_tx_fifo_control1, TX_FIFO_HI_WATERMARK);
|
||||
rfm22_write(rfm22b_dev, RFM22_tx_fifo_control1, TX_FIFO_HI_WATERMARK);
|
||||
|
||||
// TX FIFO Almost Empty Threshold (0 - 63)
|
||||
rfm22_write(RFM22_tx_fifo_control2, TX_FIFO_LO_WATERMARK);
|
||||
rfm22_write(rfm22b_dev, RFM22_tx_fifo_control2, TX_FIFO_LO_WATERMARK);
|
||||
|
||||
// RX FIFO Almost Full Threshold (0 - 63)
|
||||
rfm22_write(RFM22_rx_fifo_control, RX_FIFO_HI_WATERMARK);
|
||||
rfm22_write(rfm22b_dev, RFM22_rx_fifo_control, RX_FIFO_HI_WATERMARK);
|
||||
|
||||
rfm22_setFreqCalibration(rfm22b_dev->cfg.RFXtalCap);
|
||||
rfm22_setNominalCarrierFrequency(rfm22b_dev, rfm22b_dev->cfg.frequencyHz);
|
||||
RFM22_SetDatarate((uint32_t)rfm22b_dev, rfm22b_dev->datarate, true);
|
||||
// Set the frequency calibration
|
||||
rfm22_write(rfm22b_dev, RFM22_xtal_osc_load_cap, rfm22b_dev->cfg.RFXtalCap);
|
||||
|
||||
// Initialize the frequency and datarate to te default.
|
||||
rfm22_setNominalCarrierFrequency(rfm22b_dev, RFM22B_DEFAULT_FREQUENCY);
|
||||
rfm22_setDatarate(rfm22b_dev, RFM22B_DEFAULT_RX_DATARATE, true);
|
||||
|
||||
return RFM22B_EVENT_INITIALIZED;
|
||||
}
|
||||
|
||||
static void rfm22_clearLEDs() {
|
||||
LINK_LED_OFF;
|
||||
RX_LED_OFF;
|
||||
TX_LED_OFF;
|
||||
#ifdef PIOS_RFM22B_DEBUG_ON_TELEM
|
||||
D1_LED_OFF;
|
||||
D2_LED_OFF;
|
||||
D3_LED_OFF;
|
||||
D4_LED_OFF;
|
||||
#endif
|
||||
}
|
||||
|
||||
static enum pios_rfm22b_event rfm22_timeout(struct pios_rfm22b_dev *rfm22b_dev)
|
||||
{
|
||||
rfm22b_dev->resets++;
|
||||
rfm22b_dev->stats.timeouts++;
|
||||
rfm22b_dev->packet_start_ticks = 0;
|
||||
// Release the Tx packet if it's set.
|
||||
if (rfm22b_dev->tx_packet != 0)
|
||||
{
|
||||
rfm22b_dev->tx_data_rd = rfm22b_dev->tx_data_wr = 0;
|
||||
}
|
||||
rfm22b_dev->rx_buffer_wr = 0;
|
||||
TX_LED_OFF;
|
||||
RX_LED_OFF;
|
||||
#ifdef PIOS_RFM22B_DEBUG_ON_TELEM
|
||||
D1_LED_OFF;
|
||||
D2_LED_OFF;
|
||||
D3_LED_OFF;
|
||||
D4_LED_OFF;
|
||||
#endif
|
||||
return RFM22B_EVENT_TX_START;
|
||||
}
|
||||
|
||||
static enum pios_rfm22b_event rfm22_error(struct pios_rfm22b_dev *rfm22b_dev)
|
||||
{
|
||||
rfm22b_dev->resets++;
|
||||
rfm22b_dev->packet_start_ticks = 0;
|
||||
rfm22b_dev->stats.resets++;
|
||||
rfm22_clearLEDs();
|
||||
return RFM22B_EVENT_INITIALIZE;
|
||||
}
|
||||
|
||||
@ -1985,8 +2421,8 @@ static enum pios_rfm22b_event rfm22_error(struct pios_rfm22b_dev *rfm22b_dev)
|
||||
*/
|
||||
static enum pios_rfm22b_event rfm22_fatal_error(struct pios_rfm22b_dev *rfm22b_dev)
|
||||
{
|
||||
|
||||
// RF module error .. flash the LED's
|
||||
rfm22_clearLEDs();
|
||||
for(unsigned int j = 0; j < 16; j++)
|
||||
{
|
||||
USB_LED_ON;
|
||||
|
130
flight/PiOS/Common/pios_rfm22b_com.c
Normal file
130
flight/PiOS/Common/pios_rfm22b_com.c
Normal file
@ -0,0 +1,130 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @addtogroup PIOS PIOS Core hardware abstraction layer
|
||||
* @{
|
||||
* @addtogroup PIOS_RFM22B Radio Functions
|
||||
* @brief PIOS COM interface for for the RFM22B radio
|
||||
* @{
|
||||
*
|
||||
* @file pios_rfm22b_com.c
|
||||
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2012.
|
||||
* @brief Implements a driver the the RFM22B driver
|
||||
* @see The GNU Public License (GPL) Version 3
|
||||
*
|
||||
*****************************************************************************/
|
||||
/*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
/* Project Includes */
|
||||
#include <pios.h>
|
||||
|
||||
#include <pios_rfm22b_priv.h>
|
||||
|
||||
/* Provide a COM driver */
|
||||
static void PIOS_RFM22B_COM_ChangeBaud(uint32_t rfm22b_id, uint32_t baud);
|
||||
static void PIOS_RFM22B_COM_RegisterRxCallback(uint32_t rfm22b_id, pios_com_callback rx_in_cb, uint32_t context);
|
||||
static void PIOS_RFM22B_COM_RegisterTxCallback(uint32_t rfm22b_id, pios_com_callback tx_out_cb, uint32_t context);
|
||||
static void PIOS_RFM22B_COM_TxStart(uint32_t rfm22b_id, uint16_t tx_bytes_avail);
|
||||
static void PIOS_RFM22B_COM_RxStart(uint32_t rfm22b_id, uint16_t rx_bytes_avail);
|
||||
static bool PIOS_RFM22B_COM_Available(uint32_t rfm22b_com_id);
|
||||
|
||||
/* Local variables */
|
||||
const struct pios_com_driver pios_rfm22b_com_driver = {
|
||||
.set_baud = PIOS_RFM22B_COM_ChangeBaud,
|
||||
.tx_start = PIOS_RFM22B_COM_TxStart,
|
||||
.rx_start = PIOS_RFM22B_COM_RxStart,
|
||||
.bind_tx_cb = PIOS_RFM22B_COM_RegisterTxCallback,
|
||||
.bind_rx_cb = PIOS_RFM22B_COM_RegisterRxCallback,
|
||||
.available = PIOS_RFM22B_COM_Available
|
||||
};
|
||||
|
||||
/**
|
||||
* Changes the baud rate of the RFM22B peripheral without re-initialising.
|
||||
* \param[in] rfm22b_id RFM22B name (GPS, TELEM, AUX)
|
||||
* \param[in] baud Requested baud rate
|
||||
*/
|
||||
static void PIOS_RFM22B_COM_ChangeBaud(uint32_t rfm22b_id, uint32_t baud)
|
||||
{
|
||||
struct pios_rfm22b_dev *rfm22b_dev = (struct pios_rfm22b_dev *)rfm22b_id;
|
||||
if (!PIOS_RFM22B_validate(rfm22b_dev))
|
||||
return;
|
||||
// This is only allowed for coordinators.
|
||||
if (!rfm22b_dev->coordinator)
|
||||
return;
|
||||
// Set the RF data rate on the modem to ~2X the selected buad rate because the modem is half duplex.
|
||||
enum rfm22b_datarate datarate = RFM22_datarate_64000;
|
||||
if (baud <= 1024)
|
||||
datarate = RFM22_datarate_500;
|
||||
else if (baud <= 2048)
|
||||
datarate = RFM22_datarate_1000;
|
||||
else if (baud <= 4096)
|
||||
datarate = RFM22_datarate_8000;
|
||||
else if (baud <= 9600)
|
||||
datarate = RFM22_datarate_16000;
|
||||
else if (baud <= 19200)
|
||||
datarate = RFM22_datarate_32000;
|
||||
else if (baud <= 38400)
|
||||
datarate = RFM22_datarate_64000;
|
||||
else if (baud <= 57600)
|
||||
datarate = RFM22_datarate_128000;
|
||||
else if (baud <= 115200)
|
||||
datarate = RFM22_datarate_192000;
|
||||
PIOS_RFM22B_SetDatarate(rfm22b_id, datarate, true);
|
||||
}
|
||||
|
||||
static void PIOS_RFM22B_COM_RxStart(uint32_t rfm22b_id, uint16_t rx_bytes_avail)
|
||||
{
|
||||
}
|
||||
|
||||
static void PIOS_RFM22B_COM_TxStart(uint32_t rfm22b_id, uint16_t tx_bytes_avail)
|
||||
{
|
||||
struct pios_rfm22b_dev *rfm22b_dev = (struct pios_rfm22b_dev *)rfm22b_id;
|
||||
if (!PIOS_RFM22B_validate(rfm22b_dev))
|
||||
return;
|
||||
}
|
||||
|
||||
static void PIOS_RFM22B_COM_RegisterRxCallback(uint32_t rfm22b_id, pios_com_callback rx_in_cb, uint32_t context)
|
||||
{
|
||||
struct pios_rfm22b_dev *rfm22b_dev = (struct pios_rfm22b_dev *)rfm22b_id;
|
||||
if (!PIOS_RFM22B_validate(rfm22b_dev))
|
||||
return;
|
||||
|
||||
/*
|
||||
* Order is important in these assignments since ISR uses _cb
|
||||
* field to determine if it's ok to dereference _cb and _context
|
||||
*/
|
||||
rfm22b_dev->rx_in_context = context;
|
||||
rfm22b_dev->rx_in_cb = rx_in_cb;
|
||||
}
|
||||
|
||||
static void PIOS_RFM22B_COM_RegisterTxCallback(uint32_t rfm22b_id, pios_com_callback tx_out_cb, uint32_t context)
|
||||
{
|
||||
struct pios_rfm22b_dev *rfm22b_dev = (struct pios_rfm22b_dev *)rfm22b_id;
|
||||
if (!PIOS_RFM22B_validate(rfm22b_dev))
|
||||
return;
|
||||
|
||||
/*
|
||||
* Order is important in these assignments since ISR uses _cb
|
||||
* field to determine if it's ok to dereference _cb and _context
|
||||
*/
|
||||
rfm22b_dev->tx_out_context = context;
|
||||
rfm22b_dev->tx_out_cb = tx_out_cb;
|
||||
}
|
||||
|
||||
static bool PIOS_RFM22B_COM_Available(uint32_t rfm22b_id)
|
||||
{
|
||||
return PIOS_RFM22B_LinkStatus(rfm22b_id);
|
||||
}
|
99
flight/PiOS/Common/pios_rfm22b_rcvr.c
Normal file
99
flight/PiOS/Common/pios_rfm22b_rcvr.c
Normal file
@ -0,0 +1,99 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @addtogroup PIOS PIOS Core hardware abstraction layer
|
||||
* @{
|
||||
* @addtogroup PIOS_RFM22B_RCVR RFM22B Receiver Input Functions
|
||||
* @brief Code to output the PPM signal from the RFM22B
|
||||
* @{
|
||||
*
|
||||
* @file pios_rfm22b_rcvr.c
|
||||
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2012.
|
||||
* @brief Implements a receiver interface to the RFM22B device
|
||||
* @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_RFM22B_RCVR)
|
||||
|
||||
#include "pios_rfm22b_priv.h"
|
||||
|
||||
/* Provide a RCVR driver */
|
||||
static int32_t PIOS_RFM22B_RCVR_Get(uint32_t rcvr_id, uint8_t channel);
|
||||
static void PIOS_RFM22B_RCVR_Supervisor(uint32_t rcvr_id);
|
||||
|
||||
const struct pios_rcvr_driver pios_rfm22b_rcvr_driver = {
|
||||
.read = PIOS_RFM22B_RCVR_Get,
|
||||
};
|
||||
|
||||
int32_t PIOS_RFM22B_RCVR_Init(uint32_t rcvr_id)
|
||||
{
|
||||
struct pios_rfm22b_dev *rfm22b_dev = (struct pios_rfm22b_dev *)rcvr_id;
|
||||
if (!PIOS_RFM22B_validate(rfm22b_dev))
|
||||
return -1;
|
||||
|
||||
// Initialize
|
||||
for (uint8_t i = 0; i < PIOS_RFM22B_RCVR_MAX_CHANNELS; ++i)
|
||||
rfm22b_dev->ppm_channel[i] = PIOS_RCVR_TIMEOUT;
|
||||
rfm22b_dev->ppm_supv_timer = 0;
|
||||
|
||||
// Register the failsafe timer callback.
|
||||
if (!PIOS_RTC_RegisterTickCallback(PIOS_RFM22B_RCVR_Supervisor, rcvr_id))
|
||||
PIOS_DEBUG_Assert(0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int32_t PIOS_RFM22B_RCVR_Get(uint32_t rcvr_id, uint8_t channel)
|
||||
{
|
||||
struct pios_rfm22b_dev *rfm22b_dev = (struct pios_rfm22b_dev *)rcvr_id;
|
||||
if (!PIOS_RFM22B_validate(rfm22b_dev))
|
||||
return -1;
|
||||
|
||||
if (channel >= GCSRECEIVER_CHANNEL_NUMELEM)
|
||||
/* channel is out of range */
|
||||
return -1;
|
||||
|
||||
return rfm22b_dev->ppm_channel[channel];
|
||||
}
|
||||
|
||||
static void PIOS_RFM22B_RCVR_Supervisor(uint32_t rcvr_id) {
|
||||
struct pios_rfm22b_dev *rfm22b_dev = (struct pios_rfm22b_dev *)rcvr_id;
|
||||
if (!PIOS_RFM22B_validate(rfm22b_dev))
|
||||
return;
|
||||
|
||||
// RTC runs at 625Hz.
|
||||
if (++(rfm22b_dev->ppm_supv_timer) < (PIOS_RFM22B_RCVR_TIMEOUT_MS * 1000 / 625))
|
||||
return;
|
||||
rfm22b_dev->ppm_supv_timer = 0;
|
||||
|
||||
// Have we received fresh values since the last update?
|
||||
if (!rfm22b_dev->ppm_fresh)
|
||||
for (uint8_t i = 0; i < PIOS_RFM22B_RCVR_MAX_CHANNELS; ++i)
|
||||
rfm22b_dev->ppm_channel[i] = 0;
|
||||
rfm22b_dev->ppm_fresh = false;
|
||||
}
|
||||
|
||||
#endif /* PIOS_INCLUDE_GCSRCVR */
|
||||
|
||||
/**
|
||||
* @}
|
||||
* @}
|
||||
*/
|
@ -103,7 +103,7 @@ extern "C" {
|
||||
/* Architecture specifics. */
|
||||
#define portSTACK_GROWTH ( -1 )
|
||||
#define portTICK_RATE_MS ( ( portTickType ) 1000 / configTICK_RATE_HZ )
|
||||
#define portBYTE_ALIGNMENT 8
|
||||
#define portBYTE_ALIGNMENT 4
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
|
||||
|
@ -223,7 +223,7 @@ bool PIOS_USB_CableConnected(uint8_t id)
|
||||
* \return 0: interface not available
|
||||
* \note Applications shouldn't call this function directly, instead please use \ref PIOS_COM layer functions
|
||||
*/
|
||||
bool PIOS_USB_CheckAvailable(uint8_t id)
|
||||
bool PIOS_USB_CheckAvailable(uint32_t id)
|
||||
{
|
||||
struct pios_usb_dev * usb_dev = (struct pios_usb_dev *) pios_usb_com_id;
|
||||
|
||||
|
@ -51,6 +51,7 @@ const struct pios_com_driver pios_usb_cdc_com_driver = {
|
||||
.rx_start = PIOS_USB_CDC_RxStart,
|
||||
.bind_tx_cb = PIOS_USB_CDC_RegisterTxCallback,
|
||||
.bind_rx_cb = PIOS_USB_CDC_RegisterRxCallback,
|
||||
.available = PIOS_USB_CheckAvailable,
|
||||
};
|
||||
|
||||
enum pios_usb_cdc_dev_magic {
|
||||
|
@ -51,6 +51,7 @@ const struct pios_com_driver pios_usb_hid_com_driver = {
|
||||
.rx_start = PIOS_USB_HID_RxStart,
|
||||
.bind_tx_cb = PIOS_USB_HID_RegisterTxCallback,
|
||||
.bind_rx_cb = PIOS_USB_HID_RegisterRxCallback,
|
||||
.available = PIOS_USB_CheckAvailable,
|
||||
};
|
||||
|
||||
enum pios_usb_hid_dev_magic {
|
||||
|
@ -94,6 +94,9 @@ uint16_t PIOS_WDG_Init()
|
||||
*/
|
||||
bool PIOS_WDG_RegisterFlag(uint16_t flag_requested)
|
||||
{
|
||||
// flag are being registered so we are in module initialization phase
|
||||
// clear the WDG to prevent timeout while initializing modules. (OP-815)
|
||||
PIOS_WDG_Clear();
|
||||
|
||||
/* Fail if flag already registered */
|
||||
if(wdg_configuration.used_flags & flag_requested)
|
||||
|
@ -47,26 +47,8 @@ struct pios_tim_dev {
|
||||
const struct pios_tim_callbacks * callbacks;
|
||||
uint32_t context;
|
||||
};
|
||||
#define PIOS_TIM_ALL_FLAGS TIM_IT_CC1 | TIM_IT_CC2 | TIM_IT_CC3 | TIM_IT_CC4 | TIM_IT_Trigger | TIM_IT_Update
|
||||
|
||||
#if 0
|
||||
static bool PIOS_TIM_validate(struct pios_tim_dev * tim_dev)
|
||||
{
|
||||
return (tim_dev->magic == PIOS_TIM_DEV_MAGIC);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(PIOS_INCLUDE_FREERTOS) && 0
|
||||
static struct pios_tim_dev * PIOS_TIM_alloc(void)
|
||||
{
|
||||
struct pios_tim_dev * tim_dev;
|
||||
|
||||
tim_dev = (struct pios_tim_dev *)malloc(sizeof(*tim_dev));
|
||||
if (!tim_dev) return(NULL);
|
||||
|
||||
tim_dev->magic = PIOS_TIM_DEV_MAGIC;
|
||||
return(tim_dev);
|
||||
}
|
||||
#else
|
||||
static struct pios_tim_dev pios_tim_devs[PIOS_TIM_MAX_DEVS];
|
||||
static uint8_t pios_tim_num_devs;
|
||||
static struct pios_tim_dev * PIOS_TIM_alloc(void)
|
||||
@ -82,8 +64,6 @@ static struct pios_tim_dev * PIOS_TIM_alloc(void)
|
||||
|
||||
return (tim_dev);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
@ -105,7 +85,6 @@ int32_t PIOS_TIM_InitClock(const struct pios_tim_clock_cfg * cfg)
|
||||
case (uint32_t)TIM4:
|
||||
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE);
|
||||
break;
|
||||
#ifdef STM32F10X_HD
|
||||
case (uint32_t)TIM5:
|
||||
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM5, ENABLE);
|
||||
break;
|
||||
@ -127,16 +106,15 @@ int32_t PIOS_TIM_InitClock(const struct pios_tim_clock_cfg * cfg)
|
||||
case (uint32_t)TIM11:
|
||||
RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM11, ENABLE);
|
||||
break;
|
||||
case (uint32_t)TIM12:
|
||||
case (uint32_t)TIM12:
|
||||
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM12, ENABLE);
|
||||
break;
|
||||
case (uint32_t)TIM13:
|
||||
case (uint32_t)TIM13:
|
||||
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM13, ENABLE);
|
||||
break;
|
||||
case (uint32_t)TIM14:
|
||||
case (uint32_t)TIM14:
|
||||
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM14, ENABLE);
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Configure the dividers for this timer */
|
||||
@ -348,68 +326,6 @@ static void PIOS_TIM_generic_irq_handler(TIM_TypeDef * timer)
|
||||
}
|
||||
}
|
||||
}
|
||||
#if 0
|
||||
uint16_t val = 0;
|
||||
for(uint8_t i = 0; i < pios_pwm_cfg.num_channels; i++) {
|
||||
struct pios_pwm_channel channel = pios_pwm_cfg.channels[i];
|
||||
if ((channel.timer == timer) && (TIM_GetITStatus(channel.timer, channel.ccr) == SET)) {
|
||||
|
||||
TIM_ClearITPendingBit(channel.timer, channel.ccr);
|
||||
|
||||
switch(channel.channel) {
|
||||
case TIM_Channel_1:
|
||||
val = TIM_GetCapture1(channel.timer);
|
||||
break;
|
||||
case TIM_Channel_2:
|
||||
val = TIM_GetCapture2(channel.timer);
|
||||
break;
|
||||
case TIM_Channel_3:
|
||||
val = TIM_GetCapture3(channel.timer);
|
||||
break;
|
||||
case TIM_Channel_4:
|
||||
val = TIM_GetCapture4(channel.timer);
|
||||
break;
|
||||
}
|
||||
|
||||
if (CaptureState[i] == 0) {
|
||||
RiseValue[i] = val;
|
||||
} else {
|
||||
FallValue[i] = val;
|
||||
}
|
||||
|
||||
// flip state machine and capture value here
|
||||
/* Simple rise or fall state machine */
|
||||
TIM_ICInitTypeDef TIM_ICInitStructure = pios_pwm_cfg.tim_ic_init;
|
||||
if (CaptureState[i] == 0) {
|
||||
/* Switch states */
|
||||
CaptureState[i] = 1;
|
||||
|
||||
/* Switch polarity of input capture */
|
||||
TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Falling;
|
||||
TIM_ICInitStructure.TIM_Channel = channel.channel;
|
||||
TIM_ICInit(channel.timer, &TIM_ICInitStructure);
|
||||
} else {
|
||||
/* Capture computation */
|
||||
if (FallValue[i] > RiseValue[i]) {
|
||||
CaptureValue[i] = (FallValue[i] - RiseValue[i]);
|
||||
} else {
|
||||
CaptureValue[i] = ((channel.timer->ARR - RiseValue[i]) + FallValue[i]);
|
||||
}
|
||||
|
||||
/* Switch states */
|
||||
CaptureState[i] = 0;
|
||||
|
||||
/* Increase supervisor counter */
|
||||
CapCounter[i]++;
|
||||
|
||||
/* Switch polarity of input capture */
|
||||
TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising;
|
||||
TIM_ICInitStructure.TIM_Channel = channel.channel;
|
||||
TIM_ICInit(channel.timer, &TIM_ICInitStructure);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Bind Interrupt Handlers
|
||||
*
|
||||
@ -422,31 +338,6 @@ static void PIOS_TIM_1_CC_irq_handler (void)
|
||||
PIOS_TIM_generic_irq_handler (TIM1);
|
||||
}
|
||||
|
||||
// The rest of TIM1 interrupts are overlapped
|
||||
void TIM1_BRK_TIM9_IRQHandler(void) __attribute__ ((alias ("PIOS_TIM_9_CC_irq_handler")));
|
||||
static void PIOS_TIM_9_CC_irq_handler (void)
|
||||
{
|
||||
// TODO: Check for TIM1_BRK
|
||||
PIOS_TIM_generic_irq_handler (TIM9);
|
||||
}
|
||||
|
||||
void TIM1_UP_TIM10_IRQHandler(void) __attribute__ ((alias ("PIOS_TIM_10_CC_irq_handler")));
|
||||
static void PIOS_TIM_10_CC_irq_handler (void)
|
||||
{
|
||||
if (TIM_GetITStatus(TIM1, TIM_IT_Update)) {
|
||||
PIOS_TIM_generic_irq_handler(TIM1);
|
||||
} else if (TIM_GetITStatus(TIM10, TIM_IT_CC1 | TIM_IT_CC2 | TIM_IT_CC3 | TIM_IT_CC4)) {
|
||||
PIOS_TIM_generic_irq_handler (TIM10);
|
||||
}
|
||||
}
|
||||
|
||||
void TIM1_TRG_COM_TIM11_IRQHandler(void) __attribute__ ((alias ("PIOS_TIM_11_CC_irq_handler")));
|
||||
static void PIOS_TIM_11_CC_irq_handler (void)
|
||||
{
|
||||
// TODO: Check for TIM1_TRG
|
||||
PIOS_TIM_generic_irq_handler (TIM11);
|
||||
}
|
||||
|
||||
void TIM2_IRQHandler(void) __attribute__ ((alias ("PIOS_TIM_2_irq_handler")));
|
||||
static void PIOS_TIM_2_irq_handler (void)
|
||||
{
|
||||
@ -495,12 +386,84 @@ static void PIOS_TIM_8_CC_irq_handler (void)
|
||||
PIOS_TIM_generic_irq_handler (TIM8);
|
||||
}
|
||||
|
||||
// The rest of TIM1 interrupts are overlapped
|
||||
void TIM1_BRK_TIM9_IRQHandler(void) __attribute__ ((alias ("PIOS_TIM_9_CC_irq_handler")));
|
||||
static void PIOS_TIM_9_CC_irq_handler (void)
|
||||
{
|
||||
if (TIM_GetITStatus(TIM1, TIM_IT_Break))
|
||||
{
|
||||
PIOS_TIM_generic_irq_handler(TIM1);
|
||||
}
|
||||
else if (TIM_GetITStatus(TIM9, PIOS_TIM_ALL_FLAGS))
|
||||
{
|
||||
PIOS_TIM_generic_irq_handler (TIM9);
|
||||
}
|
||||
}
|
||||
|
||||
void TIM1_UP_TIM10_IRQHandler(void) __attribute__ ((alias ("PIOS_TIM_10_CC_irq_handler")));
|
||||
static void PIOS_TIM_10_CC_irq_handler (void)
|
||||
{
|
||||
if (TIM_GetITStatus(TIM1, TIM_IT_Update))
|
||||
{
|
||||
PIOS_TIM_generic_irq_handler(TIM1);
|
||||
}
|
||||
else if (TIM_GetITStatus(TIM10, PIOS_TIM_ALL_FLAGS))
|
||||
{
|
||||
PIOS_TIM_generic_irq_handler (TIM10);
|
||||
}
|
||||
}
|
||||
|
||||
void TIM1_TRG_COM_TIM11_IRQHandler(void) __attribute__ ((alias ("PIOS_TIM_11_CC_irq_handler")));
|
||||
static void PIOS_TIM_11_CC_irq_handler (void)
|
||||
{
|
||||
if(TIM_GetITStatus(TIM1, TIM_IT_COM | TIM_IT_Trigger))
|
||||
{
|
||||
PIOS_TIM_generic_irq_handler (TIM1);
|
||||
}
|
||||
else if (TIM_GetITStatus(TIM11, PIOS_TIM_ALL_FLAGS))
|
||||
{
|
||||
PIOS_TIM_generic_irq_handler (TIM11);
|
||||
}
|
||||
}
|
||||
|
||||
void TIM8_BRK_TIM12_IRQHandler(void) __attribute__ ((alias ("PIOS_TIM_12_irq_handler")));
|
||||
static void PIOS_TIM_12_irq_handler (void)
|
||||
{
|
||||
PIOS_TIM_generic_irq_handler (TIM12);
|
||||
if(TIM_GetITStatus(TIM8, TIM_IT_Break))
|
||||
{
|
||||
PIOS_TIM_generic_irq_handler (TIM8);
|
||||
}
|
||||
else if (TIM_GetITStatus(TIM12, PIOS_TIM_ALL_FLAGS))
|
||||
{
|
||||
PIOS_TIM_generic_irq_handler (TIM12);
|
||||
}
|
||||
}
|
||||
|
||||
void TIM8_UP_TIM13_IRQHandler(void) __attribute__ ((alias ("PIOS_TIM8_UP_TIM13_IRQHandler")));
|
||||
static void PIOS_TIM8_UP_TIM13_IRQHandler (void)
|
||||
{
|
||||
if(TIM_GetITStatus(TIM8, TIM_IT_Update))
|
||||
{
|
||||
PIOS_TIM_generic_irq_handler (TIM8);
|
||||
}
|
||||
else if (TIM_GetITStatus(TIM13, PIOS_TIM_ALL_FLAGS))
|
||||
{
|
||||
PIOS_TIM_generic_irq_handler (TIM13);
|
||||
}
|
||||
}
|
||||
|
||||
void TIM8_TRG_COM_TIM14_IRQHandler (void) __attribute__ ((alias ("PIOS_TIM8_TRG_COM_TIM14_IRQHandler")));
|
||||
static void PIOS_TIM8_TRG_COM_TIM14_IRQHandler (void)
|
||||
{
|
||||
if(TIM_GetITStatus(TIM8, TIM_IT_COM | TIM_IT_Trigger))
|
||||
{
|
||||
PIOS_TIM_generic_irq_handler (TIM8);
|
||||
}
|
||||
else if (TIM_GetITStatus(TIM14, PIOS_TIM_ALL_FLAGS))
|
||||
{
|
||||
PIOS_TIM_generic_irq_handler (TIM14);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @}
|
||||
|
@ -155,7 +155,7 @@ int32_t PIOS_USB_ChangeConnectionState(bool connected)
|
||||
* \return 0: interface not available
|
||||
*/
|
||||
uint32_t usb_found;
|
||||
bool PIOS_USB_CheckAvailable(uint8_t id)
|
||||
bool PIOS_USB_CheckAvailable(uint32_t id)
|
||||
{
|
||||
struct pios_usb_dev * usb_dev = (struct pios_usb_dev *) pios_usb_id;
|
||||
|
||||
|
@ -48,6 +48,7 @@ const struct pios_com_driver pios_usb_cdc_com_driver = {
|
||||
.rx_start = PIOS_USB_CDC_RxStart,
|
||||
.bind_tx_cb = PIOS_USB_CDC_RegisterTxCallback,
|
||||
.bind_rx_cb = PIOS_USB_CDC_RegisterRxCallback,
|
||||
.available = PIOS_USB_CheckAvailable,
|
||||
};
|
||||
|
||||
enum pios_usb_cdc_dev_magic {
|
||||
|
@ -52,6 +52,7 @@ const struct pios_com_driver pios_usb_hid_com_driver = {
|
||||
.rx_start = PIOS_USB_HID_RxStart,
|
||||
.bind_tx_cb = PIOS_USB_HID_RegisterTxCallback,
|
||||
.bind_rx_cb = PIOS_USB_HID_RegisterRxCallback,
|
||||
.available = PIOS_USB_CheckAvailable,
|
||||
};
|
||||
|
||||
enum pios_usb_hid_dev_magic {
|
||||
|
@ -98,7 +98,10 @@ uint16_t PIOS_WDG_Init()
|
||||
*/
|
||||
bool PIOS_WDG_RegisterFlag(uint16_t flag_requested)
|
||||
{
|
||||
|
||||
// flag are being registered so we are in module initialization phase
|
||||
// clear the WDG to prevent timeout while initializing modules. (OP-815)
|
||||
PIOS_WDG_Clear();
|
||||
|
||||
/* Fail if flag already registered */
|
||||
if(wdg_configuration.used_flags & flag_requested)
|
||||
return false;
|
||||
|
@ -43,6 +43,7 @@ struct pios_com_driver {
|
||||
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);
|
||||
bool (*available)(uint32_t id);
|
||||
};
|
||||
|
||||
/* Public Functions */
|
||||
@ -56,6 +57,7 @@ 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 bool PIOS_COM_Available(uint32_t com_id);
|
||||
|
||||
#endif /* PIOS_COM_H */
|
||||
|
||||
|
@ -32,6 +32,7 @@
|
||||
#define PIOS_RFM22B_H
|
||||
|
||||
#include <packet_handler.h>
|
||||
#include <oplinksettings.h>
|
||||
|
||||
enum gpio_direction {GPIO0_TX_GPIO1_RX, GPIO0_RX_GPIO1_TX};
|
||||
|
||||
@ -39,12 +40,7 @@ enum gpio_direction {GPIO0_TX_GPIO1_RX, GPIO0_RX_GPIO1_TX};
|
||||
struct pios_rfm22b_cfg {
|
||||
const struct pios_spi_cfg * spi_cfg; /* Pointer to SPI interface configuration */
|
||||
const struct pios_exti_cfg * exti_cfg; /* Pointer to the EXTI configuration */
|
||||
uint32_t frequencyHz;
|
||||
uint32_t minFrequencyHz;
|
||||
uint32_t maxFrequencyHz;
|
||||
uint8_t RFXtalCap;
|
||||
uint32_t maxRFBandwidth;
|
||||
uint8_t maxTxPower;
|
||||
uint8_t slave_num;
|
||||
enum gpio_direction gpio_direction;
|
||||
};
|
||||
@ -77,18 +73,47 @@ enum rfm22b_datarate {
|
||||
RFM22_datarate_256000 = 13,
|
||||
};
|
||||
|
||||
struct rfm22b_stats {
|
||||
uint16_t packets_per_sec;
|
||||
uint16_t tx_byte_count;
|
||||
uint16_t rx_byte_count;
|
||||
uint16_t tx_seq;
|
||||
uint16_t rx_seq;
|
||||
uint8_t rx_good;
|
||||
uint8_t rx_corrected;
|
||||
uint8_t rx_error;
|
||||
uint8_t rx_missed;
|
||||
uint8_t rx_failure;
|
||||
uint8_t tx_dropped;
|
||||
uint8_t tx_resent;
|
||||
uint8_t tx_failure;
|
||||
uint8_t resets;
|
||||
uint8_t timeouts;
|
||||
uint8_t link_quality;
|
||||
int8_t rssi;
|
||||
int8_t afc_correction;
|
||||
uint8_t link_state;
|
||||
};
|
||||
|
||||
/* Callback function prototypes */
|
||||
typedef void (*PIOS_RFM22B_ComConfigCallback)(OPLinkSettingsOutputConnectionOptions com_port, OPLinkSettingsComSpeedOptions com_speed);
|
||||
|
||||
/* Public Functions */
|
||||
extern int32_t PIOS_RFM22B_Init(uint32_t *rfb22b_id, uint32_t spi_id, uint32_t slave_num, const struct pios_rfm22b_cfg *cfg);
|
||||
extern void PIOS_RFM22B_SetFrequencyRange(uint32_t rfm22b_id, uint32_t min_frequency, uint32_t max_frequency);
|
||||
extern void PIOS_RFM22B_SetTxPower(uint32_t rfm22b_id, enum rfm22b_tx_power tx_pwr);
|
||||
extern void RFM22_SetDatarate(uint32_t rfm22b_id, enum rfm22b_datarate datarate, bool data_whitening);
|
||||
extern void PIOS_RFM22B_SetDatarate(uint32_t rfm22b_id, enum rfm22b_datarate datarate, bool data_whitening);
|
||||
extern void PIOS_RFM22B_SetDestinationId(uint32_t rfm22b_id, uint32_t dest_id);
|
||||
extern void PIOS_RFM22B_SetCoordinator(uint32_t rfm22b_id, bool coordinator);
|
||||
extern void PIOS_RFM22B_SetRemoteComConfig(uint32_t rfm22b_id, OPLinkSettingsOutputConnectionOptions com_port, OPLinkSettingsComSpeedOptions com_speed);
|
||||
extern void PIOS_RFM22B_SetComConfigCallback(uint32_t rfm22b_id, PIOS_RFM22B_ComConfigCallback cb);
|
||||
extern uint32_t PIOS_RFM22B_DeviceID(uint32_t rfb22b_id);
|
||||
extern uint16_t PIOS_RFM22B_Resets(uint32_t rfm22b_id);
|
||||
extern uint16_t PIOS_RFM22B_Timeouts(uint32_t rfm22b_id);
|
||||
extern uint8_t PIOS_RFM22B_LinkQuality(uint32_t rfm22b_id);
|
||||
extern int8_t PIOS_RFM22B_RSSI(uint32_t rfm22b_id);
|
||||
extern bool PIOS_RFM22B_Send_Packet(uint32_t rfm22b_id, PHPacketHandle p, uint32_t max_delay);
|
||||
extern uint32_t PIOS_RFM22B_Receive_Packet(uint32_t rfm22b_id, PHPacketHandle *p, uint32_t max_delay);
|
||||
extern void PIOS_RFM22B_GetStats(uint32_t rfm22b_id, struct rfm22b_stats *stats);
|
||||
extern uint8_t PIOS_RFM2B_GetPairStats(uint32_t rfm22b_id, uint32_t *device_ids, int8_t *RSSIs, uint8_t max_pairs);
|
||||
extern bool PIOS_RFM22B_LinkStatus(uint32_t rfm22b_id);
|
||||
|
||||
/* Global Variables */
|
||||
extern const struct pios_com_driver pios_rfm22b_com_driver;
|
||||
|
||||
#endif /* PIOS_RFM22B_H */
|
||||
|
||||
|
@ -1,48 +1,41 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file waypointeditorgadget.cpp
|
||||
* @addtogroup PIOS PIOS Core hardware abstraction layer
|
||||
* @{
|
||||
* @addtogroup PIOS_RFM22B COM Functions
|
||||
* @brief PIOS interface for RFM22B Radio COM interface
|
||||
* @{
|
||||
*
|
||||
* @file pios_rfm22b_com.h
|
||||
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2012.
|
||||
* @addtogroup Waypoint Editor GCS Plugins
|
||||
* @{
|
||||
* @addtogroup WaypointEditorGadgetPlugin Waypoint Editor Gadget Plugin
|
||||
* @{
|
||||
* @brief A gadget to edit a list of waypoints
|
||||
* @brief RFM22B 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
|
||||
/*
|
||||
* 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
|
||||
*
|
||||
* 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.,
|
||||
*
|
||||
* 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 "waypointeditorgadget.h"
|
||||
#include "waypointeditorgadgetwidget.h"
|
||||
|
||||
#include "extensionsystem/pluginmanager.h"
|
||||
#include "uavobjectmanager.h"
|
||||
#include "uavobject.h"
|
||||
#include <QDebug>
|
||||
#ifndef PIOS_RFM22B_H
|
||||
#define PIOS_RFM22B_H
|
||||
|
||||
WaypointEditorGadget::WaypointEditorGadget(QString classId, WaypointEditorGadgetWidget *widget, QWidget *parent) :
|
||||
IUAVGadget(classId, parent),
|
||||
m_widget(widget)
|
||||
{
|
||||
}
|
||||
extern const struct pios_com_driver pios_rfm22b_com_driver;
|
||||
|
||||
WaypointEditorGadget::~WaypointEditorGadget()
|
||||
{
|
||||
delete m_widget;
|
||||
}
|
||||
#endif /* PIOS_RFM22B_H */
|
||||
|
||||
void WaypointEditorGadget::loadConfiguration(IUAVGadgetConfiguration* config)
|
||||
{
|
||||
Q_UNUSED(config);
|
||||
}
|
||||
/**
|
||||
* @}
|
||||
* @}
|
||||
*/
|
@ -32,10 +32,11 @@
|
||||
#define PIOS_RFM22B_PRIV_H
|
||||
|
||||
#include <pios.h>
|
||||
#include "fifo_buffer.h"
|
||||
#include <fifo_buffer.h>
|
||||
#include <uavobjectmanager.h>
|
||||
#include <oplinkstatus.h>
|
||||
#include "pios_rfm22b.h"
|
||||
|
||||
extern const struct pios_com_driver pios_rfm22b_com_driver;
|
||||
#include "pios_rfm22b_rcvr.h"
|
||||
|
||||
// ************************************
|
||||
|
||||
@ -565,14 +566,239 @@ extern const struct pios_com_driver pios_rfm22b_com_driver;
|
||||
|
||||
#define RFM22_fifo_access 0x7F // R/W
|
||||
|
||||
// ************************************
|
||||
|
||||
typedef int16_t ( *t_rfm22_TxDataByteCallback ) (void);
|
||||
typedef bool ( *t_rfm22_RxDataCallback ) (void *data, uint8_t len);
|
||||
// External type definitions
|
||||
|
||||
// ************************************
|
||||
typedef int16_t (*t_rfm22_TxDataByteCallback) (void);
|
||||
typedef bool (*t_rfm22_RxDataCallback) (void *data, uint8_t len);
|
||||
enum pios_rfm22b_dev_magic {
|
||||
PIOS_RFM22B_DEV_MAGIC = 0x68e971b6,
|
||||
};
|
||||
|
||||
enum pios_rfm22b_state {
|
||||
RFM22B_STATE_UNINITIALIZED,
|
||||
RFM22B_STATE_INITIALIZING,
|
||||
RFM22B_STATE_INITIALIZED,
|
||||
RFM22B_STATE_INITIATING_CONNECTION,
|
||||
RFM22B_STATE_WAIT_FOR_CONNECTION,
|
||||
RFM22B_STATE_REQUESTING_CONNECTION,
|
||||
RFM22B_STATE_ACCEPTING_CONNECTION,
|
||||
RFM22B_STATE_CONNECTION_ACCEPTED,
|
||||
RFM22B_STATE_RX_MODE,
|
||||
RFM22B_STATE_WAIT_PREAMBLE,
|
||||
RFM22B_STATE_WAIT_SYNC,
|
||||
RFM22B_STATE_RX_DATA,
|
||||
RFM22B_STATE_RX_FAILURE,
|
||||
RFM22B_STATE_RECEIVING_STATUS,
|
||||
RFM22B_STATE_TX_START,
|
||||
RFM22B_STATE_TX_DATA,
|
||||
RFM22B_STATE_TX_FAILURE,
|
||||
RFM22B_STATE_SENDING_ACK,
|
||||
RFM22B_STATE_SENDING_NACK,
|
||||
RFM22B_STATE_RECEIVING_ACK,
|
||||
RFM22B_STATE_RECEIVING_NACK,
|
||||
RFM22B_STATE_TIMEOUT,
|
||||
RFM22B_STATE_ERROR,
|
||||
RFM22B_STATE_FATAL_ERROR,
|
||||
|
||||
RFM22B_STATE_NUM_STATES // Must be last
|
||||
};
|
||||
|
||||
enum pios_rfm22b_event {
|
||||
RFM22B_EVENT_INT_RECEIVED,
|
||||
RFM22B_EVENT_INITIALIZE,
|
||||
RFM22B_EVENT_INITIALIZED,
|
||||
RFM22B_EVENT_REQUEST_CONNECTION,
|
||||
RFM22B_EVENT_WAIT_FOR_CONNECTION,
|
||||
RFM22B_EVENT_CONNECTION_REQUESTED,
|
||||
RFM22B_EVENT_CONNECTION_ACCEPTED,
|
||||
RFM22B_EVENT_PACKET_ACKED,
|
||||
RFM22B_EVENT_PACKET_NACKED,
|
||||
RFM22B_EVENT_ACK_TIMEOUT,
|
||||
RFM22B_EVENT_RX_MODE,
|
||||
RFM22B_EVENT_PREAMBLE_DETECTED,
|
||||
RFM22B_EVENT_SYNC_DETECTED,
|
||||
RFM22B_EVENT_RX_COMPLETE,
|
||||
RFM22B_EVENT_RX_ERROR,
|
||||
RFM22B_EVENT_STATUS_RECEIVED,
|
||||
RFM22B_EVENT_TX_START,
|
||||
RFM22B_EVENT_FAILURE,
|
||||
RFM22B_EVENT_TIMEOUT,
|
||||
RFM22B_EVENT_ERROR,
|
||||
RFM22B_EVENT_FATAL_ERROR,
|
||||
|
||||
RFM22B_EVENT_NUM_EVENTS // Must be last
|
||||
};
|
||||
|
||||
#define RFM22B_RX_PACKET_STATS_LEN 4
|
||||
enum pios_rfm22b_rx_packet_status {
|
||||
RFM22B_GOOD_RX_PACKET = 0x00,
|
||||
RFM22B_CORRECTED_RX_PACKET = 0x01,
|
||||
RFM22B_ERROR_RX_PACKET = 0x2,
|
||||
RFM22B_RESENT_TX_PACKET = 0x3
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
uint32_t pairID;
|
||||
int8_t rssi;
|
||||
int8_t afc_correction;
|
||||
uint8_t lastContact;
|
||||
} rfm22b_pair_stats;
|
||||
|
||||
struct pios_rfm22b_dev {
|
||||
enum pios_rfm22b_dev_magic magic;
|
||||
struct pios_rfm22b_cfg cfg;
|
||||
|
||||
// The SPI bus information
|
||||
uint32_t spi_id;
|
||||
uint32_t slave_num;
|
||||
|
||||
// The device ID
|
||||
uint32_t deviceID;
|
||||
|
||||
// The destination ID
|
||||
uint32_t destination_id;
|
||||
|
||||
// Is this device a coordinator?
|
||||
bool coordinator;
|
||||
|
||||
// The task handle
|
||||
xTaskHandle taskHandle;
|
||||
|
||||
// The potential paired statistics
|
||||
rfm22b_pair_stats pair_stats[OPLINKSTATUS_PAIRIDS_NUMELEM];
|
||||
|
||||
// ISR pending semaphore
|
||||
xSemaphoreHandle isrPending;
|
||||
|
||||
// The com configuration callback
|
||||
PIOS_RFM22B_ComConfigCallback com_config_cb;
|
||||
|
||||
// The COM callback functions.
|
||||
pios_com_callback rx_in_cb;
|
||||
uint32_t rx_in_context;
|
||||
pios_com_callback tx_out_cb;
|
||||
uint32_t tx_out_context;
|
||||
|
||||
// the transmit power to use for data transmissions
|
||||
uint8_t tx_power;
|
||||
|
||||
// The RF datarate lookup index.
|
||||
uint8_t datarate;
|
||||
|
||||
// The state machine state and the current event
|
||||
enum pios_rfm22b_state state;
|
||||
|
||||
// The event queue handle
|
||||
xQueueHandle eventQueue;
|
||||
|
||||
// device status register
|
||||
uint8_t device_status;
|
||||
// interrupt status register 1
|
||||
uint8_t int_status1;
|
||||
// interrupt status register 2
|
||||
uint8_t int_status2;
|
||||
// ezmac status register
|
||||
uint8_t ezmac_status;
|
||||
|
||||
// The error statistics counters
|
||||
uint16_t prev_rx_seq_num;
|
||||
uint32_t rx_packet_stats[RFM22B_RX_PACKET_STATS_LEN];
|
||||
|
||||
// The packet statistics
|
||||
struct rfm22b_stats stats;
|
||||
|
||||
// Stats
|
||||
uint16_t errors;
|
||||
|
||||
// RSSI in dBm
|
||||
int8_t rssi_dBm;
|
||||
|
||||
// The packet queue handle
|
||||
xQueueHandle packetQueue;
|
||||
|
||||
// The tx data packet
|
||||
PHPacket data_packet;
|
||||
// The current tx packet
|
||||
PHPacketHandle tx_packet;
|
||||
// The previous tx packet (waiting for an ACK)
|
||||
PHPacketHandle prev_tx_packet;
|
||||
// The tx data read index
|
||||
uint16_t tx_data_rd;
|
||||
// The tx data write index
|
||||
uint16_t tx_data_wr;
|
||||
// The tx packet sequence number
|
||||
uint16_t tx_seq;
|
||||
|
||||
// The rx data packet
|
||||
PHPacket rx_packet;
|
||||
// The receive buffer write index
|
||||
uint16_t rx_buffer_wr;
|
||||
// The receive buffer write index
|
||||
uint16_t rx_packet_len;
|
||||
// Is the modem currently in Rx mode?
|
||||
bool in_rx_mode;
|
||||
|
||||
// The status packet
|
||||
PHStatusPacket status_packet;
|
||||
|
||||
// The ACK/NACK packet
|
||||
PHAckNackPacket ack_nack_packet;
|
||||
|
||||
#ifdef PIOS_PPM_RECEIVER
|
||||
// The PPM packet
|
||||
PHPpmPacket ppm_packet;
|
||||
#endif
|
||||
|
||||
// The connection packet.
|
||||
PHConnectionPacket con_packet;
|
||||
|
||||
// Send flags
|
||||
bool send_status;
|
||||
bool send_ppm;
|
||||
bool send_connection_request;
|
||||
bool time_to_send;
|
||||
uint8_t time_to_send_offset;
|
||||
|
||||
// The minimum frequency
|
||||
uint32_t min_frequency;
|
||||
// The maximum frequency
|
||||
uint32_t max_frequency;
|
||||
// The current nominal frequency
|
||||
uint32_t frequency_hz;
|
||||
// The frequency hopping step size
|
||||
float frequency_step_size;
|
||||
// current frequency hop channel
|
||||
uint8_t frequency_hop_channel;
|
||||
// the frequency hop step size
|
||||
uint8_t frequency_hop_step_size_reg;
|
||||
// afc correction reading (in Hz)
|
||||
int8_t afc_correction_Hz;
|
||||
|
||||
// The maximum time (ms) that it should take to transmit / receive a packet.
|
||||
uint32_t max_packet_time;
|
||||
portTickType packet_start_ticks;
|
||||
portTickType tx_complete_ticks;
|
||||
portTickType rx_complete_ticks;
|
||||
uint8_t max_ack_delay;
|
||||
|
||||
// The PPM channel values
|
||||
uint16_t ppm_channel[PIOS_RFM22B_RCVR_MAX_CHANNELS];
|
||||
uint8_t ppm_supv_timer;
|
||||
bool ppm_fresh;
|
||||
};
|
||||
|
||||
|
||||
// External function definitions
|
||||
|
||||
bool PIOS_RFM22_EXT_Int(void);
|
||||
bool PIOS_RFM22B_validate(struct pios_rfm22b_dev * rfm22b_dev);
|
||||
void PIOS_RFM22B_InjectEvent(struct pios_rfm22b_dev *rfm22b_dev, enum pios_rfm22b_event event, bool inISR);
|
||||
|
||||
|
||||
// Global variable definitions
|
||||
|
||||
extern const struct pios_com_driver pios_rfm22b_com_driver;
|
||||
|
||||
#endif /* PIOS_RFM22B_PRIV_H */
|
||||
|
||||
|
@ -1,46 +1,40 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file waypointeditorplugin.h
|
||||
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2012.
|
||||
* @addtogroup Waypoint Editor GCS Plugins
|
||||
* @{
|
||||
* @addtogroup WaypointEditorGadgetPlugin Waypoint Editor Gadget Plugin
|
||||
* @{
|
||||
* @brief A gadget to edit a list of waypoints
|
||||
*****************************************************************************/
|
||||
/*
|
||||
* 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 WaypointEditorPLUGIN_H_
|
||||
#define WaypointEditorPLUGIN_H_
|
||||
|
||||
#include <extensionsystem/iplugin.h>
|
||||
|
||||
class WaypointEditorGadgetFactory;
|
||||
|
||||
class WaypointEditorPlugin : public ExtensionSystem::IPlugin
|
||||
{
|
||||
public:
|
||||
WaypointEditorPlugin();
|
||||
~WaypointEditorPlugin();
|
||||
|
||||
void extensionsInitialized();
|
||||
bool initialize(const QStringList & arguments, QString * errorString);
|
||||
void shutdown();
|
||||
private:
|
||||
WaypointEditorGadgetFactory *mf;
|
||||
};
|
||||
#endif /* WaypointEditorPLUGIN_H_ */
|
||||
/**
|
||||
******************************************************************************
|
||||
* @addtogroup PIOS PIOS Core hardware abstraction layer
|
||||
* @{
|
||||
* @addtogroup PIOS RFM22B Receiver Input Functions
|
||||
* @{
|
||||
*
|
||||
* @file pios_rfm22b_rcvr.h
|
||||
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
|
||||
* @brief RFM22B Receiver Input 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_RFM22B_RCVR_H
|
||||
|
||||
#define PIOS_RFM22B_RCVR_MAX_CHANNELS 12
|
||||
|
||||
extern const struct pios_rcvr_driver pios_rfm22b_rcvr_driver;
|
||||
|
||||
extern int32_t PIOS_RFM22B_RCVR_Init(uint32_t rcvr_id);
|
||||
|
||||
#define PIOS_RFM22B_RCVR_H
|
||||
|
||||
#endif /* PIOS_RFM22B_RCVR_H */
|
@ -36,7 +36,7 @@
|
||||
extern int32_t PIOS_USB_Reenumerate();
|
||||
extern int32_t PIOS_USB_ChangeConnectionState(bool connected);
|
||||
extern bool PIOS_USB_CableConnected(uint8_t id);
|
||||
extern bool PIOS_USB_CheckAvailable(uint8_t id);
|
||||
extern bool PIOS_USB_CheckAvailable(uint32_t id);
|
||||
|
||||
#endif /* PIOS_USB_H */
|
||||
|
||||
|
@ -166,6 +166,16 @@
|
||||
#include <pios_usb.h>
|
||||
#endif
|
||||
|
||||
#if defined(PIOS_INCLUDE_RFM22B)
|
||||
#include <pios_rfm22b.h>
|
||||
#ifdef PIOS_INCLUDE_RFM22B_COM
|
||||
#include <pios_rfm22b_com.h>
|
||||
#endif
|
||||
#ifdef PIOS_INCLUDE_RFM22B_RCVR
|
||||
#include <pios_rfm22b_rcvr.h>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include <pios_crc.h>
|
||||
|
||||
#define NELEMENTS(x) (sizeof(x) / sizeof(*(x)))
|
||||
|
@ -73,7 +73,7 @@ FLASH_TOOL = OPENOCD
|
||||
|
||||
# List of modules to include
|
||||
OPTMODULES =
|
||||
MODULES = Radio RadioComBridge
|
||||
MODULES = RadioComBridge
|
||||
|
||||
# Paths
|
||||
OPSYSTEM = ./System
|
||||
@ -147,8 +147,8 @@ endif
|
||||
## UAVOBJECTS
|
||||
ifndef TESTAPP
|
||||
SRC += $(OPUAVSYNTHDIR)/gcsreceiver.c
|
||||
SRC += $(OPUAVSYNTHDIR)/pipxstatus.c
|
||||
SRC += $(OPUAVSYNTHDIR)/pipxsettings.c
|
||||
SRC += $(OPUAVSYNTHDIR)/oplinkstatus.c
|
||||
SRC += $(OPUAVSYNTHDIR)/oplinksettings.c
|
||||
SRC += $(OPUAVSYNTHDIR)/objectpersistence.c
|
||||
|
||||
endif
|
||||
@ -191,12 +191,12 @@ SRC += $(PIOSCOMMON)/pios_i2c_esc.c
|
||||
SRC += $(PIOSCOMMON)/pios_rcvr.c
|
||||
SRC += $(PIOSCOMMON)/printf-stdarg.c
|
||||
SRC += $(PIOSCOMMON)/pios_rfm22b.c
|
||||
SRC += $(PIOSCOMMON)/pios_rfm22b_com.c
|
||||
## Libraries for flight calculations
|
||||
SRC += $(FLIGHTLIB)/fifo_buffer.c
|
||||
SRC += $(FLIGHTLIB)/CoordinateConversions.c
|
||||
SRC += $(FLIGHTLIB)/taskmonitor.c
|
||||
SRC += $(FLIGHTLIB)/aes.c
|
||||
SRC += $(FLIGHTLIB)/packet_handler.c
|
||||
## The Reed-Solomon FEC library
|
||||
SRC += $(FLIGHTLIB)/rscode/rs.c
|
||||
SRC += $(FLIGHTLIB)/rscode/berlekamp.c
|
||||
|
@ -39,6 +39,7 @@
|
||||
#define PIOS_INCLUDE_LED
|
||||
#define PIOS_INCLUDE_IAP
|
||||
#define PIOS_INCLUDE_RFM22B
|
||||
#define PIOS_INCLUDE_RFM22B_COM
|
||||
#define PIOS_INCLUDE_RCVR
|
||||
#define PIOS_INCLUDE_TIM
|
||||
|
||||
@ -98,8 +99,8 @@
|
||||
/* PIOS Initcall infrastructure */
|
||||
#define PIOS_INCLUDE_INITCALL
|
||||
|
||||
/* Always include the radio module */
|
||||
#define RADIO_BUILTIN
|
||||
/* Turn on debugging signals on the telemetry port */
|
||||
//#define PIOS_RFM22B_DEBUG_ON_TELEM
|
||||
|
||||
#endif /* PIOS_CONFIG_H */
|
||||
/**
|
||||
|
@ -30,30 +30,34 @@
|
||||
|
||||
#include <pios.h>
|
||||
#include <openpilot.h>
|
||||
#include <pipxsettings.h>
|
||||
#include <oplinksettings.h>
|
||||
#include <board_hw_defs.c>
|
||||
|
||||
#define PIOS_COM_SERIAL_RX_BUF_LEN 256
|
||||
#define PIOS_COM_SERIAL_TX_BUF_LEN 256
|
||||
|
||||
#define PIOS_COM_FLEXI_RX_BUF_LEN 256
|
||||
#define PIOS_COM_FLEXI_TX_BUF_LEN 128
|
||||
#define PIOS_COM_TELEM_RX_BUF_LEN 256
|
||||
#define PIOS_COM_TELEM_TX_BUF_LEN 256
|
||||
|
||||
#define PIOS_COM_TELEM_USB_RX_BUF_LEN 256
|
||||
#define PIOS_COM_TELEM_USB_TX_BUF_LEN 256
|
||||
|
||||
#define PIOS_COM_VCP_USB_RX_BUF_LEN 256
|
||||
#define PIOS_COM_VCP_USB_TX_BUF_LEN 256
|
||||
#define PIOS_COM_TELEM_VCP_RX_BUF_LEN 256
|
||||
#define PIOS_COM_TELEM_VCP_TX_BUF_LEN 256
|
||||
|
||||
#define PIOS_COM_RFM22B_RF_RX_BUF_LEN 256
|
||||
#define PIOS_COM_RFM22B_RF_TX_BUF_LEN 256
|
||||
|
||||
uint32_t pios_com_telem_usb_id = 0;
|
||||
uint32_t pios_com_telemetry_id;
|
||||
uint32_t pios_com_flexi_id;
|
||||
uint32_t pios_com_vcp_id;
|
||||
uint32_t pios_com_uavtalk_com_id = 0;
|
||||
uint32_t pios_com_gcs_com_id = 0;
|
||||
uint32_t pios_com_trans_com_id = 0;
|
||||
uint32_t pios_com_debug_id = 0;
|
||||
uint32_t pios_com_telem_vcp_id = 0;
|
||||
uint32_t pios_com_telem_uart_telem_id = 0;
|
||||
uint32_t pios_com_telem_uart_flexi_id = 0;
|
||||
uint32_t pios_com_telemetry_id = 0;
|
||||
#if defined(PIOS_INCLUDE_PPM)
|
||||
uint32_t pios_ppm_rcvr_id = 0;
|
||||
#endif
|
||||
#if defined(PIOS_INCLUDE_RFM22B)
|
||||
uint32_t pios_rfm22b_id = 0;
|
||||
uint32_t pios_com_rfm22b_id = 0;
|
||||
uint32_t pios_com_radio_id = 0;
|
||||
#endif
|
||||
|
||||
/**
|
||||
* PIOS_Board_Init()
|
||||
@ -84,24 +88,24 @@ void PIOS_Board_Init(void) {
|
||||
PIOS_RTC_Init(&pios_rtc_main_cfg);
|
||||
#endif /* PIOS_INCLUDE_RTC */
|
||||
|
||||
PipXSettingsInitialize();
|
||||
OPLinkSettingsInitialize();
|
||||
|
||||
#if defined(PIOS_INCLUDE_LED)
|
||||
PIOS_LED_Init(&pios_led_cfg);
|
||||
#endif /* PIOS_INCLUDE_LED */
|
||||
|
||||
PipXSettingsData pipxSettings;
|
||||
OPLinkSettingsData oplinkSettings;
|
||||
#if defined(PIOS_INCLUDE_FLASH_EEPROM)
|
||||
PIOS_EEPROM_Init(&pios_eeprom_cfg);
|
||||
|
||||
/* Read the settings from flash. */
|
||||
/* NOTE: We probably need to save/restore the objID here incase the object changed but the size doesn't */
|
||||
if (PIOS_EEPROM_Load((uint8_t*)&pipxSettings, sizeof(PipXSettingsData)) == 0)
|
||||
PipXSettingsSet(&pipxSettings);
|
||||
if (PIOS_EEPROM_Load((uint8_t*)&oplinkSettings, sizeof(OPLinkSettingsData)) == 0)
|
||||
OPLinkSettingsSet(&oplinkSettings);
|
||||
else
|
||||
PipXSettingsGet(&pipxSettings);
|
||||
OPLinkSettingsGet(&oplinkSettings);
|
||||
#else
|
||||
PipXSettingsGet(&pipxSettings);
|
||||
OPLinkSettingsGet(&oplinkSettings);
|
||||
#endif /* PIOS_INCLUDE_FLASH_EEPROM */
|
||||
|
||||
/* Initialize the task monitor library */
|
||||
@ -115,11 +119,9 @@ void PIOS_Board_Init(void) {
|
||||
PIOS_TIM_InitClock(&tim_4_cfg);
|
||||
#endif /* PIOS_INCLUDE_TIM */
|
||||
|
||||
#if defined(PIOS_INCLUDE_USB)
|
||||
/* Initialize board specific USB data */
|
||||
PIOS_USB_BOARD_DATA_Init();
|
||||
|
||||
|
||||
/* Flags to determine if various USB interfaces are advertised */
|
||||
bool usb_cdc_present = false;
|
||||
|
||||
@ -134,60 +136,18 @@ void PIOS_Board_Init(void) {
|
||||
}
|
||||
#endif
|
||||
|
||||
/*Initialize the USB device */
|
||||
uint32_t pios_usb_id;
|
||||
PIOS_USB_Init(&pios_usb_id, &pios_usb_main_cfg);
|
||||
|
||||
#if defined(PIOS_INCLUDE_USB_CDC)
|
||||
if (!usb_cdc_present) {
|
||||
/* Force VCP port function to disabled if we haven't advertised VCP in our USB descriptor */
|
||||
pipxSettings.VCPConfig = PIPXSETTINGS_VCPCONFIG_DISABLED;
|
||||
}
|
||||
|
||||
switch (pipxSettings.VCPConfig)
|
||||
{
|
||||
case PIPXSETTINGS_VCPCONFIG_SERIAL:
|
||||
case PIPXSETTINGS_VCPCONFIG_DEBUG:
|
||||
{
|
||||
uint32_t pios_usb_cdc_id;
|
||||
if (PIOS_USB_CDC_Init(&pios_usb_cdc_id, &pios_usb_cdc_cfg, pios_usb_id)) {
|
||||
PIOS_Assert(0);
|
||||
}
|
||||
uint8_t * rx_buffer = (uint8_t *) pvPortMalloc(PIOS_COM_VCP_USB_RX_BUF_LEN);
|
||||
uint8_t * tx_buffer = (uint8_t *) pvPortMalloc(PIOS_COM_VCP_USB_TX_BUF_LEN);
|
||||
PIOS_Assert(rx_buffer);
|
||||
PIOS_Assert(tx_buffer);
|
||||
if (PIOS_COM_Init(&pios_com_vcp_id, &pios_usb_cdc_com_driver, pios_usb_cdc_id,
|
||||
rx_buffer, PIOS_COM_VCP_USB_RX_BUF_LEN,
|
||||
tx_buffer, PIOS_COM_VCP_USB_TX_BUF_LEN)) {
|
||||
PIOS_Assert(0);
|
||||
}
|
||||
switch (pipxSettings.VCPConfig)
|
||||
{
|
||||
case PIPXSETTINGS_VCPCONFIG_SERIAL:
|
||||
pios_com_trans_com_id = pios_com_vcp_id;
|
||||
break;
|
||||
case PIPXSETTINGS_VCPCONFIG_DEBUG:
|
||||
pios_com_debug_id = pios_com_vcp_id;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case PIPXSETTINGS_VCPCONFIG_DISABLED:
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(PIOS_INCLUDE_USB_HID)
|
||||
|
||||
/* Configure the usb HID port */
|
||||
#if defined(PIOS_INCLUDE_COM)
|
||||
/* Configure the USB HID port */
|
||||
{
|
||||
uint32_t pios_usb_hid_id;
|
||||
if (PIOS_USB_HID_Init(&pios_usb_hid_id, &pios_usb_hid_cfg, pios_usb_id)) {
|
||||
PIOS_Assert(0);
|
||||
}
|
||||
uint8_t * rx_buffer = (uint8_t *) pvPortMalloc(PIOS_COM_TELEM_USB_RX_BUF_LEN);
|
||||
uint8_t * tx_buffer = (uint8_t *) pvPortMalloc(PIOS_COM_TELEM_USB_TX_BUF_LEN);
|
||||
uint8_t *rx_buffer = (uint8_t *)pvPortMalloc(PIOS_COM_TELEM_USB_RX_BUF_LEN);
|
||||
uint8_t *tx_buffer = (uint8_t *)pvPortMalloc(PIOS_COM_TELEM_USB_TX_BUF_LEN);
|
||||
PIOS_Assert(rx_buffer);
|
||||
PIOS_Assert(tx_buffer);
|
||||
if (PIOS_COM_Init(&pios_com_telem_usb_id, &pios_usb_hid_com_driver, pios_usb_hid_id,
|
||||
@ -196,109 +156,97 @@ void PIOS_Board_Init(void) {
|
||||
PIOS_Assert(0);
|
||||
}
|
||||
}
|
||||
#endif /* PIOS_INCLUDE_COM */
|
||||
|
||||
#endif /* PIOS_INCLUDE_USB_HID */
|
||||
|
||||
#endif /* PIOS_INCLUDE_USB */
|
||||
|
||||
/* Configure USART1 (telemetry port) */
|
||||
switch (pipxSettings.TelemetryConfig)
|
||||
/* Configure the USB virtual com port (VCP) */
|
||||
#if defined(PIOS_INCLUDE_USB_CDC)
|
||||
if (usb_cdc_present)
|
||||
{
|
||||
case PIPXSETTINGS_TELEMETRYCONFIG_SERIAL:
|
||||
case PIPXSETTINGS_TELEMETRYCONFIG_UAVTALK:
|
||||
case PIPXSETTINGS_TELEMETRYCONFIG_GCS:
|
||||
case PIPXSETTINGS_TELEMETRYCONFIG_DEBUG:
|
||||
uint32_t pios_usb_cdc_id;
|
||||
if (PIOS_USB_CDC_Init(&pios_usb_cdc_id, &pios_usb_cdc_cfg, pios_usb_id)) {
|
||||
PIOS_Assert(0);
|
||||
}
|
||||
uint8_t *rx_buffer = (uint8_t *)pvPortMalloc(PIOS_COM_TELEM_VCP_RX_BUF_LEN);
|
||||
uint8_t *tx_buffer = (uint8_t *)pvPortMalloc(PIOS_COM_TELEM_VCP_TX_BUF_LEN);
|
||||
PIOS_Assert(rx_buffer);
|
||||
PIOS_Assert(tx_buffer);
|
||||
if (PIOS_COM_Init(&pios_com_telem_vcp_id, &pios_usb_cdc_com_driver, pios_usb_cdc_id,
|
||||
rx_buffer, PIOS_COM_TELEM_VCP_RX_BUF_LEN,
|
||||
tx_buffer, PIOS_COM_TELEM_VCP_TX_BUF_LEN)) {
|
||||
PIOS_Assert(0);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Configure the telemetry serial port */
|
||||
#ifndef PIOS_RFM22B_DEBUG_ON_TELEM
|
||||
{
|
||||
uint32_t pios_usart1_id;
|
||||
if (PIOS_USART_Init(&pios_usart1_id, &pios_usart_serial_cfg)) {
|
||||
PIOS_Assert(0);
|
||||
}
|
||||
uint8_t * rx_buffer = (uint8_t *) pvPortMalloc(PIOS_COM_SERIAL_RX_BUF_LEN);
|
||||
uint8_t * tx_buffer = (uint8_t *) pvPortMalloc(PIOS_COM_SERIAL_TX_BUF_LEN);
|
||||
uint8_t *rx_buffer = (uint8_t *)pvPortMalloc(PIOS_COM_TELEM_RX_BUF_LEN);
|
||||
uint8_t *tx_buffer = (uint8_t *)pvPortMalloc(PIOS_COM_TELEM_TX_BUF_LEN);
|
||||
PIOS_Assert(rx_buffer);
|
||||
PIOS_Assert(tx_buffer);
|
||||
if (PIOS_COM_Init(&pios_com_telemetry_id, &pios_usart_com_driver, pios_usart1_id,
|
||||
rx_buffer, PIOS_COM_SERIAL_RX_BUF_LEN,
|
||||
tx_buffer, PIOS_COM_SERIAL_TX_BUF_LEN)) {
|
||||
if (PIOS_COM_Init(&pios_com_telem_uart_telem_id, &pios_usart_com_driver, pios_usart1_id,
|
||||
rx_buffer, PIOS_COM_TELEM_RX_BUF_LEN,
|
||||
tx_buffer, PIOS_COM_TELEM_TX_BUF_LEN)) {
|
||||
PIOS_Assert(0);
|
||||
}
|
||||
switch (pipxSettings.TelemetryConfig)
|
||||
{
|
||||
case PIPXSETTINGS_TELEMETRYCONFIG_SERIAL:
|
||||
pios_com_trans_com_id = pios_com_telemetry_id;
|
||||
break;
|
||||
case PIPXSETTINGS_TELEMETRYCONFIG_UAVTALK:
|
||||
pios_com_uavtalk_com_id = pios_com_telemetry_id;
|
||||
break;
|
||||
case PIPXSETTINGS_TELEMETRYCONFIG_GCS:
|
||||
pios_com_gcs_com_id = pios_com_telemetry_id;
|
||||
break;
|
||||
case PIPXSETTINGS_TELEMETRYCONFIG_DEBUG:
|
||||
pios_com_debug_id = pios_com_telemetry_id;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case PIPXSETTINGS_TELEMETRYCONFIG_DISABLED:
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Configure USART3 */
|
||||
switch (pipxSettings.FlexiConfig)
|
||||
/* Configure PPM input */
|
||||
#if defined(PIOS_INCLUDE_PPM)
|
||||
if (oplinkSettings.PPM == OPLINKSETTINGS_PPM_TRUE)
|
||||
{
|
||||
case PIPXSETTINGS_FLEXICONFIG_SERIAL:
|
||||
case PIPXSETTINGS_FLEXICONFIG_UAVTALK:
|
||||
case PIPXSETTINGS_FLEXICONFIG_GCS:
|
||||
case PIPXSETTINGS_FLEXICONFIG_DEBUG:
|
||||
uint32_t pios_ppm_id;
|
||||
PIOS_PPM_Init(&pios_ppm_id, &pios_ppm_cfg);
|
||||
|
||||
if (PIOS_RCVR_Init(&pios_ppm_rcvr_id, &pios_ppm_rcvr_driver, pios_ppm_id))
|
||||
PIOS_Assert(0);
|
||||
}
|
||||
else
|
||||
#endif /* PIOS_INCLUDE_PPM */
|
||||
|
||||
/* Configure the flexi serial port */
|
||||
{
|
||||
uint32_t pios_usart3_id;
|
||||
if (PIOS_USART_Init(&pios_usart3_id, &pios_usart_telem_flexi_cfg)) {
|
||||
PIOS_Assert(0);
|
||||
}
|
||||
uint8_t * rx_buffer = (uint8_t *) pvPortMalloc(PIOS_COM_FLEXI_RX_BUF_LEN);
|
||||
uint8_t * tx_buffer = (uint8_t *) pvPortMalloc(PIOS_COM_FLEXI_TX_BUF_LEN);
|
||||
uint8_t * rx_buffer = (uint8_t *) pvPortMalloc(PIOS_COM_TELEM_RX_BUF_LEN);
|
||||
uint8_t * tx_buffer = (uint8_t *) pvPortMalloc(PIOS_COM_TELEM_TX_BUF_LEN);
|
||||
PIOS_Assert(rx_buffer);
|
||||
PIOS_Assert(tx_buffer);
|
||||
if (PIOS_COM_Init(&pios_com_flexi_id, &pios_usart_com_driver, pios_usart3_id,
|
||||
rx_buffer, PIOS_COM_FLEXI_RX_BUF_LEN,
|
||||
tx_buffer, PIOS_COM_FLEXI_TX_BUF_LEN)) {
|
||||
if (PIOS_COM_Init(&pios_com_telem_uart_flexi_id, &pios_usart_com_driver, pios_usart3_id,
|
||||
rx_buffer, PIOS_COM_TELEM_RX_BUF_LEN,
|
||||
tx_buffer, PIOS_COM_TELEM_TX_BUF_LEN)) {
|
||||
PIOS_Assert(0);
|
||||
}
|
||||
switch (pipxSettings.FlexiConfig)
|
||||
{
|
||||
case PIPXSETTINGS_FLEXICONFIG_SERIAL:
|
||||
pios_com_trans_com_id = pios_com_flexi_id;
|
||||
break;
|
||||
case PIPXSETTINGS_FLEXICONFIG_UAVTALK:
|
||||
pios_com_uavtalk_com_id = pios_com_flexi_id;
|
||||
break;
|
||||
case PIPXSETTINGS_FLEXICONFIG_GCS:
|
||||
pios_com_gcs_com_id = pios_com_flexi_id;
|
||||
break;
|
||||
case PIPXSETTINGS_FLEXICONFIG_DEBUG:
|
||||
pios_com_debug_id = pios_com_flexi_id;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case PIPXSETTINGS_FLEXICONFIG_PPM_IN:
|
||||
#if defined(PIOS_INCLUDE_PPM)
|
||||
{
|
||||
uint32_t pios_ppm_id;
|
||||
PIOS_PPM_Init(&pios_ppm_id, &pios_ppm_cfg);
|
||||
|
||||
if (PIOS_RCVR_Init(&pios_ppm_rcvr_id, &pios_ppm_rcvr_driver, pios_ppm_id)) {
|
||||
PIOS_Assert(0);
|
||||
}
|
||||
/* Initalize the RFM22B radio COM device. */
|
||||
#if defined(PIOS_INCLUDE_RFM22B)
|
||||
{
|
||||
extern const struct pios_rfm22b_cfg * PIOS_BOARD_HW_DEFS_GetRfm22Cfg (uint32_t board_revision);
|
||||
const struct pios_board_info * bdinfo = &pios_board_info_blob;
|
||||
const struct pios_rfm22b_cfg *pios_rfm22b_cfg = PIOS_BOARD_HW_DEFS_GetRfm22Cfg(bdinfo->board_rev);
|
||||
if (PIOS_RFM22B_Init(&pios_rfm22b_id, PIOS_RFM22_SPI_PORT, pios_rfm22b_cfg->slave_num, pios_rfm22b_cfg)) {
|
||||
PIOS_Assert(0);
|
||||
}
|
||||
|
||||
uint8_t *rx_buffer = (uint8_t *) pvPortMalloc(PIOS_COM_RFM22B_RF_RX_BUF_LEN);
|
||||
uint8_t *tx_buffer = (uint8_t *) pvPortMalloc(PIOS_COM_RFM22B_RF_TX_BUF_LEN);
|
||||
PIOS_Assert(rx_buffer);
|
||||
PIOS_Assert(tx_buffer);
|
||||
if (PIOS_COM_Init(&pios_com_rfm22b_id, &pios_rfm22b_com_driver, pios_rfm22b_id,
|
||||
rx_buffer, PIOS_COM_RFM22B_RF_RX_BUF_LEN,
|
||||
tx_buffer, PIOS_COM_RFM22B_RF_TX_BUF_LEN)) {
|
||||
PIOS_Assert(0);
|
||||
}
|
||||
#endif /* PIOS_INCLUDE_PPM */
|
||||
break;
|
||||
case PIPXSETTINGS_FLEXICONFIG_PPM_OUT:
|
||||
case PIPXSETTINGS_FLEXICONFIG_RSSI:
|
||||
case PIPXSETTINGS_FLEXICONFIG_DISABLED:
|
||||
break;
|
||||
}
|
||||
#endif /* PIOS_INCLUDE_RFM22B */
|
||||
|
||||
/* Remap AFIO pin */
|
||||
GPIO_PinRemapConfig( GPIO_Remap_SWJ_NoJTRST, ENABLE);
|
||||
|
@ -60,7 +60,6 @@ MODULES += AltitudeHold FixedWingPathFollower PathPlanner TxPID
|
||||
#MODULES += VtolPathFollower ## OP-700: VtolPathFollower disabled because its currently unsafe - remove this line once Sambas code has been merged
|
||||
MODULES += CameraStab
|
||||
#MODULES += OveroSync
|
||||
MODULES += Radio
|
||||
MODULES += Telemetry
|
||||
PYMODULES =
|
||||
#FlightPlan
|
||||
@ -155,7 +154,6 @@ SRC += $(MATHLIB)/sin_lookup.c
|
||||
SRC += $(MATHLIB)/pid.c
|
||||
|
||||
## For RFM22b
|
||||
SRC += $(FLIGHTLIB)/packet_handler.c
|
||||
SRC += $(RSCODE)/berlekamp.c
|
||||
SRC += $(RSCODE)/crcgen.c
|
||||
SRC += $(RSCODE)/galois.c
|
||||
@ -176,6 +174,8 @@ SRC += $(PIOSCOMMON)/pios_ms5611.c
|
||||
SRC += $(PIOSCOMMON)/pios_crc.c
|
||||
SRC += $(PIOSCOMMON)/pios_com.c
|
||||
SRC += $(PIOSCOMMON)/pios_rfm22b.c
|
||||
SRC += $(PIOSCOMMON)/pios_rfm22b_com.c
|
||||
SRC += $(PIOSCOMMON)/pios_rfm22b_rcvr.c
|
||||
SRC += $(PIOSCOMMON)/pios_rcvr.c
|
||||
SRC += $(PIOSCOMMON)/pios_sbus.c
|
||||
SRC += $(PIOSCOMMON)/pios_flash_jedec.c
|
||||
|
@ -58,8 +58,9 @@
|
||||
|
||||
/* Variables related to the RFM22B functionality */
|
||||
#define PIOS_INCLUDE_RFM22B
|
||||
#define RFM22_EXT_INT_USE
|
||||
|
||||
#define PIOS_INCLUDE_RFM22B_COM
|
||||
#define PIOS_INCLUDE_RFM22B_RCVR
|
||||
|
||||
/* Select the sensors to include */
|
||||
#define PIOS_INCLUDE_HMC5883
|
||||
#define PIOS_HMC5883_HAS_GPIOS
|
||||
@ -93,6 +94,8 @@
|
||||
/* A really shitty setting saving implementation */
|
||||
#define PIOS_INCLUDE_FLASH_SECTOR_SETTINGS
|
||||
|
||||
//#define PIOS_INCLUDE_DEBUG_CONSOLE
|
||||
|
||||
/* Other Interfaces */
|
||||
//#define PIOS_INCLUDE_I2C_ESC
|
||||
|
||||
|
@ -219,6 +219,9 @@ uint32_t pios_rcvr_group_map[MANUALCONTROLSETTINGS_CHANNELGROUPS_NONE];
|
||||
#define PIOS_COM_BRIDGE_RX_BUF_LEN 65
|
||||
#define PIOS_COM_BRIDGE_TX_BUF_LEN 12
|
||||
|
||||
#define PIOS_COM_RFM22B_RF_RX_BUF_LEN 512
|
||||
#define PIOS_COM_RFM22B_RF_TX_BUF_LEN 512
|
||||
|
||||
#if defined(PIOS_INCLUDE_DEBUG_CONSOLE)
|
||||
#define PIOS_COM_DEBUGCONSOLE_TX_BUF_LEN 40
|
||||
uint32_t pios_com_debug_id;
|
||||
@ -229,6 +232,9 @@ uint32_t pios_com_telem_usb_id = 0;
|
||||
uint32_t pios_com_telem_rf_id = 0;
|
||||
uint32_t pios_com_bridge_id = 0;
|
||||
uint32_t pios_com_overo_id = 0;
|
||||
#if defined(PIOS_INCLUDE_RFM22B)
|
||||
uint32_t pios_rfm22b_id = 0;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Setup a com port based on the passed cfg, driver and buffer sizes. tx size of -1 make the port rx only
|
||||
@ -522,7 +528,7 @@ void PIOS_Board_Init(void) {
|
||||
case HWSETTINGS_RM_MAINPORT_DEBUGCONSOLE:
|
||||
#if defined(PIOS_INCLUDE_DEBUG_CONSOLE)
|
||||
{
|
||||
PIOS_Board_configure_com(&pios_usart_main_cfg, 0, PIOS_COM_DEBUGCONSOLE_TX_BUF_LEN, &pios_usart_com_driver, &pios_com_aux_id);
|
||||
PIOS_Board_configure_com(&pios_usart_main_cfg, 0, PIOS_COM_DEBUGCONSOLE_TX_BUF_LEN, &pios_usart_com_driver, &pios_com_debug_id);
|
||||
}
|
||||
#endif /* PIOS_INCLUDE_DEBUG_CONSOLE */
|
||||
break;
|
||||
@ -585,16 +591,53 @@ void PIOS_Board_Init(void) {
|
||||
case HWSETTINGS_RM_FLEXIPORT_DEBUGCONSOLE:
|
||||
#if defined(PIOS_INCLUDE_DEBUG_CONSOLE)
|
||||
{
|
||||
PIOS_Board_configure_com(&pios_usart_flexi_cfg, 0, PIOS_COM_DEBUGCONSOLE_TX_BUF_LEN, &pios_usart_com_driver, &pios_com_aux_id);
|
||||
PIOS_Board_configure_com(&pios_usart_main_cfg, 0, PIOS_COM_DEBUGCONSOLE_TX_BUF_LEN, &pios_usart_com_driver, &pios_com_debug_id);
|
||||
}
|
||||
#endif /* PIOS_INCLUDE_DEBUG_CONSOLE */
|
||||
break;
|
||||
case HWSETTINGS_RM_FLEXIPORT_COMBRIDGE:
|
||||
PIOS_Board_configure_com(&pios_usart_flexi_cfg, PIOS_COM_BRIDGE_RX_BUF_LEN, PIOS_COM_BRIDGE_TX_BUF_LEN, &pios_usart_com_driver, &pios_com_bridge_id);
|
||||
break;
|
||||
} /* hwsettings_rm_flexiport */
|
||||
|
||||
|
||||
} /* hwsettings_rv_flexiport */
|
||||
|
||||
/* Initalize the RFM22B radio COM device. */
|
||||
#if defined(PIOS_INCLUDE_RFM22B)
|
||||
uint8_t hwsettings_radioport;
|
||||
HwSettingsRadioPortGet(&hwsettings_radioport);
|
||||
switch (hwsettings_radioport) {
|
||||
case HWSETTINGS_RADIOPORT_DISABLED:
|
||||
break;
|
||||
case HWSETTINGS_RADIOPORT_TELEMETRY:
|
||||
{
|
||||
extern const struct pios_rfm22b_cfg * PIOS_BOARD_HW_DEFS_GetRfm22Cfg (uint32_t board_revision);
|
||||
const struct pios_board_info * bdinfo = &pios_board_info_blob;
|
||||
const struct pios_rfm22b_cfg *pios_rfm22b_cfg = PIOS_BOARD_HW_DEFS_GetRfm22Cfg(bdinfo->board_rev);
|
||||
if (PIOS_RFM22B_Init(&pios_rfm22b_id, PIOS_RFM22_SPI_PORT, pios_rfm22b_cfg->slave_num, pios_rfm22b_cfg)) {
|
||||
PIOS_Assert(0);
|
||||
}
|
||||
#ifdef PIOS_INCLUDE_RFM22B_COM
|
||||
uint8_t *rx_buffer = (uint8_t *) pvPortMalloc(PIOS_COM_RFM22B_RF_RX_BUF_LEN);
|
||||
uint8_t *tx_buffer = (uint8_t *) pvPortMalloc(PIOS_COM_RFM22B_RF_TX_BUF_LEN);
|
||||
PIOS_Assert(rx_buffer);
|
||||
PIOS_Assert(tx_buffer);
|
||||
if (PIOS_COM_Init(&pios_com_telem_rf_id, &pios_rfm22b_com_driver, pios_rfm22b_id,
|
||||
rx_buffer, PIOS_COM_RFM22B_RF_RX_BUF_LEN,
|
||||
tx_buffer, PIOS_COM_RFM22B_RF_TX_BUF_LEN))
|
||||
PIOS_Assert(0);
|
||||
#endif
|
||||
#ifdef PIOS_INCLUDE_RFM22B_RCVR
|
||||
if (PIOS_RFM22B_RCVR_Init(pios_rfm22b_id) != 0)
|
||||
PIOS_Assert(0);
|
||||
uint32_t pios_rfm22b_rcvr_id;
|
||||
if (PIOS_RCVR_Init(&pios_rfm22b_rcvr_id, &pios_rfm22b_rcvr_driver, pios_rfm22b_id))
|
||||
PIOS_Assert(0);
|
||||
pios_rcvr_group_map[MANUALCONTROLSETTINGS_CHANNELGROUPS_OPLINK] = pios_rfm22b_rcvr_id;
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif /* PIOS_INCLUDE_RFM22B */
|
||||
|
||||
/* Configure the receiver port*/
|
||||
uint8_t hwsettings_rcvrport;
|
||||
HwSettingsRM_RcvrPortGet(&hwsettings_rcvrport);
|
||||
|
@ -97,11 +97,5 @@ UAVOBJSRCFILENAMES += waypointactive
|
||||
|
||||
UAVOBJSRCFILENAMES += txpidsettings
|
||||
|
||||
#Support for radio module on RM
|
||||
UAVOBJSRCFILENAMES += pipxstatus
|
||||
UAVOBJSRCFILENAMES += pipxsettings
|
||||
|
||||
|
||||
|
||||
UAVOBJSRC = $(foreach UAVOBJSRCFILE,$(UAVOBJSRCFILENAMES),$(UAVOBJSYNTHDIR)/$(UAVOBJSRCFILE).c )
|
||||
UAVOBJDEFINE = $(foreach UAVOBJSRCFILE,$(UAVOBJSRCFILENAMES),-DUAVOBJ_INIT_$(UAVOBJSRCFILE) )
|
||||
|
@ -46,40 +46,53 @@
|
||||
#define $(NAMEUC)_ISSETTINGS $(ISSETTINGS)
|
||||
#define $(NAMEUC)_NUMBYTES sizeof($(NAME)Data)
|
||||
|
||||
// Object access macros
|
||||
/**
|
||||
* @function $(NAME)Get(dataOut)
|
||||
* @brief Populate a $(NAME)Data object
|
||||
* @param[out] dataOut
|
||||
*/
|
||||
#define $(NAME)Get(dataOut) UAVObjGetData($(NAME)Handle(), dataOut)
|
||||
#define $(NAME)Set(dataIn) UAVObjSetData($(NAME)Handle(), dataIn)
|
||||
#define $(NAME)InstGet(instId, dataOut) UAVObjGetInstanceData($(NAME)Handle(), instId, dataOut)
|
||||
#define $(NAME)InstSet(instId, dataIn) UAVObjSetInstanceData($(NAME)Handle(), instId, dataIn)
|
||||
#define $(NAME)ConnectQueue(queue) UAVObjConnectQueue($(NAME)Handle(), queue, EV_MASK_ALL_UPDATES)
|
||||
#define $(NAME)ConnectCallback(cb) UAVObjConnectCallback($(NAME)Handle(), cb, EV_MASK_ALL_UPDATES)
|
||||
#define $(NAME)CreateInstance() UAVObjCreateInstance($(NAME)Handle(),&$(NAME)SetDefaults)
|
||||
#define $(NAME)RequestUpdate() UAVObjRequestUpdate($(NAME)Handle())
|
||||
#define $(NAME)RequestInstUpdate(instId) UAVObjRequestInstanceUpdate($(NAME)Handle(), instId)
|
||||
#define $(NAME)Updated() UAVObjUpdated($(NAME)Handle())
|
||||
#define $(NAME)InstUpdated(instId) UAVObjUpdated($(NAME)Handle(), instId)
|
||||
#define $(NAME)GetMetadata(dataOut) UAVObjGetMetadata($(NAME)Handle(), dataOut)
|
||||
#define $(NAME)SetMetadata(dataIn) UAVObjSetMetadata($(NAME)Handle(), dataIn)
|
||||
#define $(NAME)ReadOnly() UAVObjReadOnly($(NAME)Handle())
|
||||
// Generic interface functions
|
||||
int32_t $(NAME)Initialize();
|
||||
UAVObjHandle $(NAME)Handle();
|
||||
void $(NAME)SetDefaults(UAVObjHandle obj, uint16_t instId);
|
||||
|
||||
// Object data
|
||||
typedef struct {
|
||||
$(DATAFIELDS)
|
||||
} __attribute__((packed)) $(NAME)Data;
|
||||
|
||||
// Typesafe Object access functions
|
||||
/**
|
||||
* @function $(NAME)Get(dataOut)
|
||||
* @brief Populate a $(NAME)Data object
|
||||
* @param[out] dataOut
|
||||
*/
|
||||
static inline int32_t $(NAME)Get($(NAME)Data *dataOut) { return UAVObjGetData($(NAME)Handle(), dataOut); }
|
||||
|
||||
static inline int32_t $(NAME)Set(const $(NAME)Data *dataIn) { return UAVObjSetData($(NAME)Handle(), dataIn); }
|
||||
|
||||
static inline int32_t $(NAME)InstGet(uint16_t instId, $(NAME)Data *dataOut) { return UAVObjGetInstanceData($(NAME)Handle(), instId, dataOut); }
|
||||
|
||||
static inline int32_t $(NAME)InstSet(uint16_t instId, const $(NAME)Data *dataIn) { return UAVObjSetInstanceData($(NAME)Handle(), instId, dataIn); }
|
||||
|
||||
static inline int32_t $(NAME)ConnectQueue(xQueueHandle queue) { return UAVObjConnectQueue($(NAME)Handle(), queue, EV_MASK_ALL_UPDATES); }
|
||||
|
||||
static inline int32_t $(NAME)ConnectCallback(UAVObjEventCallback cb) { return UAVObjConnectCallback($(NAME)Handle(), cb, EV_MASK_ALL_UPDATES); }
|
||||
|
||||
static inline uint16_t $(NAME)CreateInstance() { return UAVObjCreateInstance($(NAME)Handle(), &$(NAME)SetDefaults); }
|
||||
|
||||
static inline void $(NAME)RequestUpdate() { UAVObjRequestUpdate($(NAME)Handle()); }
|
||||
|
||||
static inline void $(NAME)RequestInstUpdate(uint16_t instId) { UAVObjRequestInstanceUpdate($(NAME)Handle(), instId); }
|
||||
|
||||
static inline void $(NAME)Updated() { UAVObjUpdated($(NAME)Handle()); }
|
||||
|
||||
static inline void $(NAME)InstUpdated(uint16_t instId) { UAVObjInstanceUpdated($(NAME)Handle(), instId); }
|
||||
|
||||
static inline int32_t $(NAME)GetMetadata(UAVObjMetadata *dataOut) { return UAVObjGetMetadata($(NAME)Handle(), dataOut); }
|
||||
|
||||
static inline int32_t $(NAME)SetMetadata(const UAVObjMetadata *dataIn) { return UAVObjSetMetadata($(NAME)Handle(), dataIn); }
|
||||
|
||||
static inline int8_t $(NAME)ReadOnly() { return UAVObjReadOnly($(NAME)Handle()); }
|
||||
|
||||
// Field information
|
||||
$(DATAFIELDINFO)
|
||||
|
||||
// Generic interface functions
|
||||
int32_t $(NAME)Initialize();
|
||||
UAVObjHandle $(NAME)Handle();
|
||||
void $(NAME)SetDefaults(UAVObjHandle obj, uint16_t instId);
|
||||
|
||||
// set/Get functions
|
||||
$(SETGETFIELDSEXTERN)
|
||||
|
||||
|
@ -41,6 +41,17 @@
|
||||
// Macros
|
||||
#define SET_BITS(var, shift, value, mask) var = (var & ~(mask << shift)) | (value << shift);
|
||||
|
||||
/* Table of UAVO handles registered at compile time */
|
||||
extern struct UAVOData * __start__uavo_handles[] __attribute__((weak));
|
||||
extern struct UAVOData * __stop__uavo_handles[] __attribute__((weak));
|
||||
|
||||
#define UAVO_LIST_ITERATE(_item) \
|
||||
for (struct UAVOData ** _uavo_slot = __start__uavo_handles; \
|
||||
_uavo_slot && _uavo_slot < __stop__uavo_handles; \
|
||||
_uavo_slot++) { \
|
||||
struct UAVOData * _item = *_uavo_slot; \
|
||||
if (_item == NULL) continue;
|
||||
|
||||
/**
|
||||
* List of event queues and the eventmask associated with the queue.
|
||||
*/
|
||||
@ -98,7 +109,6 @@ struct UAVOData {
|
||||
* inside the payload for this UAVO.
|
||||
*/
|
||||
struct UAVOMeta metaObj;
|
||||
struct UAVOData * next;
|
||||
uint16_t instance_size;
|
||||
} __attribute__((packed));
|
||||
|
||||
@ -164,7 +174,6 @@ static void customSPrintf(uint8_t * buffer, uint8_t * format, ...);
|
||||
#endif
|
||||
|
||||
// Private variables
|
||||
static struct UAVOData * uavo_list;
|
||||
static xSemaphoreHandle mutex;
|
||||
static const UAVObjMetadata defMetadata = {
|
||||
.flags = (ACCESS_READWRITE << UAVOBJ_ACCESS_SHIFT |
|
||||
@ -188,9 +197,12 @@ static UAVObjStats stats;
|
||||
int32_t UAVObjInitialize()
|
||||
{
|
||||
// Initialize variables
|
||||
uavo_list = NULL;
|
||||
memset(&stats, 0, sizeof(UAVObjStats));
|
||||
|
||||
// Initialize the uavo handle table
|
||||
memset(__start__uavo_handles, 0,
|
||||
(uintptr_t)__stop__uavo_handles - (uintptr_t)__start__uavo_handles);
|
||||
|
||||
// Create mutex
|
||||
mutex = xSemaphoreCreateRecursiveMutex();
|
||||
if (mutex == NULL)
|
||||
@ -338,9 +350,6 @@ UAVObjHandle UAVObjRegister(uint32_t id,
|
||||
/* Initialize the embedded meta UAVO */
|
||||
UAVObjInitMetaData (&uavo_data->metaObj);
|
||||
|
||||
/* Add the newly created object to the global list of objects */
|
||||
LL_APPEND(uavo_list, uavo_data);
|
||||
|
||||
/* Initialize object fields and metadata to default values */
|
||||
if (initCb)
|
||||
initCb((UAVObjHandle) uavo_data, 0);
|
||||
@ -374,8 +383,7 @@ UAVObjHandle UAVObjGetByID(uint32_t id)
|
||||
xSemaphoreTakeRecursive(mutex, portMAX_DELAY);
|
||||
|
||||
// Look for object
|
||||
struct UAVOData * tmp_obj;
|
||||
LL_FOREACH(uavo_list, tmp_obj) {
|
||||
UAVO_LIST_ITERATE(tmp_obj)
|
||||
if (tmp_obj->id == id) {
|
||||
found_obj = (UAVObjHandle *)tmp_obj;
|
||||
goto unlock_exit;
|
||||
@ -1019,15 +1027,13 @@ int32_t UAVObjDelete(UAVObjHandle obj_handle, uint16_t instId)
|
||||
*/
|
||||
int32_t UAVObjSaveSettings()
|
||||
{
|
||||
struct UAVOData *obj;
|
||||
|
||||
// Get lock
|
||||
xSemaphoreTakeRecursive(mutex, portMAX_DELAY);
|
||||
|
||||
int32_t rc = -1;
|
||||
|
||||
// Save all settings objects
|
||||
LL_FOREACH(uavo_list, obj) {
|
||||
UAVO_LIST_ITERATE(obj)
|
||||
// Check if this is a settings object
|
||||
if (UAVObjIsSettings(obj)) {
|
||||
// Save object
|
||||
@ -1051,15 +1057,13 @@ unlock_exit:
|
||||
*/
|
||||
int32_t UAVObjLoadSettings()
|
||||
{
|
||||
struct UAVOData *obj;
|
||||
|
||||
// Get lock
|
||||
xSemaphoreTakeRecursive(mutex, portMAX_DELAY);
|
||||
|
||||
int32_t rc = -1;
|
||||
|
||||
// Load all settings objects
|
||||
LL_FOREACH(uavo_list, obj) {
|
||||
UAVO_LIST_ITERATE(obj)
|
||||
// Check if this is a settings object
|
||||
if (UAVObjIsSettings(obj)) {
|
||||
// Load object
|
||||
@ -1083,15 +1087,13 @@ unlock_exit:
|
||||
*/
|
||||
int32_t UAVObjDeleteSettings()
|
||||
{
|
||||
struct UAVOData *obj;
|
||||
|
||||
// Get lock
|
||||
xSemaphoreTakeRecursive(mutex, portMAX_DELAY);
|
||||
|
||||
int32_t rc = -1;
|
||||
|
||||
// Save all settings objects
|
||||
LL_FOREACH(uavo_list, obj) {
|
||||
UAVO_LIST_ITERATE(obj)
|
||||
// Check if this is a settings object
|
||||
if (UAVObjIsSettings(obj)) {
|
||||
// Save object
|
||||
@ -1115,15 +1117,13 @@ unlock_exit:
|
||||
*/
|
||||
int32_t UAVObjSaveMetaobjects()
|
||||
{
|
||||
struct UAVOData *obj;
|
||||
|
||||
// Get lock
|
||||
xSemaphoreTakeRecursive(mutex, portMAX_DELAY);
|
||||
|
||||
int32_t rc = -1;
|
||||
|
||||
// Save all settings objects
|
||||
LL_FOREACH(uavo_list, obj) {
|
||||
UAVO_LIST_ITERATE(obj)
|
||||
// Save object
|
||||
if (UAVObjSave( (UAVObjHandle) MetaObjectPtr(obj), 0) ==
|
||||
-1) {
|
||||
@ -1144,15 +1144,13 @@ unlock_exit:
|
||||
*/
|
||||
int32_t UAVObjLoadMetaobjects()
|
||||
{
|
||||
struct UAVOData *obj;
|
||||
|
||||
// Get lock
|
||||
xSemaphoreTakeRecursive(mutex, portMAX_DELAY);
|
||||
|
||||
int32_t rc = -1;
|
||||
|
||||
// Load all settings objects
|
||||
LL_FOREACH(uavo_list, obj) {
|
||||
UAVO_LIST_ITERATE(obj)
|
||||
// Load object
|
||||
if (UAVObjLoad((UAVObjHandle) MetaObjectPtr(obj), 0) ==
|
||||
-1) {
|
||||
@ -1173,15 +1171,13 @@ unlock_exit:
|
||||
*/
|
||||
int32_t UAVObjDeleteMetaobjects()
|
||||
{
|
||||
struct UAVOData *obj;
|
||||
|
||||
// Get lock
|
||||
xSemaphoreTakeRecursive(mutex, portMAX_DELAY);
|
||||
|
||||
int32_t rc = -1;
|
||||
|
||||
// Load all settings objects
|
||||
LL_FOREACH(uavo_list, obj) {
|
||||
UAVO_LIST_ITERATE(obj)
|
||||
// Load object
|
||||
if (UAVObjDelete((UAVObjHandle) MetaObjectPtr(obj), 0)
|
||||
== -1) {
|
||||
@ -1787,8 +1783,7 @@ void UAVObjIterate(void (*iterator) (UAVObjHandle obj))
|
||||
xSemaphoreTakeRecursive(mutex, portMAX_DELAY);
|
||||
|
||||
// Iterate through the list and invoke iterator for each object
|
||||
struct UAVOData *obj;
|
||||
LL_FOREACH(uavo_list, obj) {
|
||||
UAVO_LIST_ITERATE(obj)
|
||||
(*iterator) ((UAVObjHandle) obj);
|
||||
(*iterator) ((UAVObjHandle) &obj->metaObj);
|
||||
}
|
||||
|
@ -40,7 +40,7 @@
|
||||
#include "$(NAMELC).h"
|
||||
|
||||
// Private variables
|
||||
static UAVObjHandle handle = NULL;
|
||||
static UAVObjHandle handle __attribute__((section("_uavo_handles")));
|
||||
|
||||
/**
|
||||
* Initialize object.
|
||||
|
@ -59,6 +59,7 @@ int32_t UAVTalkSendNack(UAVTalkConnection connectionHandle, uint32_t objId);
|
||||
int32_t UAVTalkSendBuf(UAVTalkConnection connectionHandle, uint8_t *buf, uint16_t len);
|
||||
UAVTalkRxState UAVTalkProcessInputStream(UAVTalkConnection connection, uint8_t rxbyte);
|
||||
UAVTalkRxState UAVTalkProcessInputStreamQuiet(UAVTalkConnection connection, uint8_t rxbyte);
|
||||
UAVTalkRxState UAVTalkRelayInputStream(UAVTalkConnection connectionHandle, uint8_t rxbyte);
|
||||
void UAVTalkGetStats(UAVTalkConnection connection, UAVTalkStats *stats);
|
||||
void UAVTalkResetStats(UAVTalkConnection connection);
|
||||
void UAVTalkGetLastTimestamp(UAVTalkConnection connection, uint16_t *timestamp);
|
||||
|
@ -558,6 +558,73 @@ UAVTalkRxState UAVTalkProcessInputStream(UAVTalkConnection connectionHandle, uin
|
||||
return state;
|
||||
}
|
||||
|
||||
/**
|
||||
* Process an byte from the telemetry stream, sending the packet out the output stream when it's complete
|
||||
* This allows the interlieving of packets on an output UAVTalk stream, and is used by the OPLink device to
|
||||
* relay packets from an input com port to a different output com port without sending one packet in the middle
|
||||
* of another packet. Because this uses both the receive buffer and transmit buffer, it should only be used
|
||||
* for relaying a packet, not for the standard sending and receiving of packets.
|
||||
* \param[in] connection UAVTalkConnection to be used
|
||||
* \param[in] rxbyte Received byte
|
||||
* \return UAVTalkRxState
|
||||
*/
|
||||
UAVTalkRxState UAVTalkRelayInputStream(UAVTalkConnection connectionHandle, uint8_t rxbyte)
|
||||
{
|
||||
UAVTalkRxState state = UAVTalkProcessInputStreamQuiet(connectionHandle, rxbyte);
|
||||
|
||||
if (state == UAVTALK_STATE_COMPLETE)
|
||||
{
|
||||
UAVTalkConnectionData *connection;
|
||||
CHECKCONHANDLE(connectionHandle,connection,return -1);
|
||||
UAVTalkInputProcessor *iproc = &connection->iproc;
|
||||
|
||||
if (!connection->outStream) return -1;
|
||||
|
||||
// Setup type and object id fields
|
||||
connection->txBuffer[0] = UAVTALK_SYNC_VAL; // sync byte
|
||||
connection->txBuffer[1] = iproc->type;
|
||||
// data length inserted here below
|
||||
connection->txBuffer[4] = (uint8_t)(iproc->objId & 0xFF);
|
||||
connection->txBuffer[5] = (uint8_t)((iproc->objId >> 8) & 0xFF);
|
||||
connection->txBuffer[6] = (uint8_t)((iproc->objId >> 16) & 0xFF);
|
||||
connection->txBuffer[7] = (uint8_t)((iproc->objId >> 24) & 0xFF);
|
||||
|
||||
// Setup instance ID if one is required
|
||||
int32_t dataOffset = 8;
|
||||
if (iproc->instanceLength > 0)
|
||||
{
|
||||
connection->txBuffer[8] = (uint8_t)(iproc->instId & 0xFF);
|
||||
connection->txBuffer[9] = (uint8_t)((iproc->instId >> 8) & 0xFF);
|
||||
dataOffset = 10;
|
||||
}
|
||||
|
||||
// Add timestamp when the transaction type is appropriate
|
||||
if (iproc->type & UAVTALK_TIMESTAMPED)
|
||||
{
|
||||
portTickType time = xTaskGetTickCount();
|
||||
connection->txBuffer[dataOffset] = (uint8_t)(time & 0xFF);
|
||||
connection->txBuffer[dataOffset + 1] = (uint8_t)((time >> 8) & 0xFF);
|
||||
dataOffset += 2;
|
||||
}
|
||||
|
||||
// Copy data (if any)
|
||||
memcpy(&connection->txBuffer[dataOffset], connection->rxBuffer, iproc->length);
|
||||
|
||||
// Store the packet length
|
||||
connection->txBuffer[2] = (uint8_t)((dataOffset + iproc->length) & 0xFF);
|
||||
connection->txBuffer[3] = (uint8_t)(((dataOffset + iproc->length) >> 8) & 0xFF);
|
||||
|
||||
// Copy the checksum
|
||||
connection->txBuffer[dataOffset + iproc->length] = iproc->cs;
|
||||
|
||||
// Send the buffer.
|
||||
if (UAVTalkSendBuf(connectionHandle, connection->txBuffer, iproc->rxPacketLength) < 0)
|
||||
return UAVTALK_STATE_ERROR;
|
||||
}
|
||||
|
||||
return state;
|
||||
}
|
||||
|
||||
/**
|
||||
* Send a ACK through the telemetry link.
|
||||
* \param[in] connectionHandle UAVTalkConnection to be used
|
||||
|
@ -45,6 +45,48 @@ static const struct pios_led pios_leds[] = {
|
||||
},
|
||||
},
|
||||
},
|
||||
#ifdef PIOS_RFM22B_DEBUG_ON_TELEM
|
||||
[PIOS_LED_D1] = {
|
||||
.pin = {
|
||||
.gpio = GPIOB,
|
||||
.init = {
|
||||
.GPIO_Pin = GPIO_Pin_14,
|
||||
.GPIO_Mode = GPIO_Mode_Out_PP,
|
||||
.GPIO_Speed = GPIO_Speed_50MHz,
|
||||
},
|
||||
},
|
||||
},
|
||||
[PIOS_LED_D2] = {
|
||||
.pin = {
|
||||
.gpio = GPIOB,
|
||||
.init = {
|
||||
.GPIO_Pin = GPIO_Pin_15,
|
||||
.GPIO_Mode = GPIO_Mode_Out_PP,
|
||||
.GPIO_Speed = GPIO_Speed_50MHz,
|
||||
},
|
||||
},
|
||||
},
|
||||
[PIOS_LED_D3] = {
|
||||
.pin = {
|
||||
.gpio = GPIOA,
|
||||
.init = {
|
||||
.GPIO_Pin = GPIO_Pin_9,
|
||||
.GPIO_Mode = GPIO_Mode_Out_PP,
|
||||
.GPIO_Speed = GPIO_Speed_50MHz,
|
||||
},
|
||||
},
|
||||
},
|
||||
[PIOS_LED_D4] = {
|
||||
.pin = {
|
||||
.gpio = GPIOA,
|
||||
.init = {
|
||||
.GPIO_Pin = GPIO_Pin_10,
|
||||
.GPIO_Mode = GPIO_Mode_Out_PP,
|
||||
.GPIO_Speed = GPIO_Speed_50MHz,
|
||||
},
|
||||
},
|
||||
},
|
||||
#endif
|
||||
};
|
||||
|
||||
static const struct pios_led_cfg pios_led_cfg = {
|
||||
@ -222,12 +264,7 @@ static const struct pios_exti_cfg pios_exti_rfm22b_cfg __exti_config = {
|
||||
struct pios_rfm22b_cfg pios_rfm22b_pipx_cfg = {
|
||||
.spi_cfg = &pios_spi_rfm22b_cfg,
|
||||
.exti_cfg = &pios_exti_rfm22b_cfg,
|
||||
.frequencyHz = 434000000,
|
||||
.minFrequencyHz = 434000000 - 2000000,
|
||||
.maxFrequencyHz = 434000000 + 2000000,
|
||||
.RFXtalCap = 0x7f,
|
||||
.maxRFBandwidth = 64000,
|
||||
.maxTxPower = RFM22_tx_pwr_txpow_7, // +20dBm .. 100mW
|
||||
.slave_num = 0,
|
||||
.gpio_direction = GPIO0_TX_GPIO1_RX,
|
||||
};
|
||||
|
@ -522,12 +522,7 @@ static const struct pios_exti_cfg pios_exti_rfm22b_cfg __exti_config = {
|
||||
const struct pios_rfm22b_cfg pios_rfm22b_rm1_cfg = {
|
||||
.spi_cfg = &pios_spi_telem_flash_cfg,
|
||||
.exti_cfg = &pios_exti_rfm22b_cfg,
|
||||
.frequencyHz = 434000000,
|
||||
.minFrequencyHz = 434000000 - 2000000,
|
||||
.maxFrequencyHz = 434000000 + 2000000,
|
||||
.RFXtalCap = 0x7f,
|
||||
.maxRFBandwidth = 64000,
|
||||
.maxTxPower = RFM22_tx_pwr_txpow_7, // +20dBm .. 100mW
|
||||
.slave_num = 0,
|
||||
.gpio_direction = GPIO0_RX_GPIO1_TX,
|
||||
};
|
||||
@ -535,12 +530,7 @@ const struct pios_rfm22b_cfg pios_rfm22b_rm1_cfg = {
|
||||
const struct pios_rfm22b_cfg pios_rfm22b_rm2_cfg = {
|
||||
.spi_cfg = &pios_spi_telem_flash_cfg,
|
||||
.exti_cfg = &pios_exti_rfm22b_cfg,
|
||||
.frequencyHz = 434000000,
|
||||
.minFrequencyHz = 434000000 - 2000000,
|
||||
.maxFrequencyHz = 434000000 + 2000000,
|
||||
.RFXtalCap = 0x7f,
|
||||
.maxRFBandwidth = 64000,
|
||||
.maxTxPower = RFM22_tx_pwr_txpow_7, // +20dBm .. 100mW
|
||||
.slave_num = 0,
|
||||
.gpio_direction = GPIO0_TX_GPIO1_RX,
|
||||
};
|
||||
|
@ -6,6 +6,7 @@ TEMPLATE = subdirs
|
||||
equals(copydata, 1) {
|
||||
|
||||
# Windows release only, no debug target DLLs ending with 'd'
|
||||
# It is assumed that SDL.dll can be found in the same directory as mingw32-make.exe
|
||||
win32:CONFIG(release, debug|release) {
|
||||
|
||||
# copy Qt DLLs and phonon4
|
||||
@ -29,7 +30,7 @@ equals(copydata, 1) {
|
||||
MINGW_DLLS = libgcc_s_dw2-1.dll \
|
||||
mingwm10.dll
|
||||
for(dll, MINGW_DLLS) {
|
||||
data_copy.commands += $(COPY_FILE) $$targetPath(\"$$[QT_INSTALL_BINS]/../../../../../mingw/bin/$$dll\") $$targetPath(\"$$GCS_APP_PATH/$$dll\") $$addNewline()
|
||||
data_copy.commands += $(COPY_FILE) $$targetPath(\"$$(QTMINGW)/$$dll\") $$targetPath(\"$$GCS_APP_PATH/$$dll\") $$addNewline()
|
||||
}
|
||||
|
||||
# copy iconengines
|
||||
@ -74,7 +75,7 @@ equals(copydata, 1) {
|
||||
# xcopy /s /e <SDL>\include\SDL\* C:\QtSDK\Desktop\Qt\4.7.3\mingw\include\SDL
|
||||
# xcopy /s /e <SDL>\lib\* C:\QtSDK\Desktop\Qt\4.7.3\mingw\lib
|
||||
SDL_DLL = SDL.dll
|
||||
data_copy.commands += $(COPY_FILE) $$targetPath(\"$$[QT_INSTALL_BINS]/../../mingw/bin/$$SDL_DLL\") $$targetPath(\"$$GCS_APP_PATH/$$SDL_DLL\") $$addNewline()
|
||||
data_copy.commands += $(COPY_FILE) $$targetPath(\"$$(QTMINGW)/$$SDL_DLL\") $$targetPath(\"$$GCS_APP_PATH/$$SDL_DLL\") $$addNewline()
|
||||
|
||||
data_copy.target = FORCE
|
||||
QMAKE_EXTRA_TARGETS += data_copy
|
||||
|
@ -9,6 +9,8 @@ include(openpilotgcs.pri)
|
||||
TEMPLATE = subdirs
|
||||
CONFIG += ordered
|
||||
|
||||
DEFINES += USE_PATHPLANNER
|
||||
|
||||
SUBDIRS = src share copydata
|
||||
unix:!macx:!isEmpty(copydata):SUBDIRS += bin
|
||||
|
||||
|
@ -5,8 +5,8 @@
|
||||
<UDPMirror>false</UDPMirror>
|
||||
<Description>Default configuration</Description>
|
||||
<Details>Default configuration built to work on all screen sizes</Details>
|
||||
<ExpertMode>true</ExpertMode>
|
||||
<OverrideLanguage>en_AU</OverrideLanguage>
|
||||
<ExpertMode>false</ExpertMode>
|
||||
<OverrideLanguage>C</OverrideLanguage>
|
||||
<SaveSettingsOnExit>true</SaveSettingsOnExit>
|
||||
<SettingsWindowHeight>700</SettingsWindowHeight>
|
||||
<SettingsWindowWidth>800</SettingsWindowWidth>
|
||||
@ -2538,22 +2538,6 @@
|
||||
</data>
|
||||
</default>
|
||||
</UAVObjectBrowser>
|
||||
<Uploader>
|
||||
<default>
|
||||
<configInfo>
|
||||
<locked>false</locked>
|
||||
<version>0.0.0</version>
|
||||
</configInfo>
|
||||
<data>
|
||||
<defaultDataBits>3</defaultDataBits>
|
||||
<defaultFlow>0</defaultFlow>
|
||||
<defaultParity>0</defaultParity>
|
||||
<defaultPort>/dev/ttyS0</defaultPort>
|
||||
<defaultSpeed>14</defaultSpeed>
|
||||
<defaultStopBits>0</defaultStopBits>
|
||||
</data>
|
||||
</default>
|
||||
</Uploader>
|
||||
<configInfo>
|
||||
<locked>false</locked>
|
||||
<version>1.2.0</version>
|
||||
@ -2666,27 +2650,18 @@
|
||||
</side0>
|
||||
<side1>
|
||||
<side0>
|
||||
<side0>
|
||||
<classId>LoggingGadget</classId>
|
||||
<type>uavGadget</type>
|
||||
</side0>
|
||||
<side1>
|
||||
<classId>GpsDisplayGadget</classId>
|
||||
<gadget>
|
||||
<activeConfiguration>Flight GPS</activeConfiguration>
|
||||
</gadget>
|
||||
<type>uavGadget</type>
|
||||
</side1>
|
||||
<splitterOrientation>2</splitterOrientation>
|
||||
<splitterSizes>@Variant(AAAACQAAAAIAAAACAAAAcAAAAAIAAAHo)</splitterSizes>
|
||||
<type>splitter</type>
|
||||
<classId>LoggingGadget</classId>
|
||||
<type>uavGadget</type>
|
||||
</side0>
|
||||
<side1>
|
||||
<classId>DebugGadget</classId>
|
||||
<classId>GpsDisplayGadget</classId>
|
||||
<gadget>
|
||||
<activeConfiguration>Flight GPS</activeConfiguration>
|
||||
</gadget>
|
||||
<type>uavGadget</type>
|
||||
</side1>
|
||||
<splitterOrientation>2</splitterOrientation>
|
||||
<splitterSizes>@Variant(AAAACQAAAAIAAAACAAAB3wAAAAIAAAEp)</splitterSizes>
|
||||
<splitterSizes>@Variant(AAAACQAAAAIAAAACAAAAVAAAAAIAAAGu)</splitterSizes>
|
||||
<type>splitter</type>
|
||||
</side1>
|
||||
<splitterOrientation>1</splitterOrientation>
|
||||
|
@ -8,6 +8,7 @@
|
||||
<SaveSettingsOnExit>true</SaveSettingsOnExit>
|
||||
<SettingsWindowHeight>700</SettingsWindowHeight>
|
||||
<SettingsWindowWidth>800</SettingsWindowWidth>
|
||||
<OverrideLanguage>C</OverrideLanguage>
|
||||
<UDPMirror>false</UDPMirror>
|
||||
<Description>Wide configuration</Description>
|
||||
<Details>Default configuration built for wide screens (17"up)</Details>
|
||||
@ -2505,22 +2506,6 @@
|
||||
</data>
|
||||
</default>
|
||||
</UAVObjectBrowser>
|
||||
<Uploader>
|
||||
<default>
|
||||
<configInfo>
|
||||
<locked>false</locked>
|
||||
<version>0.0.0</version>
|
||||
</configInfo>
|
||||
<data>
|
||||
<defaultDataBits>3</defaultDataBits>
|
||||
<defaultFlow>0</defaultFlow>
|
||||
<defaultParity>0</defaultParity>
|
||||
<defaultPort>/dev/ttyS0</defaultPort>
|
||||
<defaultSpeed>14</defaultSpeed>
|
||||
<defaultStopBits>0</defaultStopBits>
|
||||
</data>
|
||||
</default>
|
||||
</Uploader>
|
||||
<configInfo>
|
||||
<locked>false</locked>
|
||||
<version>1.2.0</version>
|
||||
@ -2645,27 +2630,18 @@
|
||||
</side0>
|
||||
<side1>
|
||||
<side0>
|
||||
<side0>
|
||||
<classId>LoggingGadget</classId>
|
||||
<type>uavGadget</type>
|
||||
</side0>
|
||||
<side1>
|
||||
<classId>GpsDisplayGadget</classId>
|
||||
<gadget>
|
||||
<activeConfiguration>Flight GPS</activeConfiguration>
|
||||
</gadget>
|
||||
<type>uavGadget</type>
|
||||
</side1>
|
||||
<splitterOrientation>2</splitterOrientation>
|
||||
<splitterSizes>@Variant(AAAACQAAAAIAAAACAAAAcAAAAAIAAAHo)</splitterSizes>
|
||||
<type>splitter</type>
|
||||
<classId>LoggingGadget</classId>
|
||||
<type>uavGadget</type>
|
||||
</side0>
|
||||
<side1>
|
||||
<classId>DebugGadget</classId>
|
||||
<classId>GpsDisplayGadget</classId>
|
||||
<gadget>
|
||||
<activeConfiguration>Flight GPS</activeConfiguration>
|
||||
</gadget>
|
||||
<type>uavGadget</type>
|
||||
</side1>
|
||||
<splitterOrientation>2</splitterOrientation>
|
||||
<splitterSizes>@Variant(AAAACQAAAAIAAAACAAAB3wAAAAIAAAEp)</splitterSizes>
|
||||
<splitterSizes>@Variant(AAAACQAAAAIAAAACAAAAVAAAAAIAAAGu)</splitterSizes>
|
||||
<type>splitter</type>
|
||||
</side1>
|
||||
<splitterOrientation>1</splitterOrientation>
|
||||
|
@ -1,11 +1,13 @@
|
||||
include(../../openpilotgcs.pri)
|
||||
include(../shared/qtsingleapplication/qtsingleapplication.pri)
|
||||
include(gcsversioninfo.pri)
|
||||
|
||||
TEMPLATE = app
|
||||
TARGET = $$GCS_APP_TARGET
|
||||
DESTDIR = $$GCS_APP_PATH
|
||||
QT += xml
|
||||
SOURCES += main.cpp
|
||||
SOURCES += main.cpp \
|
||||
gcssplashscreen.cpp
|
||||
include(../rpath.pri)
|
||||
include(../libs/utils/utils.pri)
|
||||
|
||||
@ -28,3 +30,9 @@ win32 {
|
||||
}
|
||||
|
||||
OTHER_FILES += openpilotgcs.rc
|
||||
|
||||
RESOURCES += \
|
||||
appresources.qrc
|
||||
|
||||
HEADERS += \
|
||||
gcssplashscreen.h
|
||||
|
5
ground/openpilotgcs/src/app/appresources.qrc
Normal file
5
ground/openpilotgcs/src/app/appresources.qrc
Normal file
@ -0,0 +1,5 @@
|
||||
<RCC>
|
||||
<qresource prefix="/app">
|
||||
<file>splash.png</file>
|
||||
</qresource>
|
||||
</RCC>
|
85
ground/openpilotgcs/src/app/gcssplashscreen.cpp
Normal file
85
ground/openpilotgcs/src/app/gcssplashscreen.cpp
Normal file
@ -0,0 +1,85 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
*
|
||||
* @file gcssplashscreen.cpp
|
||||
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2012.
|
||||
* @addtogroup [Group]
|
||||
* @{
|
||||
* @addtogroup GCSSplashScreen
|
||||
* @{
|
||||
* @brief [Brief]
|
||||
*****************************************************************************/
|
||||
/*
|
||||
* 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 "gcssplashscreen.h"
|
||||
#include <QDebug>
|
||||
|
||||
const QChar CopyrightSymbol(0x00a9);
|
||||
|
||||
GCSSplashScreen::GCSSplashScreen() :
|
||||
QSplashScreen(), m_pixmap(0), m_painter(0)
|
||||
{
|
||||
QString revision;
|
||||
QString year;
|
||||
#ifdef GCS_REVISION
|
||||
revision = GCS_REVISION;
|
||||
#else
|
||||
revision = tr("N/A");
|
||||
#endif
|
||||
|
||||
#ifdef GCS_YEAR
|
||||
year = GCS_YEAR;
|
||||
#else
|
||||
year = "2013";
|
||||
#endif
|
||||
|
||||
setWindowFlags(windowFlags());
|
||||
m_pixmap = new QPixmap(":/app/splash.png");
|
||||
|
||||
m_painter = new QPainter(m_pixmap);
|
||||
m_painter->setPen(Qt::lightGray);
|
||||
QFont font("Tahoma", 8);
|
||||
m_painter->setFont(font);
|
||||
m_painter->drawText(405, 170, QString(CopyrightSymbol) +
|
||||
QString(" 2010-") + year +
|
||||
QString(tr(" The OpenPilot Project - All Rights Reserved")));
|
||||
|
||||
m_painter->drawText(406, 173, 310, 100, Qt::TextWordWrap|Qt::AlignTop|Qt::AlignLeft,
|
||||
QString(tr("GCS Revision - ")) + revision);
|
||||
setPixmap(*m_pixmap);
|
||||
}
|
||||
|
||||
GCSSplashScreen::~GCSSplashScreen()
|
||||
{
|
||||
}
|
||||
|
||||
void GCSSplashScreen::drawMessageText(const QString &message)
|
||||
{
|
||||
QPixmap pix(*m_pixmap);
|
||||
QPainter progressPainter(&pix);
|
||||
progressPainter.setPen(Qt::lightGray);
|
||||
QFont font("Tahoma", 13);
|
||||
progressPainter.setFont(font);
|
||||
progressPainter.drawText(170, 385, message);
|
||||
setPixmap(pix);
|
||||
}
|
||||
|
||||
void GCSSplashScreen::showPluginLoadingProgress(ExtensionSystem::PluginSpec *pluginSpec)
|
||||
{
|
||||
QString message(tr("Loading ") + pluginSpec->name() + " plugin...");
|
||||
drawMessageText(message);
|
||||
}
|
@ -1,49 +1,56 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file waypointeditorgadgetfactory.h
|
||||
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2012.
|
||||
* @addtogroup Waypoint Editor GCS Plugins
|
||||
* @{
|
||||
* @addtogroup WaypointEditorGadgetPlugin Waypoint Editor Gadget Plugin
|
||||
* @{
|
||||
* @brief A gadget to edit a list of waypoints
|
||||
*****************************************************************************/
|
||||
/*
|
||||
* 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 WaypointEditorGADGETFACTORY_H_
|
||||
#define WaypointEditorGADGETFACTORY_H_
|
||||
|
||||
#include <coreplugin/iuavgadgetfactory.h>
|
||||
|
||||
namespace Core {
|
||||
class IUAVGadget;
|
||||
class IUAVGadgetFactory;
|
||||
}
|
||||
|
||||
using namespace Core;
|
||||
|
||||
class WaypointEditorGadgetFactory : public IUAVGadgetFactory
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
WaypointEditorGadgetFactory(QObject *parent = 0);
|
||||
~WaypointEditorGadgetFactory();
|
||||
|
||||
IUAVGadget *createGadget(QWidget *parent);
|
||||
};
|
||||
|
||||
#endif // WaypointEditorGADGETFACTORY_H_
|
||||
/**
|
||||
******************************************************************************
|
||||
*
|
||||
* @file gcssplashscreen.h
|
||||
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2012.
|
||||
* @addtogroup [Group]
|
||||
* @{
|
||||
* @addtogroup GCSSplashScreen
|
||||
* @{
|
||||
* @brief [Brief]
|
||||
*****************************************************************************/
|
||||
/*
|
||||
* 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 GCSSPLASHSCREEN_H
|
||||
#define GCSSPLASHSCREEN_H
|
||||
|
||||
#include <QSplashScreen>
|
||||
#include <QPixmap>
|
||||
#include <QPainter>
|
||||
#include <extensionsystem/pluginspec.h>
|
||||
|
||||
#include "../../../../build/ground/openpilotgcs/gcsversioninfo.h"
|
||||
|
||||
class GCSSplashScreen : public QSplashScreen
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit GCSSplashScreen();
|
||||
~GCSSplashScreen();
|
||||
|
||||
public slots:
|
||||
void showPluginLoadingProgress(ExtensionSystem::PluginSpec *pluginSpec);
|
||||
void showProgressMessage(const QString &message) { drawMessageText(message); }
|
||||
|
||||
private:
|
||||
QPixmap *m_pixmap;
|
||||
QPainter *m_painter;
|
||||
void drawMessageText(const QString &message);
|
||||
|
||||
};
|
||||
|
||||
#endif // GCSSPLASHSCREEN_H
|
@ -28,6 +28,7 @@
|
||||
|
||||
#include "qtsingleapplication.h"
|
||||
#include "utils/xmlconfig.h"
|
||||
#include "gcssplashscreen.h"
|
||||
|
||||
#include <extensionsystem/pluginmanager.h>
|
||||
#include <extensionsystem/pluginspec.h>
|
||||
@ -46,6 +47,8 @@
|
||||
#include <QtGui/QMessageBox>
|
||||
#include <QtGui/QApplication>
|
||||
#include <QtGui/QMainWindow>
|
||||
#include <QtGui/QSplashScreen>
|
||||
#include <QtGui/QPainter>
|
||||
|
||||
enum { OptionIndent = 4, DescriptionIndent = 24 };
|
||||
|
||||
@ -241,10 +244,17 @@ int main(int argc, char **argv)
|
||||
#ifdef Q_OS_LINUX
|
||||
QApplication::setAttribute(Qt::AA_X11InitThreads, true);
|
||||
#endif
|
||||
QApplication::setGraphicsSystem("raster");
|
||||
|
||||
//Set the default locale to EN, if this is not set the system locale will be used
|
||||
//and as of now we dont want that behaviour.
|
||||
QLocale::setDefault(QLocale::English);
|
||||
|
||||
SharedTools::QtSingleApplication app((QLatin1String(appNameC)), argc, argv);
|
||||
|
||||
//Open Splashscreen
|
||||
GCSSplashScreen splash;
|
||||
splash.show();
|
||||
|
||||
QString locale = QLocale::system().name();
|
||||
|
||||
// Must be done before any QSettings class is created
|
||||
@ -275,6 +285,8 @@ int main(int argc, char **argv)
|
||||
}
|
||||
app.setProperty("qtc_locale", locale); // Do we need this?
|
||||
|
||||
splash.showProgressMessage(QObject::tr("Application starting..."));
|
||||
|
||||
// Load
|
||||
ExtensionSystem::PluginManager pluginManager;
|
||||
pluginManager.setFileExtension(QLatin1String("pluginspec"));
|
||||
@ -314,7 +326,7 @@ int main(int argc, char **argv)
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!coreplugin) {
|
||||
if(!coreplugin){
|
||||
QString nativePaths = QDir::toNativeSeparators(pluginPaths.join(QLatin1String(",")));
|
||||
const QString reason = QCoreApplication::translate("Application", "Could not find 'Core.pluginspec' in %1").arg(nativePaths);
|
||||
displayError(msgCoreLoadFailure(reason));
|
||||
@ -342,11 +354,16 @@ int main(int argc, char **argv)
|
||||
if (!isFirstInstance && foundAppOptions.contains(QLatin1String(CLIENT_OPTION)))
|
||||
return sendArguments(app, pluginManager.arguments()) ? 0 : -1;
|
||||
|
||||
QObject::connect(&pluginManager, SIGNAL(pluginAboutToBeLoaded(ExtensionSystem::PluginSpec*)),
|
||||
&splash, SLOT(showPluginLoadingProgress(ExtensionSystem::PluginSpec*)));
|
||||
|
||||
pluginManager.loadPlugins();
|
||||
|
||||
if (coreplugin->hasError()) {
|
||||
displayError(msgCoreLoadFailure(coreplugin->errorString()));
|
||||
return 1;
|
||||
}
|
||||
|
||||
{
|
||||
QStringList errors;
|
||||
foreach (ExtensionSystem::PluginSpec *p, pluginManager.plugins())
|
||||
@ -369,5 +386,10 @@ int main(int argc, char **argv)
|
||||
|
||||
// Do this after the event loop has started
|
||||
QTimer::singleShot(100, &pluginManager, SLOT(startTests()));
|
||||
|
||||
//Update message and postpone closing of splashscreen 3 seconds
|
||||
splash.showProgressMessage(QObject::tr("Application started."));
|
||||
QTimer::singleShot(1500, &splash, SLOT(close()));
|
||||
|
||||
return app.exec();
|
||||
}
|
||||
|
BIN
ground/openpilotgcs/src/app/splash.png
Normal file
BIN
ground/openpilotgcs/src/app/splash.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 274 KiB |
@ -583,7 +583,9 @@ void PluginManagerPrivate::loadPlugins()
|
||||
QListIterator<PluginSpec *> it(queue);
|
||||
it.toBack();
|
||||
while (it.hasPrevious()) {
|
||||
loadPlugin(it.previous(), PluginSpec::Running);
|
||||
PluginSpec* plugin = it.previous();
|
||||
emit q->pluginAboutToBeLoaded(plugin);
|
||||
loadPlugin(plugin, PluginSpec::Running);
|
||||
}
|
||||
emit q->pluginsChanged();
|
||||
q->m_allPluginsLoaded=true;
|
||||
|
@ -114,6 +114,7 @@ signals:
|
||||
void objectAdded(QObject *obj);
|
||||
void aboutToRemoveObject(QObject *obj);
|
||||
|
||||
void pluginAboutToBeLoaded(ExtensionSystem::PluginSpec* pluginSpec);
|
||||
void pluginsChanged();
|
||||
void pluginsLoadEnded();
|
||||
private slots:
|
||||
|
@ -150,6 +150,7 @@ namespace mapcontrol
|
||||
QString uavoInfoStrLine3, uavoInfoStrLine4;
|
||||
QString uavoInfoStrLine5;
|
||||
|
||||
uavoInfoStrLine1.append(QString("CAS: %1 kph").arg(CAS_mps * 3.6));
|
||||
uavoInfoStrLine2.append(QString("Groundspeed: %1 kph").arg(groundspeed_kph, 0, 'f',1));
|
||||
uavoInfoStrLine3.append(QString("Lat-Lon: %1, %2").arg(coord.Lat(), 0, 'f',7).arg(coord.Lng(), 0, 'f',7));
|
||||
uavoInfoStrLine4.append(QString("North-East: %1 m, %2 m").arg(NED[0], 0, 'f',1).arg(NED[1], 0, 'f',1));
|
||||
|
@ -229,7 +229,6 @@ WayPointItem::WayPointItem(MapGraphicItem *map, bool magicwaypoint):reached(fals
|
||||
}
|
||||
void WayPointItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
|
||||
{
|
||||
QGraphicsItem::mouseReleaseEvent(event);
|
||||
if(event->button()==Qt::LeftButton)
|
||||
{
|
||||
if(text)
|
||||
@ -242,15 +241,14 @@ WayPointItem::WayPointItem(MapGraphicItem *map, bool magicwaypoint):reached(fals
|
||||
delete textBG;
|
||||
textBG=NULL;
|
||||
}
|
||||
coord=map->FromLocalToLatLng(this->pos().x(),this->pos().y());
|
||||
|
||||
isDragging=false;
|
||||
RefreshToolTip();
|
||||
emit manualCoordChange(this);
|
||||
emit localPositionChanged(this->pos(),this);
|
||||
emit WPValuesChanged(this);
|
||||
emit WPDropped(this);
|
||||
}
|
||||
QGraphicsItem::mouseReleaseEvent(event);
|
||||
}
|
||||
void WayPointItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
|
||||
{
|
||||
|
@ -234,13 +234,6 @@ signals:
|
||||
* @param waypoint a pointer to this WayPoint
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Fired when the waypoint is dropped somewhere
|
||||
*
|
||||
* @param waypoint a pointer to this WayPoint
|
||||
*/
|
||||
void WPDropped(WayPointItem* waypoint);
|
||||
|
||||
void WPValuesChanged(WayPointItem* waypoint);
|
||||
void waypointdoubleclick(WayPointItem* waypoint);
|
||||
void localPositionChanged(QPointF point,WayPointItem* waypoint);
|
||||
|
@ -1498,7 +1498,7 @@ font: bold 12px;
|
||||
margin:1px;</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Tricopter Yaw Motor channel</string>
|
||||
<string>Tricopter Yaw Servo channel</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
|
@ -51,9 +51,10 @@
|
||||
<string><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
|
||||
<html><head><meta name="qrichtext" content="1" /><style type="text/css">
|
||||
p, li { white-space: pre-wrap; }
|
||||
</style></head><body style=" font-family:'Ubuntu'; font-size:11pt; font-weight:400; font-style:normal;">
|
||||
</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:8.25pt; font-weight:400; font-style:normal;">
|
||||
<p align="center" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Lucida Grande'; font-size:20pt; font-weight:600; color:#ff0000;">WARNING:</span></p>
|
||||
<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Lucida Grande'; font-size:13pt;"><br /></p>
|
||||
<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Lucida Grande'; font-size:13pt;"></p>
|
||||
<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Lucida Grande'; font-size:13pt;"><br /></span></p>
|
||||
<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Lucida Grande'; font-size:13pt;"><br /></span></p>
|
||||
<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Lucida Grande'; font-size:13pt;">This is an experimental plugin for the GCS that is going to make your aircraft shake, etc, so test with lots of space and be </span><span style=" font-family:'Lucida Grande'; font-size:13pt; font-weight:600;">very very wary</span><span style=" font-family:'Lucida Grande'; font-size:13pt;"> for it creating bad tuning values. Basically there is no reason to think this will work at all.<br /><br />To use autotuning, here are the steps:<br /></span></p>
|
||||
<ul style="margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; -qt-list-indent: 1;"><li style=" font-family:'Lucida Grande'; font-size:13pt;" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">On the <span style=" font-style:italic;">Input configuration</span> tab, <span style=" font-style:italic;">Flight Mode Switch Settings</span>, set one of your flight modes to &quot;Autotune&quot;.<br /></li>
|
||||
@ -70,7 +71,7 @@ p, li { white-space: pre-wrap; }
|
||||
<property name="title">
|
||||
<string>Module Control</string>
|
||||
</property>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_3">
|
||||
<layout class="QVBoxLayout" name="verticalLayout_4">
|
||||
<item>
|
||||
<widget class="QCheckBox" name="enableAutoTune">
|
||||
<property name="text">
|
||||
@ -82,24 +83,13 @@ p, li { white-space: pre-wrap; }
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_5">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
<widget class="QLabel" name="label_13">
|
||||
<property name="text">
|
||||
<string>After enabling the module, you must power cycle before using and configuring.</string>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>454</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
<zorder>horizontalSpacer_5</zorder>
|
||||
<zorder>enableAutoTune</zorder>
|
||||
<zorder>horizontalSpacer_4</zorder>
|
||||
<zorder>enableAutoTune</zorder>
|
||||
<zorder>horizontalSpacer_5</zorder>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
@ -192,8 +182,8 @@ p, li { white-space: pre-wrap; }
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>711</width>
|
||||
<height>596</height>
|
||||
<width>709</width>
|
||||
<height>605</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
|
@ -7,7 +7,7 @@
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>786</width>
|
||||
<height>566</height>
|
||||
<height>791</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
@ -64,8 +64,8 @@
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>741</width>
|
||||
<height>559</height>
|
||||
<width>762</width>
|
||||
<height>658</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
@ -130,7 +130,7 @@
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>130</height>
|
||||
<height>110</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
@ -285,7 +285,7 @@ have to define channel output range using Output configuration tab.</string>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="label_43">
|
||||
<property name="text">
|
||||
<string>Output Range</string>
|
||||
<string>Output Range (Angle)</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
@ -390,7 +390,7 @@ margin:1px;</string>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>250</height>
|
||||
<height>187</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
@ -403,9 +403,6 @@ margin:1px;</string>
|
||||
<string>Advanced Settings (Control)</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_8">
|
||||
<property name="verticalSpacing">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<item row="0" column="3">
|
||||
<widget class="QLabel" name="label_32">
|
||||
<property name="minimumSize">
|
||||
@ -653,34 +650,6 @@ AxisLock: camera remembers tracking attitude. Input controls the rate of deflect
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="3">
|
||||
<widget class="QSpinBox" name="yawResponseTime">
|
||||
<property name="focusPolicy">
|
||||
<enum>Qt::StrongFocus</enum>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Input low-pass filter response time for yaw axis, ms.
|
||||
|
||||
This option smoothes the stick input. Zero value disables LPF.</string>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>1000</number>
|
||||
</property>
|
||||
<property name="value">
|
||||
<number>150</number>
|
||||
</property>
|
||||
<property name="objrelation" stdset="0">
|
||||
<stringlist>
|
||||
<string>objname:CameraStabSettings</string>
|
||||
<string>fieldname:ResponseTime</string>
|
||||
<string>element:Yaw</string>
|
||||
<string>haslimits:no</string>
|
||||
<string>scale:1</string>
|
||||
<string>buttongroup:1</string>
|
||||
</stringlist>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="2">
|
||||
<widget class="QComboBox" name="pitchStabilizationMode">
|
||||
<property name="focusPolicy">
|
||||
@ -759,34 +728,6 @@ AxisLock: camera remembers tracking attitude. Input controls the rate of deflect
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="2">
|
||||
<widget class="QSpinBox" name="pitchResponseTime">
|
||||
<property name="focusPolicy">
|
||||
<enum>Qt::StrongFocus</enum>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Input low-pass filter response time for pitch axis, ms.
|
||||
|
||||
This option smoothes the stick input. Zero value disables LPF.</string>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>1000</number>
|
||||
</property>
|
||||
<property name="value">
|
||||
<number>150</number>
|
||||
</property>
|
||||
<property name="objrelation" stdset="0">
|
||||
<stringlist>
|
||||
<string>objname:CameraStabSettings</string>
|
||||
<string>fieldname:ResponseTime</string>
|
||||
<string>element:Pitch</string>
|
||||
<string>haslimits:no</string>
|
||||
<string>scale:1</string>
|
||||
<string>buttongroup:1</string>
|
||||
</stringlist>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QComboBox" name="rollStabilizationMode">
|
||||
<property name="focusPolicy">
|
||||
@ -865,59 +806,24 @@ AxisLock: camera remembers tracking attitude. Input controls the rate of deflect
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="1">
|
||||
<widget class="QSpinBox" name="rollResponseTime">
|
||||
<property name="focusPolicy">
|
||||
<enum>Qt::StrongFocus</enum>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Input low-pass filter response time for roll axis, ms.
|
||||
|
||||
This option smoothes the stick input. Zero value disables LPF.</string>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>1000</number>
|
||||
</property>
|
||||
<property name="value">
|
||||
<number>150</number>
|
||||
</property>
|
||||
<property name="objrelation" stdset="0">
|
||||
<stringlist>
|
||||
<string>objname:CameraStabSettings</string>
|
||||
<string>fieldname:ResponseTime</string>
|
||||
<string>element:Roll</string>
|
||||
<string>haslimits:no</string>
|
||||
<string>scale:1</string>
|
||||
<string>buttongroup:1</string>
|
||||
</stringlist>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" column="0">
|
||||
<item row="5" column="0">
|
||||
<widget class="QLabel" name="label_36">
|
||||
<property name="text">
|
||||
<string>MaxAxisLockRate</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="0">
|
||||
<widget class="QLabel" name="label_37">
|
||||
<property name="text">
|
||||
<string>Response Time</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="0">
|
||||
<widget class="QLabel" name="label_38">
|
||||
<property name="text">
|
||||
<string>Input Rate</string>
|
||||
<string>Input Rate (Speed)</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="QLabel" name="label_39">
|
||||
<property name="text">
|
||||
<string>Input Range</string>
|
||||
<string>Input Range (Angle)</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
@ -928,14 +834,14 @@ This option smoothes the stick input. Zero value disables LPF.</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" column="2" colspan="2">
|
||||
<item row="5" column="2" colspan="2">
|
||||
<widget class="QLabel" name="label_41">
|
||||
<property name="text">
|
||||
<string>(the same value for Roll, Pitch, Yaw)</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" column="1">
|
||||
<item row="5" column="1">
|
||||
<widget class="QDoubleSpinBox" name="MaxAxisLockRate">
|
||||
<property name="focusPolicy">
|
||||
<enum>Qt::StrongFocus</enum>
|
||||
@ -974,30 +880,471 @@ value.</string>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="groupBox_4">
|
||||
<widget class="QGroupBox" name="groupBox_3">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>71</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>16777215</width>
|
||||
<height>16777215</height>
|
||||
<height>187</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="title">
|
||||
<string>Messages</string>
|
||||
<string>Expert Settings (Attitude Filter and Feed Forward)</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_3">
|
||||
<item>
|
||||
<widget class="QLabel" name="message">
|
||||
<property name="autoFillBackground">
|
||||
<bool>false</bool>
|
||||
<layout class="QGridLayout" name="gridLayout_2">
|
||||
<item row="0" column="1">
|
||||
<widget class="QLabel" name="label_49">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>16</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>16777215</width>
|
||||
<height>16</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true">background-color: qlineargradient(spread:reflect, x1:0.507, y1:0, x2:0.507, y2:0.772, stop:0.208955 rgba(74, 74, 74, 255), stop:0.78607 rgba(36, 36, 36, 255));
|
||||
color: rgb(255, 255, 255);
|
||||
border-radius: 5;
|
||||
font: bold 12px;
|
||||
margin:1px;</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
<string>Roll</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="2">
|
||||
<widget class="QLabel" name="label_50">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>16</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>16777215</width>
|
||||
<height>16</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true">background-color: qlineargradient(spread:reflect, x1:0.507, y1:0, x2:0.507, y2:0.772, stop:0.208955 rgba(74, 74, 74, 255), stop:0.78607 rgba(36, 36, 36, 255));
|
||||
color: rgb(255, 255, 255);
|
||||
border-radius: 5;
|
||||
font: bold 12px;
|
||||
margin:1px;</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Pitch</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="3">
|
||||
<widget class="QLabel" name="label_51">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>16</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>16777215</width>
|
||||
<height>16</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true">background-color: qlineargradient(spread:reflect, x1:0.507, y1:0, x2:0.507, y2:0.772, stop:0.208955 rgba(74, 74, 74, 255), stop:0.78607 rgba(36, 36, 36, 255));
|
||||
color: rgb(255, 255, 255);
|
||||
border-radius: 5;
|
||||
font: bold 12px;
|
||||
margin:1px;</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Yaw</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="label_2">
|
||||
<property name="text">
|
||||
<string>Attitude Filter RT</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QSpinBox" name="rollResponseTime">
|
||||
<property name="toolTip">
|
||||
<string>Roll axis attitude filter response time
|
||||
|
||||
Range: 0-250ms, 0 disables the filter (default).
|
||||
|
||||
Smoothes estimated airframe attitude used by camera stabilization.</string>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>250</number>
|
||||
</property>
|
||||
<property name="objrelation" stdset="0">
|
||||
<stringlist>
|
||||
<string>objname:CameraStabSettings</string>
|
||||
<string>fieldname:ResponseTime</string>
|
||||
<string>element:Roll</string>
|
||||
<string>buttongroup:1</string>
|
||||
</stringlist>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="2">
|
||||
<widget class="QSpinBox" name="pitchResponseTime">
|
||||
<property name="toolTip">
|
||||
<string>Pitch axis attitude filter response time
|
||||
|
||||
Range: 0-250ms, 0 disables the filter (default).
|
||||
|
||||
Smoothes estimated airframe attitude used by camera stabilization.</string>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>250</number>
|
||||
</property>
|
||||
<property name="objrelation" stdset="0">
|
||||
<stringlist>
|
||||
<string>objname:CameraStabSettings</string>
|
||||
<string>fieldname:ResponseTime</string>
|
||||
<string>element:Pitch</string>
|
||||
<string>buttongroup:1</string>
|
||||
</stringlist>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="3">
|
||||
<widget class="QSpinBox" name="yawResponseTime">
|
||||
<property name="toolTip">
|
||||
<string>Yaw axis attitude filter response time
|
||||
|
||||
Range: 0-250ms, 0 disables the filter (default).
|
||||
|
||||
Smoothes estimated airframe attitude used by camera stabilization.</string>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>250</number>
|
||||
</property>
|
||||
<property name="objrelation" stdset="0">
|
||||
<stringlist>
|
||||
<string>objname:CameraStabSettings</string>
|
||||
<string>fieldname:ResponseTime</string>
|
||||
<string>element:Yaw</string>
|
||||
<string>buttongroup:1</string>
|
||||
</stringlist>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="label_4">
|
||||
<property name="text">
|
||||
<string>FF Servo Acceleration</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QSpinBox" name="rollFeedForward">
|
||||
<property name="toolTip">
|
||||
<string>Roll servo feed forward acceleration
|
||||
|
||||
Range: 0-25, 0 disables feed forward for the axis (default).
|
||||
|
||||
Good starting value is 2-7.
|
||||
Too high value may burn your servo!</string>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>25</number>
|
||||
</property>
|
||||
<property name="objrelation" stdset="0">
|
||||
<stringlist>
|
||||
<string>objname:CameraStabSettings</string>
|
||||
<string>fieldname:FeedForward</string>
|
||||
<string>element:Roll</string>
|
||||
<string>haslimits:no</string>
|
||||
<string>scale:1</string>
|
||||
<string>buttongroup:1</string>
|
||||
</stringlist>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="2">
|
||||
<widget class="QSpinBox" name="pitchFeedForward">
|
||||
<property name="toolTip">
|
||||
<string>Pitch servo feed forward acceleration
|
||||
|
||||
Range: 0-25, 0 disables feed forward for the axis (default).
|
||||
|
||||
Good starting value is 2-7.
|
||||
Too high value may burn your servo!</string>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>25</number>
|
||||
</property>
|
||||
<property name="objrelation" stdset="0">
|
||||
<stringlist>
|
||||
<string>objname:CameraStabSettings</string>
|
||||
<string>fieldname:FeedForward</string>
|
||||
<string>element:Pitch</string>
|
||||
<string>haslimits:no</string>
|
||||
<string>scale:1</string>
|
||||
<string>buttongroup:1</string>
|
||||
</stringlist>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="3">
|
||||
<widget class="QSpinBox" name="yawFeedForward">
|
||||
<property name="toolTip">
|
||||
<string>Yaw servo feed forward acceleration
|
||||
|
||||
Range: 0-25, 0 disables feed forward for the axis (default).
|
||||
|
||||
Good starting value is 2-7.
|
||||
Too high value may burn your servo!</string>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>25</number>
|
||||
</property>
|
||||
<property name="objrelation" stdset="0">
|
||||
<stringlist>
|
||||
<string>objname:CameraStabSettings</string>
|
||||
<string>fieldname:FeedForward</string>
|
||||
<string>element:Yaw</string>
|
||||
<string>haslimits:no</string>
|
||||
<string>scale:1</string>
|
||||
<string>buttongroup:1</string>
|
||||
</stringlist>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="QLabel" name="label_48">
|
||||
<property name="text">
|
||||
<string>FF Accel Time Constant</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="1">
|
||||
<widget class="QSpinBox" name="rollAccelTime">
|
||||
<property name="toolTip">
|
||||
<string>Roll servo feed forward acceleration time constant
|
||||
|
||||
Range: 0-50ms, default is 5.</string>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>50</number>
|
||||
</property>
|
||||
<property name="value">
|
||||
<number>5</number>
|
||||
</property>
|
||||
<property name="objrelation" stdset="0">
|
||||
<stringlist>
|
||||
<string>objname:CameraStabSettings</string>
|
||||
<string>fieldname:AccelTime</string>
|
||||
<string>element:Roll</string>
|
||||
<string>buttongroup:1</string>
|
||||
</stringlist>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="2">
|
||||
<widget class="QSpinBox" name="pitchAccelTime">
|
||||
<property name="toolTip">
|
||||
<string>Pitch servo feed forward acceleration time constant
|
||||
|
||||
Range: 0-50ms, default is 5.</string>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>50</number>
|
||||
</property>
|
||||
<property name="value">
|
||||
<number>5</number>
|
||||
</property>
|
||||
<property name="objrelation" stdset="0">
|
||||
<stringlist>
|
||||
<string>objname:CameraStabSettings</string>
|
||||
<string>fieldname:AccelTime</string>
|
||||
<string>element:Pitch</string>
|
||||
<string>buttongroup:1</string>
|
||||
</stringlist>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="3">
|
||||
<widget class="QSpinBox" name="yawAccelTime">
|
||||
<property name="toolTip">
|
||||
<string>Yaw servo feed forward acceleration time constant
|
||||
|
||||
Range: 0-50ms, default is 5.</string>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>50</number>
|
||||
</property>
|
||||
<property name="value">
|
||||
<number>5</number>
|
||||
</property>
|
||||
<property name="objrelation" stdset="0">
|
||||
<stringlist>
|
||||
<string>objname:CameraStabSettings</string>
|
||||
<string>fieldname:AccelTime</string>
|
||||
<string>element:Yaw</string>
|
||||
<string>buttongroup:1</string>
|
||||
</stringlist>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="0">
|
||||
<widget class="QLabel" name="label_5">
|
||||
<property name="text">
|
||||
<string>FF Decel Time Constant</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="1">
|
||||
<widget class="QSpinBox" name="rollDecelTime">
|
||||
<property name="toolTip">
|
||||
<string>Roll servo feed forward deceleration time constant
|
||||
|
||||
Range: 0-50ms, default is 5.</string>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>50</number>
|
||||
</property>
|
||||
<property name="value">
|
||||
<number>5</number>
|
||||
</property>
|
||||
<property name="objrelation" stdset="0">
|
||||
<stringlist>
|
||||
<string>objname:CameraStabSettings</string>
|
||||
<string>fieldname:DecelTime</string>
|
||||
<string>element:Roll</string>
|
||||
<string>buttongroup:1</string>
|
||||
</stringlist>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="2">
|
||||
<widget class="QSpinBox" name="pitchDecelTime">
|
||||
<property name="toolTip">
|
||||
<string>Pitch servo feed forward deceleration time constant
|
||||
|
||||
Range: 0-50ms, default is 5.</string>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>50</number>
|
||||
</property>
|
||||
<property name="value">
|
||||
<number>5</number>
|
||||
</property>
|
||||
<property name="objrelation" stdset="0">
|
||||
<stringlist>
|
||||
<string>objname:CameraStabSettings</string>
|
||||
<string>fieldname:DecelTime</string>
|
||||
<string>element:Pitch</string>
|
||||
<string>buttongroup:1</string>
|
||||
</stringlist>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="3">
|
||||
<widget class="QSpinBox" name="yawDecelTime">
|
||||
<property name="toolTip">
|
||||
<string>Yaw servo feed forward deceleration time constant
|
||||
|
||||
Range: 0-50ms, default is 5.</string>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>50</number>
|
||||
</property>
|
||||
<property name="value">
|
||||
<number>5</number>
|
||||
</property>
|
||||
<property name="objrelation" stdset="0">
|
||||
<stringlist>
|
||||
<string>objname:CameraStabSettings</string>
|
||||
<string>fieldname:DecelTime</string>
|
||||
<string>element:Yaw</string>
|
||||
<string>buttongroup:1</string>
|
||||
</stringlist>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="0">
|
||||
<widget class="QLabel" name="label_47">
|
||||
<property name="text">
|
||||
<string>Gimbal Type:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="1">
|
||||
<widget class="QComboBox" name="gimbalType">
|
||||
<property name="focusPolicy">
|
||||
<enum>Qt::StrongFocus</enum>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Gimbal type
|
||||
|
||||
Used to limit feed forward acceleration at extreme angles.
|
||||
Generic type provides no limit.</string>
|
||||
</property>
|
||||
<property name="objrelation" stdset="0">
|
||||
<stringlist>
|
||||
<string>objname:CameraStabSettings</string>
|
||||
<string>fieldname:GimbalType</string>
|
||||
<string>buttongroup:1</string>
|
||||
</stringlist>
|
||||
</property>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Yaw-Roll-Pitch</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="2">
|
||||
<widget class="QLabel" name="label_6">
|
||||
<property name="text">
|
||||
<string>FF Max Acceleration</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="3">
|
||||
<widget class="QSpinBox" name="maxAccel">
|
||||
<property name="toolTip">
|
||||
<string>Feed forward maximum acceleration
|
||||
|
||||
Range: 0-1000, default is 500.
|
||||
|
||||
The same value is used for all axes.</string>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>1000</number>
|
||||
</property>
|
||||
<property name="value">
|
||||
<number>500</number>
|
||||
</property>
|
||||
<property name="objrelation" stdset="0">
|
||||
<stringlist>
|
||||
<string>objname:CameraStabSettings</string>
|
||||
<string>fieldname:MaxAccel</string>
|
||||
<string>buttongroup:1</string>
|
||||
</stringlist>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
@ -1005,13 +1352,17 @@ value.</string>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="verticalSpacer_2">
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string>Input configuration also provides smoothing for controls. Look for RT options on the RC Input tab.</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="verticalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeType">
|
||||
<enum>QSizePolicy::Expanding</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
@ -1028,6 +1379,37 @@ value.</string>
|
||||
</widget>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="groupBox_4">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>50</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>16777215</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="title">
|
||||
<string>Messages</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_3">
|
||||
<item>
|
||||
<widget class="QLabel" name="message">
|
||||
<property name="autoFillBackground">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<property name="horizontalSpacing">
|
||||
@ -1221,7 +1603,44 @@ Apply or Save button afterwards.</string>
|
||||
</layout>
|
||||
</widget>
|
||||
<tabstops>
|
||||
<tabstop>scrollArea</tabstop>
|
||||
<tabstop>enableCameraStabilization</tabstop>
|
||||
<tabstop>rollChannel</tabstop>
|
||||
<tabstop>pitchChannel</tabstop>
|
||||
<tabstop>yawChannel</tabstop>
|
||||
<tabstop>rollOutputRange</tabstop>
|
||||
<tabstop>pitchOutputRange</tabstop>
|
||||
<tabstop>yawOutputRange</tabstop>
|
||||
<tabstop>rollInputChannel</tabstop>
|
||||
<tabstop>pitchInputChannel</tabstop>
|
||||
<tabstop>yawInputChannel</tabstop>
|
||||
<tabstop>rollStabilizationMode</tabstop>
|
||||
<tabstop>pitchStabilizationMode</tabstop>
|
||||
<tabstop>yawStabilizationMode</tabstop>
|
||||
<tabstop>rollInputRange</tabstop>
|
||||
<tabstop>pitchInputRange</tabstop>
|
||||
<tabstop>yawInputRange</tabstop>
|
||||
<tabstop>rollInputRate</tabstop>
|
||||
<tabstop>pitchInputRate</tabstop>
|
||||
<tabstop>yawInputRate</tabstop>
|
||||
<tabstop>MaxAxisLockRate</tabstop>
|
||||
<tabstop>rollResponseTime</tabstop>
|
||||
<tabstop>pitchResponseTime</tabstop>
|
||||
<tabstop>yawResponseTime</tabstop>
|
||||
<tabstop>rollFeedForward</tabstop>
|
||||
<tabstop>pitchFeedForward</tabstop>
|
||||
<tabstop>yawFeedForward</tabstop>
|
||||
<tabstop>rollAccelTime</tabstop>
|
||||
<tabstop>pitchAccelTime</tabstop>
|
||||
<tabstop>yawAccelTime</tabstop>
|
||||
<tabstop>rollDecelTime</tabstop>
|
||||
<tabstop>pitchDecelTime</tabstop>
|
||||
<tabstop>yawDecelTime</tabstop>
|
||||
<tabstop>gimbalType</tabstop>
|
||||
<tabstop>maxAccel</tabstop>
|
||||
<tabstop>camerastabilizationResetToDefaults</tabstop>
|
||||
<tabstop>pushButton</tabstop>
|
||||
<tabstop>camerastabilizationSaveRAM</tabstop>
|
||||
<tabstop>camerastabilizationSaveSD</tabstop>
|
||||
</tabstops>
|
||||
<resources>
|
||||
<include location="../coreplugin/core.qrc"/>
|
||||
|
@ -111,7 +111,7 @@
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>750</width>
|
||||
<height>466</height>
|
||||
<height>483</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
@ -391,6 +391,86 @@ arming it in that case!</string>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_4">
|
||||
<item>
|
||||
<widget class="QLabel" name="label_5">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>AccelTau</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_12">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeType">
|
||||
<enum>QSizePolicy::Fixed</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>10</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QDoubleSpinBox" name="accelTauSpinbox">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>60</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Accelerometer filtering.
|
||||
|
||||
Sets the amount of lowpass filtering of accelerometer data
|
||||
for the attitude estimation. Higher values apply a stronger
|
||||
filter, which may help with drifting in attitude mode.
|
||||
|
||||
Range: 0.00 - 0.20, Good starting value: 0.05 - 0.10
|
||||
Start low and raise until drift stops.
|
||||
|
||||
A setting of 0.00 disables the filter.</string>
|
||||
</property>
|
||||
<property name="decimals">
|
||||
<number>2</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<double>0.200000000000000</double>
|
||||
</property>
|
||||
<property name="singleStep">
|
||||
<double>0.010000000000000</double>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_11">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
|
@ -281,6 +281,7 @@ bool ConfigFixedWingWidget::setupFrameFixedWing(QString airframeType)
|
||||
|
||||
UAVDataObject* mixer = dynamic_cast<UAVDataObject*>(getObjectManager()->getObject(QString("MixerSettings")));
|
||||
Q_ASSERT(mixer);
|
||||
resetMotorAndServoMixers(mixer);
|
||||
|
||||
// ... and compute the matrix:
|
||||
// In order to make code a bit nicer, we assume:
|
||||
@ -288,16 +289,8 @@ bool ConfigFixedWingWidget::setupFrameFixedWing(QString airframeType)
|
||||
|
||||
// 1. Assign the servo/motor/none for each channel
|
||||
|
||||
int channel;
|
||||
//disable all
|
||||
for (channel=0; (unsigned int) channel < VehicleConfig::CHANNEL_NUMELEM; channel++)
|
||||
{
|
||||
setMixerType(mixer,channel,VehicleConfig::MIXERTYPE_DISABLED);
|
||||
resetMixerVector(mixer, channel);
|
||||
}
|
||||
|
||||
//motor
|
||||
channel = m_aircraft->fwEngineChannelBox->currentIndex()-1;
|
||||
int channel = m_aircraft->fwEngineChannelBox->currentIndex()-1;
|
||||
setMixerType(mixer,channel,VehicleConfig::MIXERTYPE_MOTOR);
|
||||
setMixerVectorValue(mixer,channel,VehicleConfig::MIXERVECTOR_THROTTLECURVE1, 127);
|
||||
|
||||
@ -359,6 +352,7 @@ bool ConfigFixedWingWidget::setupFrameElevon(QString airframeType)
|
||||
|
||||
UAVDataObject* mixer = dynamic_cast<UAVDataObject*>(getObjectManager()->getObject(QString("MixerSettings")));
|
||||
Q_ASSERT(mixer);
|
||||
resetMotorAndServoMixers(mixer);
|
||||
|
||||
// Save the curve:
|
||||
// ... and compute the matrix:
|
||||
@ -367,17 +361,10 @@ bool ConfigFixedWingWidget::setupFrameElevon(QString airframeType)
|
||||
|
||||
// 1. Assign the servo/motor/none for each channel
|
||||
|
||||
int channel;
|
||||
double value;
|
||||
//disable all
|
||||
for (channel=0; (unsigned int) channel < VehicleConfig::CHANNEL_NUMELEM; channel++)
|
||||
{
|
||||
setMixerType(mixer,channel,VehicleConfig::MIXERTYPE_DISABLED);
|
||||
resetMixerVector(mixer, channel);
|
||||
}
|
||||
|
||||
//motor
|
||||
channel = m_aircraft->fwEngineChannelBox->currentIndex()-1;
|
||||
int channel = m_aircraft->fwEngineChannelBox->currentIndex()-1;
|
||||
setMixerType(mixer,channel,VehicleConfig::MIXERTYPE_MOTOR);
|
||||
setMixerVectorValue(mixer,channel,VehicleConfig::MIXERVECTOR_THROTTLECURVE1, 127);
|
||||
|
||||
@ -437,6 +424,7 @@ bool ConfigFixedWingWidget::setupFrameVtail(QString airframeType)
|
||||
|
||||
UAVDataObject* mixer = dynamic_cast<UAVDataObject*>(getObjectManager()->getObject(QString("MixerSettings")));
|
||||
Q_ASSERT(mixer);
|
||||
resetMotorAndServoMixers(mixer);
|
||||
|
||||
// Save the curve:
|
||||
// ... and compute the matrix:
|
||||
@ -445,17 +433,10 @@ bool ConfigFixedWingWidget::setupFrameVtail(QString airframeType)
|
||||
|
||||
// 1. Assign the servo/motor/none for each channel
|
||||
|
||||
int channel;
|
||||
double value;
|
||||
//disable all
|
||||
for (channel=0; (unsigned int) channel < VehicleConfig::CHANNEL_NUMELEM; channel++)
|
||||
{
|
||||
setMixerType(mixer,channel,VehicleConfig::MIXERTYPE_DISABLED);
|
||||
resetMixerVector(mixer, channel);
|
||||
}
|
||||
|
||||
//motor
|
||||
channel = m_aircraft->fwEngineChannelBox->currentIndex()-1;
|
||||
int channel = m_aircraft->fwEngineChannelBox->currentIndex()-1;
|
||||
setMixerType(mixer,channel,VehicleConfig::MIXERTYPE_MOTOR);
|
||||
setMixerVectorValue(mixer,channel,VehicleConfig::MIXERVECTOR_THROTTLECURVE1, 127);
|
||||
|
||||
|
@ -295,16 +295,10 @@ bool ConfigGroundVehicleWidget::setupGroundVehicleMotorcycle(QString airframeTyp
|
||||
|
||||
UAVDataObject* mixer = dynamic_cast<UAVDataObject*>(getObjectManager()->getObject(QString("MixerSettings")));
|
||||
Q_ASSERT(mixer);
|
||||
|
||||
int channel;
|
||||
//disable all
|
||||
for (channel=0; (unsigned int) channel < VehicleConfig::CHANNEL_NUMELEM; channel++) {
|
||||
setMixerType(mixer,channel,VehicleConfig::MIXERTYPE_DISABLED);
|
||||
resetMixerVector(mixer, channel);
|
||||
}
|
||||
resetMotorAndServoMixers(mixer);
|
||||
|
||||
//motor
|
||||
channel = m_aircraft->gvMotor2ChannelBox->currentIndex()-1;
|
||||
int channel = m_aircraft->gvMotor2ChannelBox->currentIndex()-1;
|
||||
setMixerType(mixer, channel, VehicleConfig::MIXERTYPE_SERVO);
|
||||
setMixerVectorValue(mixer, channel, VehicleConfig::MIXERVECTOR_THROTTLECURVE1, 127);
|
||||
setMixerVectorValue(mixer, channel, VehicleConfig::MIXERVECTOR_YAW, 127);
|
||||
@ -352,16 +346,10 @@ bool ConfigGroundVehicleWidget::setupGroundVehicleDifferential(QString airframeT
|
||||
|
||||
UAVDataObject* mixer = dynamic_cast<UAVDataObject*>(getObjectManager()->getObject(QString("MixerSettings")));
|
||||
Q_ASSERT(mixer);
|
||||
|
||||
int channel;
|
||||
//disable all
|
||||
for (channel=0; (unsigned int) channel < VehicleConfig::CHANNEL_NUMELEM; channel++) {
|
||||
setMixerType(mixer,channel,VehicleConfig::MIXERTYPE_DISABLED);
|
||||
resetMixerVector(mixer, channel);
|
||||
}
|
||||
resetMotorAndServoMixers(mixer);
|
||||
|
||||
//left motor
|
||||
channel = m_aircraft->gvMotor1ChannelBox->currentIndex()-1;
|
||||
int channel = m_aircraft->gvMotor1ChannelBox->currentIndex()-1;
|
||||
setMixerType(mixer, channel, VehicleConfig::MIXERTYPE_SERVO);
|
||||
setMixerVectorValue(mixer, channel, VehicleConfig::MIXERVECTOR_THROTTLECURVE1, 127);
|
||||
setMixerVectorValue(mixer, channel, VehicleConfig::MIXERVECTOR_YAW, 127);
|
||||
@ -407,15 +395,9 @@ bool ConfigGroundVehicleWidget::setupGroundVehicleCar(QString airframeType)
|
||||
|
||||
UAVDataObject* mixer = dynamic_cast<UAVDataObject*>(getObjectManager()->getObject(QString("MixerSettings")));
|
||||
Q_ASSERT(mixer);
|
||||
resetMotorAndServoMixers(mixer);
|
||||
|
||||
int channel;
|
||||
//disable all
|
||||
for (channel=0; (unsigned int) channel < VehicleConfig::CHANNEL_NUMELEM; channel++) {
|
||||
setMixerType(mixer,channel,VehicleConfig::MIXERTYPE_DISABLED);
|
||||
resetMixerVector(mixer, channel);
|
||||
}
|
||||
|
||||
channel = m_aircraft->gvSteering1ChannelBox->currentIndex()-1;
|
||||
int channel = m_aircraft->gvSteering1ChannelBox->currentIndex()-1;
|
||||
setMixerType(mixer,channel, VehicleConfig::MIXERTYPE_SERVO);
|
||||
setMixerVectorValue(mixer, channel, VehicleConfig::MIXERVECTOR_YAW, 127);
|
||||
|
||||
|
@ -1032,13 +1032,7 @@ bool ConfigMultiRotorWidget::setupMultiRotorMixer(double mixerFactors[8][3])
|
||||
|
||||
UAVDataObject* mixer = dynamic_cast<UAVDataObject*>(getObjectManager()->getObject(QString("MixerSettings")));
|
||||
Q_ASSERT(mixer);
|
||||
|
||||
//disable all
|
||||
for (int channel=0; channel<(int)VehicleConfig::CHANNEL_NUMELEM; channel++)
|
||||
{
|
||||
setMixerType(mixer,channel,VehicleConfig::MIXERTYPE_DISABLED);
|
||||
resetMixerVector(mixer, channel);
|
||||
}
|
||||
resetMotorAndServoMixers(mixer);
|
||||
|
||||
// and enable only the relevant channels:
|
||||
double pFactor = (double)m_aircraft->mrPitchMixLevel->value()/100;
|
||||
|
@ -181,6 +181,18 @@ void VehicleConfig::resetMixerVector(UAVDataObject* mixer, int channel)
|
||||
}
|
||||
}
|
||||
|
||||
// Disable all servo/motor mixers (but keep camera and accessory ones)
|
||||
void VehicleConfig::resetMotorAndServoMixers(UAVDataObject *mixer)
|
||||
{
|
||||
for (int channel = 0; channel < (int)VehicleConfig::CHANNEL_NUMELEM; channel++) {
|
||||
QString type = getMixerType(mixer, channel);
|
||||
if ((type == "Disabled") || (type == "Motor") || (type == "Servo")) {
|
||||
setMixerType(mixer, channel, VehicleConfig::MIXERTYPE_DISABLED);
|
||||
resetMixerVector(mixer, channel);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
double VehicleConfig::getMixerVectorValue(UAVDataObject* mixer, int channel, MixerVectorElem elementName)
|
||||
{
|
||||
Q_ASSERT(mixer);
|
||||
|
@ -127,6 +127,7 @@ class VehicleConfig: public ConfigTaskWidget
|
||||
double getMixerVectorValue(UAVDataObject* mixer, int channel, MixerVectorElem elementName);
|
||||
void setMixerVectorValue(UAVDataObject* mixer, int channel, MixerVectorElem elementName, double value);
|
||||
void resetMixerVector(UAVDataObject* mixer, int channel);
|
||||
void resetMotorAndServoMixers(UAVDataObject* mixer);
|
||||
QString getMixerType(UAVDataObject* mixer, int channel);
|
||||
void setMixerType(UAVDataObject* mixer, int channel, MixerTypeElem mixerType);
|
||||
double getMixerValue(UAVDataObject* mixer, QString elementName);
|
||||
|
@ -56,7 +56,9 @@ ConfigCCAttitudeWidget::ConfigCCAttitudeWidget(QWidget *parent) :
|
||||
|
||||
// Connect the help button
|
||||
connect(ui->ccAttitudeHelp, SIGNAL(clicked()), this, SLOT(openHelp()));
|
||||
|
||||
addUAVObjectToWidgetRelation("AttitudeSettings","ZeroDuringArming",ui->zeroGyroBiasOnArming);
|
||||
addUAVObjectToWidgetRelation("AttitudeSettings", "AccelTau", ui->accelTauSpinbox);
|
||||
|
||||
addUAVObjectToWidgetRelation("AttitudeSettings","BoardRotation",ui->rollBias,AttitudeSettings::BOARDROTATION_ROLL);
|
||||
addUAVObjectToWidgetRelation("AttitudeSettings","BoardRotation",ui->pitchBias,AttitudeSettings::BOARDROTATION_PITCH);
|
||||
@ -73,8 +75,8 @@ ConfigCCAttitudeWidget::~ConfigCCAttitudeWidget()
|
||||
void ConfigCCAttitudeWidget::sensorsUpdated(UAVObject * obj) {
|
||||
|
||||
if (!timer.isActive()) {
|
||||
// ignore updates that come in after the timer has expired
|
||||
return;
|
||||
// ignore updates that come in after the timer has expired
|
||||
return;
|
||||
}
|
||||
|
||||
Accels * accels = Accels::GetInstance(getObjectManager());
|
||||
@ -207,16 +209,27 @@ void ConfigCCAttitudeWidget::openHelp()
|
||||
QDesktopServices::openUrl( QUrl("http://wiki.openpilot.org/x/44Cf", QUrl::StrictMode) );
|
||||
}
|
||||
|
||||
void ConfigCCAttitudeWidget::setAccelFiltering(bool active)
|
||||
{
|
||||
setDirty(true);
|
||||
}
|
||||
|
||||
void ConfigCCAttitudeWidget::enableControls(bool enable)
|
||||
{
|
||||
if(ui->zeroBias)
|
||||
if(ui->zeroBias) {
|
||||
ui->zeroBias->setEnabled(enable);
|
||||
}
|
||||
if(ui->zeroGyroBiasOnArming) {
|
||||
ui->zeroGyroBiasOnArming->setEnabled(enable);
|
||||
}
|
||||
if(ui->accelTauSpinbox) {
|
||||
ui->accelTauSpinbox->setEnabled(enable);
|
||||
}
|
||||
ConfigTaskWidget::enableControls(enable);
|
||||
}
|
||||
|
||||
void ConfigCCAttitudeWidget::updateObjectsFromWidgets()
|
||||
{
|
||||
ConfigTaskWidget::updateObjectsFromWidgets();
|
||||
|
||||
ui->zeroBiasProgress->setValue(0);
|
||||
}
|
||||
|
@ -52,6 +52,7 @@ private slots:
|
||||
void timeout();
|
||||
void startAccelCalibration();
|
||||
void openHelp();
|
||||
void setAccelFiltering(bool active);
|
||||
|
||||
private:
|
||||
Ui_ccattitude *ui;
|
||||
@ -65,6 +66,7 @@ private:
|
||||
QList<double> x_accum, y_accum, z_accum;
|
||||
QList<double> x_gyro_accum, y_gyro_accum, z_gyro_accum;
|
||||
|
||||
static const float DEFAULT_ENABLED_ACCEL_TAU = 0.1;
|
||||
static const int NUM_SENSOR_UPDATES = 300;
|
||||
static const float ACCEL_SCALE = 0.004f * 9.81f;
|
||||
protected:
|
||||
|
@ -140,17 +140,17 @@ ConfigGadgetWidget::ConfigGadgetWidget(QWidget *parent) : QWidget(parent)
|
||||
|
||||
// Connect to the PipXStatus object updates
|
||||
UAVObjectManager *objManager = pm->getObject<UAVObjectManager>();
|
||||
pipxStatusObj = dynamic_cast<UAVDataObject*>(objManager->getObject("PipXStatus"));
|
||||
if (pipxStatusObj != NULL ) {
|
||||
connect(pipxStatusObj, SIGNAL(objectUpdated(UAVObject*)), this, SLOT(updatePipXStatus(UAVObject*)));
|
||||
oplinkStatusObj = dynamic_cast<UAVDataObject*>(objManager->getObject("OPLinkStatus"));
|
||||
if (oplinkStatusObj != NULL ) {
|
||||
connect(oplinkStatusObj, SIGNAL(objectUpdated(UAVObject*)), this, SLOT(updateOPLinkStatus(UAVObject*)));
|
||||
} else {
|
||||
qDebug() << "Error: Object is unknown (PipXStatus).";
|
||||
qDebug() << "Error: Object is unknown (OPLinkStatus).";
|
||||
}
|
||||
|
||||
// Create the timer that is used to timeout the connection to the PipX.
|
||||
pipxTimeout = new QTimer(this);
|
||||
connect(pipxTimeout, SIGNAL(timeout()),this,SLOT(onPipxtremeDisconnect()));
|
||||
pipxConnected = false;
|
||||
// Create the timer that is used to timeout the connection to the OPLink.
|
||||
oplinkTimeout = new QTimer(this);
|
||||
connect(oplinkTimeout, SIGNAL(timeout()), this, SLOT(onOPLinkDisconnect()));
|
||||
oplinkConnected = false;
|
||||
}
|
||||
|
||||
ConfigGadgetWidget::~ConfigGadgetWidget()
|
||||
@ -268,29 +268,29 @@ void ConfigGadgetWidget::tabAboutToChange(int i, bool * proceed)
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief Called by updates to @PipXStatus
|
||||
\brief Called by updates to @OPLinkStatus
|
||||
*/
|
||||
void ConfigGadgetWidget::updatePipXStatus(UAVObject *)
|
||||
void ConfigGadgetWidget::updateOPLinkStatus(UAVObject *)
|
||||
{
|
||||
// Restart the disconnection timer.
|
||||
pipxTimeout->start(5000);
|
||||
if (!pipxConnected)
|
||||
oplinkTimeout->start(5000);
|
||||
if (!oplinkConnected)
|
||||
{
|
||||
qDebug() << "ConfigGadgetWidget onPipxtremeConnect";
|
||||
qDebug() << "ConfigGadgetWidget onOPLinkConnect";
|
||||
|
||||
QIcon *icon = new QIcon();
|
||||
icon->addFile(":/configgadget/images/pipx-normal.png", QSize(), QIcon::Normal, QIcon::Off);
|
||||
icon->addFile(":/configgadget/images/pipx-selected.png", QSize(), QIcon::Selected, QIcon::Off);
|
||||
|
||||
QWidget *qwd = new ConfigPipXtremeWidget(this);
|
||||
ftw->insertTab(ConfigGadgetWidget::pipxtreme, qwd, *icon, QString("PipXtreme"));
|
||||
pipxConnected = true;
|
||||
ftw->insertTab(ConfigGadgetWidget::oplink, qwd, *icon, QString("OPLink"));
|
||||
oplinkConnected = true;
|
||||
}
|
||||
}
|
||||
|
||||
void ConfigGadgetWidget::onPipxtremeDisconnect() {
|
||||
qDebug()<<"ConfigGadgetWidget onPipxtremeDisconnect";
|
||||
pipxTimeout->stop();
|
||||
ftw->removeTab(ConfigGadgetWidget::pipxtreme);
|
||||
pipxConnected = false;
|
||||
void ConfigGadgetWidget::onOPLinkDisconnect() {
|
||||
qDebug()<<"ConfigGadgetWidget onOPLinkDisconnect";
|
||||
oplinkTimeout->stop();
|
||||
ftw->removeTab(ConfigGadgetWidget::oplink);
|
||||
oplinkConnected = false;
|
||||
}
|
||||
|
@ -48,32 +48,32 @@ class ConfigGadgetWidget: public QWidget
|
||||
public:
|
||||
ConfigGadgetWidget(QWidget *parent = 0);
|
||||
~ConfigGadgetWidget();
|
||||
enum widgetTabs {hardware=0, aircraft, input, output, sensors, stabilization, camerastabilization, txpid, pipxtreme, autotune};
|
||||
enum widgetTabs {hardware=0, aircraft, input, output, sensors, stabilization, camerastabilization, txpid, oplink, autotune};
|
||||
void startInputWizard();
|
||||
|
||||
public slots:
|
||||
void onAutopilotConnect();
|
||||
void onAutopilotDisconnect();
|
||||
void tabAboutToChange(int i,bool *);
|
||||
void updatePipXStatus(UAVObject *object);
|
||||
void onPipxtremeDisconnect();
|
||||
void updateOPLinkStatus(UAVObject *object);
|
||||
void onOPLinkDisconnect();
|
||||
|
||||
signals:
|
||||
void autopilotConnected();
|
||||
void autopilotDisconnected();
|
||||
void pipxtremeConnect();
|
||||
void pipxtremeDisconnect();
|
||||
void oplinkConnect();
|
||||
void oplinkDisconnect();
|
||||
|
||||
protected:
|
||||
void resizeEvent(QResizeEvent * event);
|
||||
MyTabbedStackWidget *ftw;
|
||||
|
||||
private:
|
||||
UAVDataObject* pipxStatusObj;
|
||||
UAVDataObject* oplinkStatusObj;
|
||||
|
||||
// A timer that timesout the connction to the PipX.
|
||||
QTimer *pipxTimeout;
|
||||
bool pipxConnected;
|
||||
// A timer that timesout the connction to the OPLink.
|
||||
QTimer *oplinkTimeout;
|
||||
bool oplinkConnected;
|
||||
};
|
||||
|
||||
#endif // CONFIGGADGETWIDGET_H
|
||||
|
@ -77,6 +77,7 @@ ConfigInputWidget::ConfigInputWidget(QWidget *parent) :
|
||||
|
||||
//Generate the rows of buttons in the input channel form GUI
|
||||
unsigned int index=0;
|
||||
unsigned int indexRT = 0;
|
||||
foreach (QString name, manualSettingsObj->getField("ChannelNumber")->getElementNames())
|
||||
{
|
||||
Q_ASSERT(index < ManualControlSettings::CHANNELGROUPS_NUMELEM);
|
||||
@ -88,6 +89,28 @@ ConfigInputWidget::ConfigInputWidget(QWidget *parent) :
|
||||
addUAVObjectToWidgetRelation("ManualControlSettings","ChannelMin",inpForm->ui->channelMin,index);
|
||||
addUAVObjectToWidgetRelation("ManualControlSettings","ChannelNeutral",inpForm->ui->channelNeutral,index);
|
||||
addUAVObjectToWidgetRelation("ManualControlSettings","ChannelMax",inpForm->ui->channelMax,index);
|
||||
|
||||
// Input filter response time fields supported for some channels only
|
||||
switch (index) {
|
||||
case ManualControlSettings::CHANNELGROUPS_ROLL:
|
||||
case ManualControlSettings::CHANNELGROUPS_PITCH:
|
||||
case ManualControlSettings::CHANNELGROUPS_YAW:
|
||||
case ManualControlSettings::CHANNELGROUPS_ACCESSORY0:
|
||||
case ManualControlSettings::CHANNELGROUPS_ACCESSORY1:
|
||||
case ManualControlSettings::CHANNELGROUPS_ACCESSORY2:
|
||||
addUAVObjectToWidgetRelation("ManualControlSettings", "ResponseTime", inpForm->ui->channelResponseTime, indexRT);
|
||||
++indexRT;
|
||||
break;
|
||||
case ManualControlSettings::CHANNELGROUPS_THROTTLE:
|
||||
case ManualControlSettings::CHANNELGROUPS_FLIGHTMODE:
|
||||
case ManualControlSettings::CHANNELGROUPS_COLLECTIVE:
|
||||
inpForm->ui->channelResponseTime->setEnabled(false);
|
||||
break;
|
||||
default:
|
||||
Q_ASSERT(0);
|
||||
break;
|
||||
}
|
||||
|
||||
++index;
|
||||
}
|
||||
|
||||
|
@ -27,77 +27,81 @@
|
||||
|
||||
#include "configpipxtremewidget.h"
|
||||
|
||||
#include <pipxsettings.h>
|
||||
#include <pipxstatus.h>
|
||||
#include <oplinksettings.h>
|
||||
#include <oplinkstatus.h>
|
||||
|
||||
ConfigPipXtremeWidget::ConfigPipXtremeWidget(QWidget *parent) : ConfigTaskWidget(parent)
|
||||
{
|
||||
m_pipx = new Ui_PipXtremeWidget();
|
||||
m_pipx->setupUi(this);
|
||||
m_oplink = new Ui_PipXtremeWidget();
|
||||
m_oplink->setupUi(this);
|
||||
|
||||
// Connect to the PipXStatus object updates
|
||||
// Connect to the OPLinkStatus object updates
|
||||
ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance();
|
||||
UAVObjectManager *objManager = pm->getObject<UAVObjectManager>();
|
||||
pipxStatusObj = dynamic_cast<UAVDataObject*>(objManager->getObject("PipXStatus"));
|
||||
if (pipxStatusObj != NULL ) {
|
||||
connect(pipxStatusObj, SIGNAL(objectUpdated(UAVObject*)), this, SLOT(updateStatus(UAVObject*)));
|
||||
oplinkStatusObj = dynamic_cast<UAVDataObject*>(objManager->getObject("OPLinkStatus"));
|
||||
if (oplinkStatusObj != NULL ) {
|
||||
connect(oplinkStatusObj, SIGNAL(objectUpdated(UAVObject*)), this, SLOT(updateStatus(UAVObject*)));
|
||||
} else {
|
||||
qDebug() << "Error: Object is unknown (PipXStatus).";
|
||||
qDebug() << "Error: Object is unknown (OPLinkStatus).";
|
||||
}
|
||||
|
||||
// Connect to the PipXSettings object updates
|
||||
pipxSettingsObj = dynamic_cast<UAVDataObject*>(objManager->getObject("PipXSettings"));
|
||||
if (pipxSettingsObj != NULL ) {
|
||||
connect(pipxSettingsObj, SIGNAL(objectUpdated(UAVObject*)), this, SLOT(updateSettings(UAVObject*)));
|
||||
// Connect to the OPLinkSettings object updates
|
||||
oplinkSettingsObj = dynamic_cast<UAVDataObject*>(objManager->getObject("OPLinkSettings"));
|
||||
if (oplinkSettingsObj != NULL ) {
|
||||
connect(oplinkSettingsObj, SIGNAL(objectUpdated(UAVObject*)), this, SLOT(updateSettings(UAVObject*)));
|
||||
} else {
|
||||
qDebug() << "Error: Object is unknown (PipXSettings).";
|
||||
qDebug() << "Error: Object is unknown (OPLinkSettings).";
|
||||
}
|
||||
autoLoadWidgets();
|
||||
addApplySaveButtons(m_pipx->Apply, m_pipx->Save);
|
||||
addApplySaveButtons(m_oplink->Apply, m_oplink->Save);
|
||||
|
||||
addUAVObjectToWidgetRelation("PipXSettings", "TelemetryConfig", m_pipx->TelemPortConfig);
|
||||
addUAVObjectToWidgetRelation("PipXSettings", "TelemetrySpeed", m_pipx->TelemPortSpeed);
|
||||
addUAVObjectToWidgetRelation("PipXSettings", "FlexiConfig", m_pipx->FlexiPortConfig);
|
||||
addUAVObjectToWidgetRelation("PipXSettings", "FlexiSpeed", m_pipx->FlexiPortSpeed);
|
||||
addUAVObjectToWidgetRelation("PipXSettings", "VCPConfig", m_pipx->VCPConfig);
|
||||
addUAVObjectToWidgetRelation("PipXSettings", "VCPSpeed", m_pipx->VCPSpeed);
|
||||
addUAVObjectToWidgetRelation("PipXSettings", "RFSpeed", m_pipx->MaxRFDatarate);
|
||||
addUAVObjectToWidgetRelation("PipXSettings", "MaxRFPower", m_pipx->MaxRFTxPower);
|
||||
addUAVObjectToWidgetRelation("PipXSettings", "SendTimeout", m_pipx->SendTimeout);
|
||||
addUAVObjectToWidgetRelation("PipXSettings", "MinPacketSize", m_pipx->MinPacketSize);
|
||||
addUAVObjectToWidgetRelation("PipXSettings", "FrequencyCalibration", m_pipx->FrequencyCalibration);
|
||||
addUAVObjectToWidgetRelation("PipXSettings", "Frequency", m_pipx->Frequency);
|
||||
addUAVObjectToWidgetRelation("OPLinkSettings", "Coordinator", m_oplink->Coordinator);
|
||||
addUAVObjectToWidgetRelation("OPLinkSettings", "PPM", m_oplink->PPM);
|
||||
addUAVObjectToWidgetRelation("OPLinkSettings", "UAVTalk", m_oplink->UAVTalk);
|
||||
addUAVObjectToWidgetRelation("OPLinkSettings", "InputConnection", m_oplink->InputConnection);
|
||||
addUAVObjectToWidgetRelation("OPLinkSettings", "OutputConnection", m_oplink->OutputConnection);
|
||||
addUAVObjectToWidgetRelation("OPLinkSettings", "ComSpeed", m_oplink->ComSpeed);
|
||||
addUAVObjectToWidgetRelation("OPLinkSettings", "MaxRFPower", m_oplink->MaxRFTxPower);
|
||||
addUAVObjectToWidgetRelation("OPLinkSettings", "SendTimeout", m_oplink->SendTimeout);
|
||||
addUAVObjectToWidgetRelation("OPLinkSettings", "MinPacketSize", m_oplink->MinPacketSize);
|
||||
addUAVObjectToWidgetRelation("OPLinkSettings", "FrequencyCalibration", m_oplink->FrequencyCalibration);
|
||||
addUAVObjectToWidgetRelation("OPLinkSettings", "MinFrequency", m_oplink->MinFrequency);
|
||||
addUAVObjectToWidgetRelation("OPLinkSettings", "MaxFrequency", m_oplink->MaxFrequency);
|
||||
|
||||
addUAVObjectToWidgetRelation("PipXStatus", "MinFrequency", m_pipx->MinFrequency);
|
||||
addUAVObjectToWidgetRelation("PipXStatus", "MaxFrequency", m_pipx->MaxFrequency);
|
||||
addUAVObjectToWidgetRelation("PipXStatus", "FrequencyStepSize", m_pipx->FrequencyStepSize);
|
||||
addUAVObjectToWidgetRelation("PipXStatus", "FrequencyBand", m_pipx->FreqBand);
|
||||
addUAVObjectToWidgetRelation("PipXStatus", "RSSI", m_pipx->RSSI);
|
||||
addUAVObjectToWidgetRelation("PipXStatus", "AFC", m_pipx->RxAFC);
|
||||
addUAVObjectToWidgetRelation("PipXStatus", "Retries", m_pipx->Retries);
|
||||
addUAVObjectToWidgetRelation("PipXStatus", "LinkQuality", m_pipx->LinkQuality);
|
||||
addUAVObjectToWidgetRelation("PipXStatus", "UAVTalkErrors", m_pipx->UAVTalkErrors);
|
||||
addUAVObjectToWidgetRelation("PipXStatus", "Resets", m_pipx->Resets);
|
||||
addUAVObjectToWidgetRelation("PipXStatus", "Dropped", m_pipx->Dropped);
|
||||
addUAVObjectToWidgetRelation("PipXStatus", "RXRate", m_pipx->RXRate);
|
||||
addUAVObjectToWidgetRelation("PipXStatus", "TXRate", m_pipx->TXRate);
|
||||
addUAVObjectToWidgetRelation("OPLinkStatus", "RxGood", m_oplink->Good);
|
||||
addUAVObjectToWidgetRelation("OPLinkStatus", "RxCorrected", m_oplink->Corrected);
|
||||
addUAVObjectToWidgetRelation("OPLinkStatus", "RxErrors", m_oplink->Errors);
|
||||
addUAVObjectToWidgetRelation("OPLinkStatus", "RxMissed", m_oplink->Missed);
|
||||
addUAVObjectToWidgetRelation("OPLinkStatus", "RxFailure", m_oplink->RxFailure);
|
||||
addUAVObjectToWidgetRelation("OPLinkStatus", "UAVTalkErrors", m_oplink->UAVTalkErrors);
|
||||
addUAVObjectToWidgetRelation("OPLinkStatus", "TxDropped", m_oplink->Dropped);
|
||||
addUAVObjectToWidgetRelation("OPLinkStatus", "TxResent", m_oplink->Resent);
|
||||
addUAVObjectToWidgetRelation("OPLinkStatus", "TxFailure", m_oplink->TxFailure);
|
||||
addUAVObjectToWidgetRelation("OPLinkStatus", "Resets", m_oplink->Resets);
|
||||
addUAVObjectToWidgetRelation("OPLinkStatus", "Timeouts", m_oplink->Timeouts);
|
||||
addUAVObjectToWidgetRelation("OPLinkStatus", "RSSI", m_oplink->RSSI);
|
||||
addUAVObjectToWidgetRelation("OPLinkStatus", "AFCCorrection", m_oplink->AFCCorrection);
|
||||
addUAVObjectToWidgetRelation("OPLinkStatus", "LinkQuality", m_oplink->LinkQuality);
|
||||
addUAVObjectToWidgetRelation("OPLinkStatus", "RXSeq", m_oplink->RXSeq);
|
||||
addUAVObjectToWidgetRelation("OPLinkStatus", "TXSeq", m_oplink->TXSeq);
|
||||
addUAVObjectToWidgetRelation("OPLinkStatus", "RXRate", m_oplink->RXRate);
|
||||
addUAVObjectToWidgetRelation("OPLinkStatus", "TXRate", m_oplink->TXRate);
|
||||
|
||||
// Connect to the pair ID radio buttons.
|
||||
connect(m_pipx->PairSelectB, SIGNAL(toggled(bool)), this, SLOT(pairBToggled(bool)));
|
||||
connect(m_pipx->PairSelect1, SIGNAL(toggled(bool)), this, SLOT(pair1Toggled(bool)));
|
||||
connect(m_pipx->PairSelect2, SIGNAL(toggled(bool)), this, SLOT(pair2Toggled(bool)));
|
||||
connect(m_pipx->PairSelect3, SIGNAL(toggled(bool)), this, SLOT(pair3Toggled(bool)));
|
||||
connect(m_pipx->PairSelect4, SIGNAL(toggled(bool)), this, SLOT(pair4Toggled(bool)));
|
||||
connect(m_oplink->PairSelectB, SIGNAL(toggled(bool)), this, SLOT(pairBToggled(bool)));
|
||||
connect(m_oplink->PairSelect1, SIGNAL(toggled(bool)), this, SLOT(pair1Toggled(bool)));
|
||||
connect(m_oplink->PairSelect2, SIGNAL(toggled(bool)), this, SLOT(pair2Toggled(bool)));
|
||||
connect(m_oplink->PairSelect3, SIGNAL(toggled(bool)), this, SLOT(pair3Toggled(bool)));
|
||||
connect(m_oplink->PairSelect4, SIGNAL(toggled(bool)), this, SLOT(pair4Toggled(bool)));
|
||||
|
||||
//Add scroll bar when necessary
|
||||
QScrollArea *scroll = new QScrollArea;
|
||||
scroll->setWidget(m_pipx->frame_3);
|
||||
scroll->setWidget(m_oplink->frame_3);
|
||||
scroll->setWidgetResizable(true);
|
||||
m_pipx->verticalLayout_3->addWidget(scroll);
|
||||
m_oplink->verticalLayout_3->addWidget(scroll);
|
||||
|
||||
// Request and update of the setting object.
|
||||
settingsUpdated = false;
|
||||
//pipxSettingsObj->requestUpdate();
|
||||
|
||||
disableMouseWheelEvents();
|
||||
}
|
||||
@ -113,84 +117,84 @@ void ConfigPipXtremeWidget::refreshValues()
|
||||
|
||||
void ConfigPipXtremeWidget::applySettings()
|
||||
{
|
||||
PipXSettings *pipxSettings = PipXSettings::GetInstance(getObjectManager());
|
||||
PipXSettings::DataFields pipxSettingsData = pipxSettings->getData();
|
||||
OPLinkSettings *oplinkSettings = OPLinkSettings::GetInstance(getObjectManager());
|
||||
OPLinkSettings::DataFields oplinkSettingsData = oplinkSettings->getData();
|
||||
|
||||
// Get the pair ID.
|
||||
quint32 pairID = 0;
|
||||
bool okay;
|
||||
if (m_pipx->PairSelect1->isChecked())
|
||||
pairID = m_pipx->PairID1->text().toUInt(&okay, 16);
|
||||
else if (m_pipx->PairSelect2->isChecked())
|
||||
pairID = m_pipx->PairID2->text().toUInt(&okay, 16);
|
||||
else if (m_pipx->PairSelect3->isChecked())
|
||||
pairID = m_pipx->PairID3->text().toUInt(&okay, 16);
|
||||
else if (m_pipx->PairSelect4->isChecked())
|
||||
pairID = m_pipx->PairID4->text().toUInt(&okay, 16);
|
||||
pipxSettingsData.PairID = pairID;
|
||||
pipxSettings->setData(pipxSettingsData);
|
||||
if (m_oplink->PairSelect1->isChecked())
|
||||
pairID = m_oplink->PairID1->text().toUInt(&okay, 16);
|
||||
else if (m_oplink->PairSelect2->isChecked())
|
||||
pairID = m_oplink->PairID2->text().toUInt(&okay, 16);
|
||||
else if (m_oplink->PairSelect3->isChecked())
|
||||
pairID = m_oplink->PairID3->text().toUInt(&okay, 16);
|
||||
else if (m_oplink->PairSelect4->isChecked())
|
||||
pairID = m_oplink->PairID4->text().toUInt(&okay, 16);
|
||||
oplinkSettingsData.PairID = pairID;
|
||||
oplinkSettings->setData(oplinkSettingsData);
|
||||
}
|
||||
|
||||
void ConfigPipXtremeWidget::saveSettings()
|
||||
{
|
||||
//applySettings();
|
||||
UAVObject *obj = PipXSettings::GetInstance(getObjectManager());
|
||||
UAVObject *obj = OPLinkSettings::GetInstance(getObjectManager());
|
||||
saveObjectToSD(obj);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief Called by updates to @PipXStatus
|
||||
\brief Called by updates to @OPLinkStatus
|
||||
*/
|
||||
void ConfigPipXtremeWidget::updateStatus(UAVObject *object)
|
||||
{
|
||||
|
||||
// Request and update of the setting object if we haven't received it yet.
|
||||
if (!settingsUpdated)
|
||||
pipxSettingsObj->requestUpdate();
|
||||
oplinkSettingsObj->requestUpdate();
|
||||
|
||||
// Get the current pairID
|
||||
PipXSettings *pipxSettings = PipXSettings::GetInstance(getObjectManager());
|
||||
OPLinkSettings *oplinkSettings = OPLinkSettings::GetInstance(getObjectManager());
|
||||
quint32 pairID = 0;
|
||||
if (pipxSettings)
|
||||
pairID = pipxSettings->getPairID();
|
||||
if (oplinkSettings)
|
||||
pairID = oplinkSettings->getPairID();
|
||||
|
||||
// Update the detected devices.
|
||||
UAVObjectField* pairIdField = object->getField("PairIDs");
|
||||
if (pairIdField) {
|
||||
quint32 pairid1 = pairIdField->getValue(0).toUInt();
|
||||
m_pipx->PairID1->setText(QString::number(pairid1, 16).toUpper());
|
||||
m_pipx->PairID1->setEnabled(false);
|
||||
m_pipx->PairSelect1->setChecked(pairID && (pairID == pairid1));
|
||||
m_pipx->PairSelect1->setEnabled(pairid1);
|
||||
m_oplink->PairID1->setText(QString::number(pairid1, 16).toUpper());
|
||||
m_oplink->PairID1->setEnabled(false);
|
||||
m_oplink->PairSelect1->setChecked(pairID && (pairID == pairid1));
|
||||
m_oplink->PairSelect1->setEnabled(pairid1);
|
||||
quint32 pairid2 = pairIdField->getValue(1).toUInt();
|
||||
m_pipx->PairID2->setText(QString::number(pairIdField->getValue(1).toUInt(), 16).toUpper());
|
||||
m_pipx->PairID2->setEnabled(false);
|
||||
m_pipx->PairSelect2->setChecked(pairID && (pairID == pairid2));
|
||||
m_pipx->PairSelect2->setEnabled(pairid2);
|
||||
m_oplink->PairID2->setText(QString::number(pairIdField->getValue(1).toUInt(), 16).toUpper());
|
||||
m_oplink->PairID2->setEnabled(false);
|
||||
m_oplink->PairSelect2->setChecked(pairID && (pairID == pairid2));
|
||||
m_oplink->PairSelect2->setEnabled(pairid2);
|
||||
quint32 pairid3 = pairIdField->getValue(2).toUInt();
|
||||
m_pipx->PairID3->setText(QString::number(pairIdField->getValue(2).toUInt(), 16).toUpper());
|
||||
m_pipx->PairID3->setEnabled(false);
|
||||
m_pipx->PairSelect3->setChecked(pairID && (pairID == pairid3));
|
||||
m_pipx->PairSelect3->setEnabled(pairid3);
|
||||
m_oplink->PairID3->setText(QString::number(pairIdField->getValue(2).toUInt(), 16).toUpper());
|
||||
m_oplink->PairID3->setEnabled(false);
|
||||
m_oplink->PairSelect3->setChecked(pairID && (pairID == pairid3));
|
||||
m_oplink->PairSelect3->setEnabled(pairid3);
|
||||
quint32 pairid4 = pairIdField->getValue(3).toUInt();
|
||||
m_pipx->PairID4->setText(QString::number(pairIdField->getValue(3).toUInt(), 16).toUpper());
|
||||
m_pipx->PairID4->setEnabled(false);
|
||||
m_pipx->PairSelect4->setChecked(pairID && (pairID == pairid4));
|
||||
m_pipx->PairSelect4->setEnabled(pairid4);
|
||||
m_oplink->PairID4->setText(QString::number(pairIdField->getValue(3).toUInt(), 16).toUpper());
|
||||
m_oplink->PairID4->setEnabled(false);
|
||||
m_oplink->PairSelect4->setChecked(pairID && (pairID == pairid4));
|
||||
m_oplink->PairSelect4->setEnabled(pairid4);
|
||||
} else {
|
||||
qDebug() << "PipXtremeGadgetWidget: Count not read PairID field.";
|
||||
}
|
||||
UAVObjectField* pairRssiField = object->getField("PairSignalStrengths");
|
||||
if (pairRssiField) {
|
||||
m_pipx->PairSignalStrengthBar1->setValue(pairRssiField->getValue(0).toInt());
|
||||
m_pipx->PairSignalStrengthBar2->setValue(pairRssiField->getValue(1).toInt());
|
||||
m_pipx->PairSignalStrengthBar3->setValue(pairRssiField->getValue(2).toInt());
|
||||
m_pipx->PairSignalStrengthBar4->setValue(pairRssiField->getValue(3).toInt());
|
||||
m_pipx->PairSignalStrengthLabel1->setText(QString("%1dB").arg(pairRssiField->getValue(0).toInt()));
|
||||
m_pipx->PairSignalStrengthLabel2->setText(QString("%1dB").arg(pairRssiField->getValue(1).toInt()));
|
||||
m_pipx->PairSignalStrengthLabel3->setText(QString("%1dB").arg(pairRssiField->getValue(2).toInt()));
|
||||
m_pipx->PairSignalStrengthLabel4->setText(QString("%1dB").arg(pairRssiField->getValue(3).toInt()));
|
||||
} else {
|
||||
m_oplink->PairSignalStrengthBar1->setValue(pairRssiField->getValue(0).toInt());
|
||||
m_oplink->PairSignalStrengthBar2->setValue(pairRssiField->getValue(1).toInt());
|
||||
m_oplink->PairSignalStrengthBar3->setValue(pairRssiField->getValue(2).toInt());
|
||||
m_oplink->PairSignalStrengthBar4->setValue(pairRssiField->getValue(3).toInt());
|
||||
m_oplink->PairSignalStrengthLabel1->setText(QString("%1dB").arg(pairRssiField->getValue(0).toInt()));
|
||||
m_oplink->PairSignalStrengthLabel2->setText(QString("%1dB").arg(pairRssiField->getValue(1).toInt()));
|
||||
m_oplink->PairSignalStrengthLabel3->setText(QString("%1dB").arg(pairRssiField->getValue(2).toInt()));
|
||||
m_oplink->PairSignalStrengthLabel4->setText(QString("%1dB").arg(pairRssiField->getValue(3).toInt()));
|
||||
} else {
|
||||
qDebug() << "PipXtremeGadgetWidget: Count not read PairID field.";
|
||||
}
|
||||
|
||||
@ -208,7 +212,7 @@ void ConfigPipXtremeWidget::updateStatus(UAVObject *object)
|
||||
* 20 bytes: SHA1 sum of the firmware.
|
||||
* 40 bytes: free for now.
|
||||
*/
|
||||
char buf[PipXStatus::DESCRIPTION_NUMELEM];
|
||||
char buf[OPLinkStatus::DESCRIPTION_NUMELEM];
|
||||
for (unsigned int i = 0; i < 26; ++i)
|
||||
buf[i] = descField->getValue(i + 14).toChar().toAscii();
|
||||
buf[26] = '\0';
|
||||
@ -219,7 +223,7 @@ void ConfigPipXtremeWidget::updateStatus(UAVObject *object)
|
||||
gitDate += descField->getValue(11-i).toChar().toAscii() & 0xFF;
|
||||
}
|
||||
QString date = QDateTime::fromTime_t(gitDate).toUTC().toString("yyyy-MM-dd HH:mm");
|
||||
m_pipx->FirmwareVersion->setText(descstr + " " + date);
|
||||
m_oplink->FirmwareVersion->setText(descstr + " " + date);
|
||||
} else {
|
||||
qDebug() << "PipXtremeGadgetWidget: Count not read Description field.";
|
||||
}
|
||||
@ -227,16 +231,16 @@ void ConfigPipXtremeWidget::updateStatus(UAVObject *object)
|
||||
// Update the serial number field
|
||||
UAVObjectField* serialField = object->getField("CPUSerial");
|
||||
if (serialField) {
|
||||
char buf[PipXStatus::CPUSERIAL_NUMELEM * 2 + 1];
|
||||
for (unsigned int i = 0; i < PipXStatus::CPUSERIAL_NUMELEM; ++i)
|
||||
char buf[OPLinkStatus::CPUSERIAL_NUMELEM * 2 + 1];
|
||||
for (unsigned int i = 0; i < OPLinkStatus::CPUSERIAL_NUMELEM; ++i)
|
||||
{
|
||||
unsigned char val = serialField->getValue(i).toUInt() >> 4;
|
||||
buf[i * 2] = ((val < 10) ? '0' : '7') + val;
|
||||
val = serialField->getValue(i).toUInt() & 0xf;
|
||||
buf[i * 2 + 1] = ((val < 10) ? '0' : '7') + val;
|
||||
}
|
||||
buf[PipXStatus::CPUSERIAL_NUMELEM * 2] = '\0';
|
||||
m_pipx->SerialNumber->setText(buf);
|
||||
buf[OPLinkStatus::CPUSERIAL_NUMELEM * 2] = '\0';
|
||||
m_oplink->SerialNumber->setText(buf);
|
||||
} else {
|
||||
qDebug() << "PipXtremeGadgetWidget: Count not read Description field.";
|
||||
}
|
||||
@ -244,35 +248,35 @@ void ConfigPipXtremeWidget::updateStatus(UAVObject *object)
|
||||
// Update the DeviceID field
|
||||
UAVObjectField* idField = object->getField("DeviceID");
|
||||
if (idField) {
|
||||
m_pipx->DeviceID->setText(QString::number(idField->getValue().toUInt(), 16).toUpper());
|
||||
m_oplink->DeviceID->setText(QString::number(idField->getValue().toUInt(), 16).toUpper());
|
||||
} else {
|
||||
qDebug() << "PipXtremeGadgetWidget: Count not read DeviceID field.";
|
||||
}
|
||||
|
||||
// Update the PairID field
|
||||
m_pipx->PairID->setText(QString::number(pairID, 16).toUpper());
|
||||
m_oplink->PairID->setText(QString::number(pairID, 16).toUpper());
|
||||
|
||||
// Update the link state
|
||||
UAVObjectField* linkField = object->getField("LinkState");
|
||||
if (linkField) {
|
||||
m_pipx->LinkState->setText(linkField->getValue().toString());
|
||||
m_oplink->LinkState->setText(linkField->getValue().toString());
|
||||
} else {
|
||||
qDebug() << "PipXtremeGadgetWidget: Count not read link state field.";
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief Called by updates to @PipXSettings
|
||||
\brief Called by updates to @OPLinkSettings
|
||||
*/
|
||||
void ConfigPipXtremeWidget::updateSettings(UAVObject *object)
|
||||
{
|
||||
Q_UNUSED(object);
|
||||
|
||||
if (!settingsUpdated)
|
||||
{
|
||||
settingsUpdated = true;
|
||||
enableControls(true);
|
||||
}
|
||||
{
|
||||
settingsUpdated = true;
|
||||
enableControls(true);
|
||||
}
|
||||
}
|
||||
|
||||
void ConfigPipXtremeWidget::disconnected()
|
||||
@ -288,20 +292,20 @@ void ConfigPipXtremeWidget::pairIDToggled(bool checked, quint8 idx)
|
||||
{
|
||||
if(checked)
|
||||
{
|
||||
PipXStatus *pipxStatus = PipXStatus::GetInstance(getObjectManager());
|
||||
PipXSettings *pipxSettings = PipXSettings::GetInstance(getObjectManager());
|
||||
OPLinkStatus *oplinkStatus = OPLinkStatus::GetInstance(getObjectManager());
|
||||
OPLinkSettings *oplinkSettings = OPLinkSettings::GetInstance(getObjectManager());
|
||||
|
||||
if (pipxStatus && pipxSettings)
|
||||
if (oplinkStatus && oplinkSettings)
|
||||
{
|
||||
if (idx == 4)
|
||||
{
|
||||
pipxSettings->setPairID(0);
|
||||
oplinkSettings->setPairID(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
quint32 pairID = pipxStatus->getPairIDs(idx);
|
||||
quint32 pairID = oplinkStatus->getPairIDs(idx);
|
||||
if (pairID)
|
||||
pipxSettings->setPairID(pairID);
|
||||
oplinkSettings->setPairID(pairID);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -43,13 +43,13 @@ public slots:
|
||||
void updateSettings(UAVObject *object1);
|
||||
|
||||
private:
|
||||
Ui_PipXtremeWidget *m_pipx;
|
||||
Ui_PipXtremeWidget *m_oplink;
|
||||
|
||||
// The PipXtreme status UAVObject
|
||||
UAVDataObject* pipxStatusObj;
|
||||
// The OPLink status UAVObject
|
||||
UAVDataObject* oplinkStatusObj;
|
||||
|
||||
// The PipXtreme ssettins UAVObject
|
||||
UAVDataObject* pipxSettingsObj;
|
||||
// The OPLink ssettins UAVObject
|
||||
UAVDataObject* oplinkSettingsObj;
|
||||
|
||||
bool settingsUpdated;
|
||||
|
||||
|
@ -54,7 +54,7 @@
|
||||
#define sign(x) ((x < 0) ? -1 : 1)
|
||||
|
||||
// Uncomment this to enable 6 point calibration on the accels
|
||||
//#define SIX_POINT_CAL_ACCEL
|
||||
#define SIX_POINT_CAL_ACCEL
|
||||
|
||||
const double ConfigRevoWidget::maxVarValue = 0.1;
|
||||
|
||||
|
@ -49,9 +49,8 @@ ConfigStabilizationWidget::ConfigStabilizationWidget(QWidget *parent) : ConfigTa
|
||||
|
||||
ExtensionSystem::PluginManager *pm=ExtensionSystem::PluginManager::instance();
|
||||
Core::Internal::GeneralSettings * settings=pm->getObject<Core::Internal::GeneralSettings>();
|
||||
if(!settings->useExpertMode() || true)
|
||||
if(!settings->useExpertMode())
|
||||
m_stabilization->saveStabilizationToRAM_6->setVisible(false);
|
||||
m_stabilization->saveStabilizationToRAM_6->setVisible(true);
|
||||
|
||||
|
||||
|
||||
|
@ -1368,7 +1368,8 @@ channel value for each flight mode.</string>
|
||||
<enum>Qt::StrongFocus</enum>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>After the time indicated here, the frame go back to disarmed state.</string>
|
||||
<string>After the time indicated here, the frame go back to disarmed state.
|
||||
Set to 0 to disable (recommended for soaring fixed wings).</string>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>64</number>
|
||||
@ -1378,7 +1379,7 @@ channel value for each flight mode.</string>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_19">
|
||||
<property name="text">
|
||||
<string>seconds.</string>
|
||||
<string>seconds (0 to disable).</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
|
@ -19,12 +19,14 @@ inputChannelForm::inputChannelForm(QWidget *parent,bool showlegend) :
|
||||
layout()->removeWidget(ui->legend3);
|
||||
layout()->removeWidget(ui->legend4);
|
||||
layout()->removeWidget(ui->legend5);
|
||||
layout()->removeWidget(ui->legend6);
|
||||
delete ui->legend0;
|
||||
delete ui->legend1;
|
||||
delete ui->legend2;
|
||||
delete ui->legend3;
|
||||
delete ui->legend4;
|
||||
delete ui->legend5;
|
||||
delete ui->legend6;
|
||||
|
||||
}
|
||||
|
||||
@ -109,6 +111,7 @@ void inputChannelForm::groupUpdated()
|
||||
count = 8; // Need to make this 6 for CC
|
||||
break;
|
||||
case ManualControlSettings::CHANNELGROUPS_PPM:
|
||||
case ManualControlSettings::CHANNELGROUPS_OPLINK:
|
||||
case ManualControlSettings::CHANNELGROUPS_DSMMAINPORT:
|
||||
case ManualControlSettings::CHANNELGROUPS_DSMFLEXIPORT:
|
||||
count = 12;
|
||||
|
@ -236,83 +236,6 @@ font:bold;</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="7">
|
||||
<widget class="QLabel" name="legend5">
|
||||
<property name="enabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<weight>75</weight>
|
||||
<italic>false</italic>
|
||||
<bold>true</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true">background-color: qlineargradient(spread:reflect, x1:0.507, y1:0, x2:0.507, y2:0.772, stop:0.208955 rgba(74, 74, 74, 255), stop:0.78607 rgba(36, 36, 36, 255));
|
||||
color: rgb(255, 255, 255);
|
||||
border-radius: 5;
|
||||
margin:1px;
|
||||
font:bold;</string>
|
||||
</property>
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::StyledPanel</enum>
|
||||
</property>
|
||||
<property name="lineWidth">
|
||||
<number>1</number>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Max</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="8">
|
||||
<spacer name="horizontalSpacer_3">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeType">
|
||||
<enum>QSizePolicy::Fixed</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>48</width>
|
||||
<height>10</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="0" column="9">
|
||||
<spacer name="horizontalSpacer_4">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeType">
|
||||
<enum>QSizePolicy::Fixed</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>42</width>
|
||||
<height>10</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="channelName">
|
||||
<property name="sizePolicy">
|
||||
@ -483,6 +406,144 @@ font:bold;</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="7">
|
||||
<widget class="QLabel" name="legend5">
|
||||
<property name="enabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<weight>75</weight>
|
||||
<italic>false</italic>
|
||||
<bold>true</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true">background-color: qlineargradient(spread:reflect, x1:0.507, y1:0, x2:0.507, y2:0.772, stop:0.208955 rgba(74, 74, 74, 255), stop:0.78607 rgba(36, 36, 36, 255));
|
||||
color: rgb(255, 255, 255);
|
||||
border-radius: 5;
|
||||
margin:1px;
|
||||
font:bold;</string>
|
||||
</property>
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::StyledPanel</enum>
|
||||
</property>
|
||||
<property name="lineWidth">
|
||||
<number>1</number>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Max</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="9">
|
||||
<widget class="QCheckBox" name="channelRev">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Rev</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="10">
|
||||
<widget class="QSpinBox" name="channelResponseTime">
|
||||
<property name="enabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>30</width>
|
||||
<height>25</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Optional input filter response time.
|
||||
|
||||
Range: 0-999ms, 0 disables filter (default).
|
||||
|
||||
Warning: this is an expert mode feature, mostly used for aerial video
|
||||
camera control (airframe yaw and camera gimbal accessory channels).
|
||||
Too high values for main controls can cause undesirable effects and
|
||||
even lead to crash. Use with caution.</string>
|
||||
</property>
|
||||
<property name="wrapping">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="frame">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="buttonSymbols">
|
||||
<enum>QAbstractSpinBox::NoButtons</enum>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>999</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="10">
|
||||
<widget class="QLabel" name="legend6">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>30</width>
|
||||
<height>26</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<weight>75</weight>
|
||||
<italic>false</italic>
|
||||
<bold>true</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true">background-color: qlineargradient(spread:reflect, x1:0.507, y1:0, x2:0.507, y2:0.772, stop:0.208955 rgba(74, 74, 74, 255), stop:0.78607 rgba(36, 36, 36, 255));
|
||||
color: rgb(255, 255, 255);
|
||||
border-radius: 5;
|
||||
margin:5px;
|
||||
font:bold;</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>RT</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="8">
|
||||
<widget class="QLabel" name="neutral">
|
||||
<property name="sizePolicy">
|
||||
@ -508,22 +569,6 @@ font:bold;</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="9">
|
||||
<widget class="QCheckBox" name="channelRev">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Rev</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
<widget class="QSpinBox" name="channelNumber">
|
||||
<property name="enabled">
|
||||
@ -552,7 +597,6 @@ font:bold;</string>
|
||||
<tabstop>channelMin</tabstop>
|
||||
<tabstop>channelNeutral</tabstop>
|
||||
<tabstop>channelMax</tabstop>
|
||||
<tabstop>channelRev</tabstop>
|
||||
</tabstops>
|
||||
<resources/>
|
||||
<connections/>
|
||||
|
@ -434,7 +434,7 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="label_2">
|
||||
<property name="text">
|
||||
<string>Serial Number</string>
|
||||
@ -444,7 +444,7 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1" colspan="3">
|
||||
<item row="1" column="1" colspan="3">
|
||||
<widget class="QLineEdit" name="SerialNumber">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||
@ -498,7 +498,7 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="DeviceIDLabel">
|
||||
<property name="text">
|
||||
<string>Device ID</string>
|
||||
@ -508,7 +508,7 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="1">
|
||||
<item row="2" column="1">
|
||||
<widget class="QLineEdit" name="DeviceID">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
@ -552,7 +552,7 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="2">
|
||||
<item row="3" column="0">
|
||||
<widget class="QLabel" name="PairIDLabel">
|
||||
<property name="text">
|
||||
<string>Pair ID</string>
|
||||
@ -562,7 +562,7 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="3">
|
||||
<item row="3" column="1">
|
||||
<widget class="QLineEdit" name="PairID">
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
@ -601,9 +601,9 @@
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="0">
|
||||
<widget class="QLabel" name="label_3">
|
||||
<widget class="QLabel" name="label_11">
|
||||
<property name="text">
|
||||
<string>Min Frequency</string>
|
||||
<string>Link State</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
@ -611,9 +611,9 @@
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="1">
|
||||
<widget class="QLineEdit" name="MinFrequency">
|
||||
<widget class="QLineEdit" name="LinkState">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
@ -637,13 +637,13 @@
|
||||
</font>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>The modems minimum allowed frequency</string>
|
||||
<string>The modems current state</string>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true">QLineEdit {
|
||||
border: none;
|
||||
border-radius: 1px;
|
||||
padding: 0 4px;
|
||||
padding: 0 3px;
|
||||
background: rgba(0, 0, 0, 16);
|
||||
/* background: transparent; */
|
||||
/* selection-background-color: darkgray;*/
|
||||
@ -655,63 +655,15 @@
|
||||
<property name="readOnly">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="2">
|
||||
<widget class="QLabel" name="label_4">
|
||||
<property name="text">
|
||||
<string>Max Frequency</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="3">
|
||||
<widget class="QLineEdit" name="MaxFrequency">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>101</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<weight>75</weight>
|
||||
<bold>true</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>The modems maximum allowed frequency</string>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true">QLineEdit {
|
||||
border: none;
|
||||
border-radius: 1px;
|
||||
padding: 0 4px;
|
||||
background: rgba(0, 0, 0, 16);
|
||||
/* background: transparent; */
|
||||
/* selection-background-color: darkgray;*/
|
||||
}</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
<property name="readOnly">
|
||||
<bool>true</bool>
|
||||
<property name="placeholderText">
|
||||
<string>Disconnected</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="0">
|
||||
<widget class="QLabel" name="label_12">
|
||||
<widget class="QLabel" name="LinkQualityLabel">
|
||||
<property name="text">
|
||||
<string>Freq. Step Size</string>
|
||||
<string>Link Quality</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
@ -719,19 +671,7 @@
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="1">
|
||||
<widget class="QLineEdit" name="FrequencyStepSize">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<widget class="QLineEdit" name="LinkQuality">
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>101</width>
|
||||
@ -744,9 +684,6 @@
|
||||
<bold>true</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>The modems minimum frequency step size</string>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true">QLineEdit {
|
||||
border: none;
|
||||
@ -757,59 +694,8 @@
|
||||
/* selection-background-color: darkgray;*/
|
||||
}</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
<property name="readOnly">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="2">
|
||||
<widget class="QLabel" name="FreqBandLabel">
|
||||
<property name="text">
|
||||
<string>Freq. Band</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="3">
|
||||
<widget class="QLineEdit" name="FreqBand">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>101</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<weight>75</weight>
|
||||
<bold>true</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>The current frequency band</string>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true">QLineEdit {
|
||||
border: none;
|
||||
border-radius: 1px;
|
||||
padding: 0 4px;
|
||||
background: rgba(0, 0, 0, 16);
|
||||
/* background: transparent; */
|
||||
/* selection-background-color: darkgray;*/
|
||||
}</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
|
||||
<property name="frame">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="readOnly">
|
||||
<bool>true</bool>
|
||||
@ -861,18 +747,18 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" column="2">
|
||||
<item row="7" column="0">
|
||||
<widget class="QLabel" name="RxAFCLabel">
|
||||
<property name="text">
|
||||
<string>Rx AFC</string>
|
||||
<string>AFC Corr.</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" column="3">
|
||||
<widget class="QLineEdit" name="RxAFC">
|
||||
<item row="7" column="1">
|
||||
<widget class="QLineEdit" name="AFCCorrection">
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>101</width>
|
||||
@ -900,7 +786,55 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="7" column="0">
|
||||
<item row="8" column="0">
|
||||
<widget class="QLabel" name="TXSeqLabel">
|
||||
<property name="text">
|
||||
<string>TX Seq. No.</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="8" column="1">
|
||||
<widget class="QLineEdit" name="TXSeq">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>101</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<weight>75</weight>
|
||||
<bold>true</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true">QLineEdit {
|
||||
border: none;
|
||||
border-radius: 1px;
|
||||
padding: 0 4px;
|
||||
background: rgba(0, 0, 0, 16);
|
||||
/* background: transparent; */
|
||||
/* selection-background-color: darkgray;*/
|
||||
}</string>
|
||||
</property>
|
||||
<property name="frame">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="readOnly">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="9" column="0">
|
||||
<widget class="QLabel" name="TXRateLabel">
|
||||
<property name="text">
|
||||
<string>TX Rate (B/s)</string>
|
||||
@ -910,7 +844,7 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="7" column="1">
|
||||
<item row="9" column="1">
|
||||
<widget class="QLineEdit" name="TXRate">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
@ -948,7 +882,55 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="7" column="2">
|
||||
<item row="10" column="0">
|
||||
<widget class="QLabel" name="RXSeqLabel">
|
||||
<property name="text">
|
||||
<string>RX Seq. No.</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="10" column="1">
|
||||
<widget class="QLineEdit" name="RXSeq">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>101</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<weight>75</weight>
|
||||
<bold>true</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true">QLineEdit {
|
||||
border: none;
|
||||
border-radius: 1px;
|
||||
padding: 0 4px;
|
||||
background: rgba(0, 0, 0, 16);
|
||||
/* background: transparent; */
|
||||
/* selection-background-color: darkgray;*/
|
||||
}</string>
|
||||
</property>
|
||||
<property name="frame">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="readOnly">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="11" column="0">
|
||||
<widget class="QLabel" name="RXRateLabel">
|
||||
<property name="text">
|
||||
<string>RX Rate (B/s)</string>
|
||||
@ -958,7 +940,7 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="7" column="3">
|
||||
<item row="11" column="1">
|
||||
<widget class="QLineEdit" name="RXRate">
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
@ -990,20 +972,20 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="8" column="0">
|
||||
<widget class="QLabel" name="label_11">
|
||||
<item row="2" column="2">
|
||||
<widget class="QLabel" name="GoodLabel">
|
||||
<property name="text">
|
||||
<string>Link State</string>
|
||||
<string>RX Good</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="8" column="1">
|
||||
<widget class="QLineEdit" name="LinkState">
|
||||
<item row="2" column="3">
|
||||
<widget class="QLineEdit" name="Good">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
@ -1027,52 +1009,7 @@
|
||||
</font>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>The modems current state</string>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true">QLineEdit {
|
||||
border: none;
|
||||
border-radius: 1px;
|
||||
padding: 0 3px;
|
||||
background: rgba(0, 0, 0, 16);
|
||||
/* background: transparent; */
|
||||
/* selection-background-color: darkgray;*/
|
||||
}</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
<property name="readOnly">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="placeholderText">
|
||||
<string>Disconnected</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="8" column="2">
|
||||
<widget class="QLabel" name="LinkQualityLabel">
|
||||
<property name="text">
|
||||
<string>Link Quality</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="8" column="3">
|
||||
<widget class="QLineEdit" name="LinkQuality">
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>101</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<weight>75</weight>
|
||||
<bold>true</bold>
|
||||
</font>
|
||||
<string>The percentage of packets that were corrected with error correction</string>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true">QLineEdit {
|
||||
@ -1084,32 +1021,350 @@
|
||||
/* selection-background-color: darkgray;*/
|
||||
}</string>
|
||||
</property>
|
||||
<property name="frame">
|
||||
<bool>false</bool>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
<property name="readOnly">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="9" column="0">
|
||||
<widget class="QLabel" name="RetriesLabel">
|
||||
<item row="3" column="2">
|
||||
<widget class="QLabel" name="CorrectedLabel">
|
||||
<property name="text">
|
||||
<string>Retries</string>
|
||||
<string>RX Corrected</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="9" column="1">
|
||||
<widget class="QLineEdit" name="Retries">
|
||||
<item row="3" column="3">
|
||||
<widget class="QLineEdit" name="Corrected">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>101</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<weight>75</weight>
|
||||
<bold>true</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>The percentage of packets that were corrected with error correction</string>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true">QLineEdit {
|
||||
border: none;
|
||||
border-radius: 1px;
|
||||
padding: 0 4px;
|
||||
background: rgba(0, 0, 0, 16);
|
||||
/* background: transparent; */
|
||||
/* selection-background-color: darkgray;*/
|
||||
}</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
<property name="readOnly">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="2">
|
||||
<widget class="QLabel" name="ErrorsLabel">
|
||||
<property name="text">
|
||||
<string>RX Errors</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="3">
|
||||
<widget class="QLineEdit" name="Errors">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>101</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<weight>75</weight>
|
||||
<bold>true</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>The percentage of packets that could not be corrected with error correction</string>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true">QLineEdit {
|
||||
border: none;
|
||||
border-radius: 1px;
|
||||
padding: 0 4px;
|
||||
background: rgba(0, 0, 0, 16);
|
||||
/* background: transparent; */
|
||||
/* selection-background-color: darkgray;*/
|
||||
}</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
<property name="readOnly">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="2">
|
||||
<widget class="QLabel" name="MissedPacketsLabel">
|
||||
<property name="text">
|
||||
<string>RX Missed</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="3">
|
||||
<widget class="QLineEdit" name="Missed">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>101</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<weight>75</weight>
|
||||
<bold>true</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>The percentage of packets that were not received at all</string>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true">QLineEdit {
|
||||
border: none;
|
||||
border-radius: 1px;
|
||||
padding: 0 4px;
|
||||
background: rgba(0, 0, 0, 16);
|
||||
/* background: transparent; */
|
||||
/* selection-background-color: darkgray;*/
|
||||
}</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
<property name="readOnly">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" column="2">
|
||||
<widget class="QLabel" name="RxFailureLabel">
|
||||
<property name="text">
|
||||
<string>RX Failure</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" column="3">
|
||||
<widget class="QLineEdit" name="RxFailure">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>101</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<weight>75</weight>
|
||||
<bold>true</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>The percentage of packets that were not received at all</string>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true">QLineEdit {
|
||||
border: none;
|
||||
border-radius: 1px;
|
||||
padding: 0 4px;
|
||||
background: rgba(0, 0, 0, 16);
|
||||
/* background: transparent; */
|
||||
/* selection-background-color: darkgray;*/
|
||||
}</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
<property name="readOnly">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="7" column="2">
|
||||
<widget class="QLabel" name="DroppedLabel">
|
||||
<property name="text">
|
||||
<string>TX Dropped</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="7" column="3">
|
||||
<widget class="QLineEdit" name="Dropped">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>101</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<weight>75</weight>
|
||||
<bold>true</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>The number of packets that were unable to be transmitted</string>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true">QLineEdit {
|
||||
border: none;
|
||||
border-radius: 1px;
|
||||
padding: 0 4px;
|
||||
background: rgba(0, 0, 0, 16);
|
||||
/* background: transparent; */
|
||||
/* selection-background-color: darkgray;*/
|
||||
}</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
<property name="readOnly">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="8" column="2">
|
||||
<widget class="QLabel" name="ResentLabel">
|
||||
<property name="text">
|
||||
<string>TX Resent</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="8" column="3">
|
||||
<widget class="QLineEdit" name="Resent">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>101</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<weight>75</weight>
|
||||
<bold>true</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>The number of packets that were unable to be transmitted</string>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true">QLineEdit {
|
||||
border: none;
|
||||
border-radius: 1px;
|
||||
padding: 0 4px;
|
||||
background: rgba(0, 0, 0, 16);
|
||||
/* background: transparent; */
|
||||
/* selection-background-color: darkgray;*/
|
||||
}</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
<property name="readOnly">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="9" column="2">
|
||||
<widget class="QLabel" name="TxFailureLabel">
|
||||
<property name="text">
|
||||
<string>Tx Failure</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="9" column="3">
|
||||
<widget class="QLineEdit" name="TxFailure">
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>101</width>
|
||||
@ -1140,7 +1395,7 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="9" column="2">
|
||||
<item row="10" column="2">
|
||||
<widget class="QLabel" name="UAVTalkErrorsLabel">
|
||||
<property name="text">
|
||||
<string>UAVTalk Errors</string>
|
||||
@ -1150,7 +1405,7 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="9" column="3">
|
||||
<item row="10" column="3">
|
||||
<widget class="QLineEdit" name="UAVTalkErrors">
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
@ -1182,7 +1437,7 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="10" column="0">
|
||||
<item row="11" column="2">
|
||||
<widget class="QLabel" name="ResetsLabel">
|
||||
<property name="text">
|
||||
<string>Resets</string>
|
||||
@ -1192,7 +1447,7 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="10" column="1">
|
||||
<item row="11" column="3">
|
||||
<widget class="QLineEdit" name="Resets">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
@ -1230,18 +1485,18 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="10" column="2">
|
||||
<widget class="QLabel" name="DroppedLabel">
|
||||
<item row="12" column="2">
|
||||
<widget class="QLabel" name="TimeoutsLabel">
|
||||
<property name="text">
|
||||
<string>Dropped</string>
|
||||
<string>Timeouts</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="10" column="3">
|
||||
<widget class="QLineEdit" name="Dropped">
|
||||
<item row="12" column="3">
|
||||
<widget class="QLineEdit" name="Timeouts">
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>101</width>
|
||||
@ -1296,18 +1551,39 @@
|
||||
<string>Configuration</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_2">
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="TelemPortConfigLabel">
|
||||
<item row="0" column="1">
|
||||
<widget class="QCheckBox" name="Coordinator">
|
||||
<property name="text">
|
||||
<string>Coordinator</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QCheckBox" name="PPM">
|
||||
<property name="text">
|
||||
<string>PPM</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QCheckBox" name="UAVTalk">
|
||||
<property name="text">
|
||||
<string>UAVTalk</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="QLabel" name="InputConnectionLabel">
|
||||
<property name="text">
|
||||
<string>Telemetry Port Config.</string>
|
||||
<string>Input Connection</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QComboBox" name="TelemPortConfig">
|
||||
<item row="3" column="1">
|
||||
<widget class="QComboBox" name="InputConnection">
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>16777215</width>
|
||||
@ -1315,22 +1591,45 @@
|
||||
</size>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Set the telemetry port configuration</string>
|
||||
<string>Choose which port to communicate over on this modem</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="TelemPortSpeedLabel">
|
||||
<item row="4" column="0">
|
||||
<widget class="QLabel" name="OutputConnectionLabel">
|
||||
<property name="text">
|
||||
<string>Telemetry Port Speed</string>
|
||||
<string>Output Connection</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QComboBox" name="TelemPortSpeed">
|
||||
<item row="4" column="1">
|
||||
<widget class="QComboBox" name="OutputConnection">
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>16777215</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Choose which port to communicate over on the remote modem</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="0">
|
||||
<widget class="QLabel" name="ComSpeedLabel">
|
||||
<property name="text">
|
||||
<string>COM Speed</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="1">
|
||||
<widget class="QComboBox" name="ComSpeed">
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>16777215</width>
|
||||
@ -1342,122 +1641,7 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="FlexiPortConfigLabel">
|
||||
<property name="text">
|
||||
<string>Flexi Port Configuration</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QComboBox" name="FlexiPortConfig">
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>16777215</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Set the flexi port configuration</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="QLabel" name="FlexiPortSpeedConfig">
|
||||
<property name="text">
|
||||
<string>Flexi Port Speed</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="1">
|
||||
<widget class="QComboBox" name="FlexiPortSpeed">
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>16777215</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Set the flexi port speed</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="0">
|
||||
<widget class="QLabel" name="VCPConfigLabel">
|
||||
<property name="text">
|
||||
<string>VCP Configuration</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="1">
|
||||
<widget class="QComboBox" name="VCPConfig">
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>16777215</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Set the virtual serial port configuration</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="0">
|
||||
<widget class="QLabel" name="VCPSpeedLabel">
|
||||
<property name="text">
|
||||
<string>VCP Speed</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="1">
|
||||
<widget class="QComboBox" name="VCPSpeed">
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>16777215</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Set the virtual serial port speed</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" column="0">
|
||||
<widget class="QLabel" name="MaxRFDatarateLabel">
|
||||
<property name="text">
|
||||
<string>Max RF Datarate (bits/s)</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" column="1">
|
||||
<widget class="QComboBox" name="MaxRFDatarate">
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>16777215</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Set the maximum RF datarate/channel bandwidth the modem will use</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="7" column="0">
|
||||
<widget class="QLabel" name="MaxRFTxPowerLabel">
|
||||
<property name="text">
|
||||
<string>Max RF Tx Power(mW)</string>
|
||||
@ -1467,7 +1651,7 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="7" column="1">
|
||||
<item row="6" column="1">
|
||||
<widget class="QComboBox" name="MaxRFTxPower">
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
@ -1486,7 +1670,7 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="8" column="0">
|
||||
<item row="7" column="0">
|
||||
<widget class="QLabel" name="SendTimeoutLabel">
|
||||
<property name="text">
|
||||
<string>Send Timeout (ms)</string>
|
||||
@ -1496,7 +1680,7 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="8" column="1">
|
||||
<item row="7" column="1">
|
||||
<widget class="QSpinBox" name="SendTimeout">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||
@ -1511,7 +1695,7 @@
|
||||
</size>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Calibrate the modems RF carrier frequency</string>
|
||||
<string>Set the send timeout</string>
|
||||
</property>
|
||||
<property name="accelerated">
|
||||
<bool>true</bool>
|
||||
@ -1521,7 +1705,7 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="9" column="0">
|
||||
<item row="8" column="0">
|
||||
<widget class="QLabel" name="MinPacketSizeLabel">
|
||||
<property name="text">
|
||||
<string>Min Packet Size</string>
|
||||
@ -1531,7 +1715,7 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="9" column="1">
|
||||
<item row="8" column="1">
|
||||
<widget class="QSpinBox" name="MinPacketSize">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||
@ -1546,7 +1730,7 @@
|
||||
</size>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Calibrate the modems RF carrier frequency</string>
|
||||
<string>Set the minimum packet size</string>
|
||||
</property>
|
||||
<property name="accelerated">
|
||||
<bool>true</bool>
|
||||
@ -1556,7 +1740,7 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="10" column="0">
|
||||
<item row="9" column="0">
|
||||
<widget class="QLabel" name="FreqCalLabel">
|
||||
<property name="text">
|
||||
<string>Frequency Calibration</string>
|
||||
@ -1566,7 +1750,7 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="10" column="1">
|
||||
<item row="9" column="1">
|
||||
<widget class="QSpinBox" name="FrequencyCalibration">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||
@ -1591,18 +1775,18 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="11" column="0">
|
||||
<item row="10" column="0">
|
||||
<widget class="QLabel" name="label_5">
|
||||
<property name="text">
|
||||
<string>Frequency (Hz)</string>
|
||||
<string>Min. Frequency (Hz)</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="11" column="1">
|
||||
<widget class="QSpinBox" name="Frequency">
|
||||
<item row="10" column="1">
|
||||
<widget class="QSpinBox" name="MinFrequency">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
@ -1616,7 +1800,7 @@
|
||||
</size>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Set the modems RF carrier frequency</string>
|
||||
<string>Set the modems minimum RF carrier frequency</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
|
||||
@ -1625,7 +1809,7 @@
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="minimum">
|
||||
<number>0</number>
|
||||
<number>400000000</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>1000000000</number>
|
||||
@ -1635,7 +1819,51 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="15" column="0" colspan="2">
|
||||
<item row="11" column="0">
|
||||
<widget class="QLabel" name="MaxFrequencyLabel">
|
||||
<property name="text">
|
||||
<string>Max. Frequency (Hz)</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="11" column="1">
|
||||
<widget class="QSpinBox" name="MaxFrequency">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>16777215</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Set the modems maximum RF carrier frequency</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
<property name="accelerated">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="minimum">
|
||||
<number>400000000</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>1000000000</number>
|
||||
</property>
|
||||
<property name="singleStep">
|
||||
<number>100000</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="12" column="0" colspan="2">
|
||||
<widget class="QGroupBox" name="groupBox_4">
|
||||
<property name="title">
|
||||
<string>AES Encryption</string>
|
||||
@ -1704,7 +1932,7 @@
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="16" column="0">
|
||||
<item row="13" column="0">
|
||||
<spacer name="verticalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
@ -1717,16 +1945,6 @@
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="14" column="0" colspan="2">
|
||||
<widget class="QPushButton" name="ScanSpectrum">
|
||||
<property name="toolTip">
|
||||
<string>Scan whole band to see where their is interference and/or used channels</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string> Scan Spectrum </string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
@ -1747,9 +1965,6 @@
|
||||
<tabstop>FirmwareVersion</tabstop>
|
||||
<tabstop>SerialNumber</tabstop>
|
||||
<tabstop>DeviceID</tabstop>
|
||||
<tabstop>MinFrequency</tabstop>
|
||||
<tabstop>MaxFrequency</tabstop>
|
||||
<tabstop>FrequencyStepSize</tabstop>
|
||||
<tabstop>LinkState</tabstop>
|
||||
<tabstop>RxAFC</tabstop>
|
||||
<tabstop>Retries</tabstop>
|
||||
|
@ -4,9 +4,9 @@ Without the work of the people in this file OpenPilot would not be what it is to
|
||||
|
||||
<p>It is sorted alphabetically by name</p>
|
||||
|
||||
<pre>
|
||||
Connor Abbott
|
||||
<pre>Connor Abbott
|
||||
David Ankers
|
||||
Sergiy Anikeyev
|
||||
Pedro Assuncao
|
||||
Fredrik Arvidsson
|
||||
Werner Backes
|
||||
@ -16,6 +16,7 @@ David Carlson
|
||||
James Cotton
|
||||
Steve Doll
|
||||
Piotr Esden-Tempski
|
||||
Richard Flay
|
||||
Peter Farnworth
|
||||
Ed Faulkner
|
||||
Darren Furniss
|
||||
@ -23,6 +24,7 @@ Frederic Goddeeris
|
||||
Daniel Godin
|
||||
Bani Greyling
|
||||
Nuno Guedes
|
||||
Erik Gustavsson
|
||||
Peter Gunnarsson
|
||||
Dean Hall
|
||||
Joe Hlebasko
|
||||
@ -43,6 +45,7 @@ Ken Northup
|
||||
Greg Matthews
|
||||
Guy McCaldin
|
||||
Gary Mortimer
|
||||
Alessio Morale
|
||||
Cathy Moss
|
||||
Angus Peart
|
||||
Dmytro Poplavskiy
|
||||
@ -72,6 +75,7 @@ Brian Webb
|
||||
Justin Welander
|
||||
Mat Wellington
|
||||
Kendal Wells
|
||||
Dmitriy Zaitsev
|
||||
</pre>
|
||||
|
||||
</html>
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user