2012-02-25 15:37:05 +01:00
|
|
|
/**
|
2013-05-19 16:37:30 +02:00
|
|
|
******************************************************************************
|
2014-01-14 22:46:01 +01:00
|
|
|
|
2013-05-19 16:37:30 +02:00
|
|
|
* @addtogroup OpenPilotModules OpenPilot Modules
|
|
|
|
* @{
|
|
|
|
* @addtogroup RadioComBridgeModule Com Port to Radio Bridge Module
|
|
|
|
* @brief Bridge Com and Radio ports
|
|
|
|
* @{
|
|
|
|
*
|
|
|
|
* @file RadioComBridge.c
|
2013-06-15 22:50:13 +02:00
|
|
|
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2012-2013.
|
2013-05-19 16:37:30 +02:00
|
|
|
* @brief Bridges selected Com Port to the COM VCP emulated serial port
|
|
|
|
* @see The GNU Public License (GPL) Version 3
|
|
|
|
*
|
|
|
|
*****************************************************************************/
|
2012-02-25 15:37:05 +01:00
|
|
|
/*
|
|
|
|
* 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
|
|
|
|
*/
|
|
|
|
|
|
|
|
// ****************
|
|
|
|
|
2012-04-06 05:24:50 +02:00
|
|
|
#include <openpilot.h>
|
|
|
|
#include <radiocombridge.h>
|
2012-10-20 20:48:22 +02:00
|
|
|
#include <oplinkstatus.h>
|
2012-05-03 05:51:29 +02:00
|
|
|
#include <objectpersistence.h>
|
2012-10-20 20:48:22 +02:00
|
|
|
#include <oplinksettings.h>
|
2013-06-16 17:48:18 +02:00
|
|
|
#include <oplinkreceiver.h>
|
2014-01-06 21:35:00 +01:00
|
|
|
#include <radiocombridgestats.h>
|
2012-04-08 03:13:41 +02:00
|
|
|
#include <uavtalk_priv.h>
|
2012-04-11 05:22:53 +02:00
|
|
|
#include <pios_rfm22b.h>
|
2012-04-08 03:13:41 +02:00
|
|
|
#include <ecc.h>
|
2012-02-25 15:37:05 +01:00
|
|
|
|
|
|
|
#include <stdbool.h>
|
|
|
|
|
|
|
|
// ****************
|
|
|
|
// Private constants
|
|
|
|
|
2017-03-31 05:06:03 +02:00
|
|
|
#define TELEM_STACK_SIZE_WORDS 150
|
|
|
|
#define PPM_STACK_SIZE_WORDS 150
|
|
|
|
#define TASK_PRIORITY (tskIDLE_PRIORITY + 1)
|
|
|
|
#define MAX_RETRIES 2
|
|
|
|
#define RETRY_TIMEOUT_MS 20
|
|
|
|
#define EVENT_QUEUE_SIZE 10
|
|
|
|
#define MAX_PORT_DELAY 200
|
|
|
|
#define SERIAL_RX_BUF_LEN 100
|
|
|
|
#define PPM_INPUT_TIMEOUT 100
|
2012-05-02 04:14:58 +02:00
|
|
|
|
2014-01-06 21:35:00 +01:00
|
|
|
|
2012-02-25 15:37:05 +01:00
|
|
|
// ****************
|
|
|
|
// Private types
|
|
|
|
|
2012-06-30 19:06:01 +02:00
|
|
|
typedef struct {
|
2013-04-13 18:52:48 +02:00
|
|
|
// The task handles.
|
|
|
|
xTaskHandle telemetryTxTaskHandle;
|
2013-05-02 05:23:26 +02:00
|
|
|
xTaskHandle telemetryRxTaskHandle;
|
2017-03-31 05:06:03 +02:00
|
|
|
xTaskHandle telemRadioTxTaskHandle;
|
|
|
|
xTaskHandle telemRadioRxTaskHandle;
|
2013-06-16 17:48:18 +02:00
|
|
|
xTaskHandle PPMInputTaskHandle;
|
2012-03-16 03:29:54 +01:00
|
|
|
|
2013-04-13 18:52:48 +02:00
|
|
|
// The UAVTalk connection on the com side.
|
2013-06-15 22:50:13 +02:00
|
|
|
UAVTalkConnection telemUAVTalkCon;
|
|
|
|
UAVTalkConnection radioUAVTalkCon;
|
2012-03-16 03:29:54 +01:00
|
|
|
|
2013-04-13 18:52:48 +02:00
|
|
|
// Queue handles.
|
|
|
|
xQueueHandle uavtalkEventQueue;
|
2013-06-15 22:50:13 +02:00
|
|
|
xQueueHandle radioEventQueue;
|
2012-05-02 04:14:58 +02:00
|
|
|
|
2013-04-13 18:52:48 +02:00
|
|
|
// Error statistics.
|
2017-03-31 05:06:03 +02:00
|
|
|
uint32_t telemetryTxRetries;
|
|
|
|
uint32_t radioTxRetries;
|
2014-01-06 21:35:00 +01:00
|
|
|
|
|
|
|
// Is this modem the coordinator
|
2017-03-31 05:06:03 +02:00
|
|
|
bool isCoordinator;
|
2012-02-25 15:37:05 +01:00
|
|
|
} RadioComBridgeData;
|
|
|
|
|
2012-05-02 04:14:58 +02:00
|
|
|
// ****************
|
|
|
|
// Private functions
|
|
|
|
|
2012-10-20 20:48:22 +02:00
|
|
|
static void telemetryTxTask(void *parameters);
|
2013-05-02 05:23:26 +02:00
|
|
|
static void telemetryRxTask(void *parameters);
|
2017-03-31 05:06:03 +02:00
|
|
|
static void telemRadioTxTask(void *parameters);
|
|
|
|
static void telemRadioRxTask(void *parameters);
|
2013-06-16 17:48:18 +02:00
|
|
|
static void PPMInputTask(void *parameters);
|
2012-10-20 20:48:22 +02:00
|
|
|
static int32_t UAVTalkSendHandler(uint8_t *buf, int32_t length);
|
|
|
|
static int32_t RadioSendHandler(uint8_t *buf, int32_t length);
|
2015-03-11 00:54:02 +01:00
|
|
|
static void ProcessTelemetryStream(UAVTalkConnection inConnectionHandle, UAVTalkConnection outConnectionHandle, uint8_t *rxbuffer, uint8_t count);
|
|
|
|
static void ProcessRadioStream(UAVTalkConnection inConnectionHandle, UAVTalkConnection outConnectionHandle, uint8_t *rxbuffer, uint8_t count);
|
2013-06-15 22:50:13 +02:00
|
|
|
static void objectPersistenceUpdatedCb(UAVObjEvent *objEv);
|
2014-01-06 21:35:00 +01:00
|
|
|
static void registerObject(UAVObjHandle obj);
|
2012-05-02 04:14:58 +02:00
|
|
|
|
2012-02-25 15:37:05 +01:00
|
|
|
// ****************
|
|
|
|
// Private variables
|
|
|
|
|
|
|
|
static RadioComBridgeData *data;
|
|
|
|
|
|
|
|
/**
|
2013-06-15 22:50:13 +02:00
|
|
|
* @brief Start the module
|
2013-04-13 18:52:48 +02:00
|
|
|
*
|
|
|
|
* @return -1 if initialisation failed, 0 on success
|
2012-02-25 15:37:05 +01:00
|
|
|
*/
|
|
|
|
static int32_t RadioComBridgeStart(void)
|
|
|
|
{
|
2013-05-19 16:37:30 +02:00
|
|
|
if (data) {
|
|
|
|
// Get the settings.
|
|
|
|
OPLinkSettingsData oplinkSettings;
|
|
|
|
OPLinkSettingsGet(&oplinkSettings);
|
2014-01-06 21:35:00 +01:00
|
|
|
|
|
|
|
// Check if this is the coordinator modem
|
2015-12-31 00:45:02 +01:00
|
|
|
data->isCoordinator = (oplinkSettings.Protocol == OPLINKSETTINGS_PROTOCOL_OPLINKCOORDINATOR);
|
2013-04-06 02:32:15 +02:00
|
|
|
|
2013-05-04 18:24:40 +02:00
|
|
|
// 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 OPLINKSETTINGS_MAXRFPOWER_16:
|
|
|
|
PIOS_RFM22B_SetTxPower(pios_rfm22b_id, RFM22_tx_pwr_txpow_1);
|
|
|
|
break;
|
|
|
|
case OPLINKSETTINGS_MAXRFPOWER_316:
|
|
|
|
PIOS_RFM22B_SetTxPower(pios_rfm22b_id, RFM22_tx_pwr_txpow_2);
|
|
|
|
break;
|
|
|
|
case OPLINKSETTINGS_MAXRFPOWER_63:
|
|
|
|
PIOS_RFM22B_SetTxPower(pios_rfm22b_id, RFM22_tx_pwr_txpow_3);
|
|
|
|
break;
|
|
|
|
case OPLINKSETTINGS_MAXRFPOWER_126:
|
|
|
|
PIOS_RFM22B_SetTxPower(pios_rfm22b_id, RFM22_tx_pwr_txpow_4);
|
|
|
|
break;
|
|
|
|
case OPLINKSETTINGS_MAXRFPOWER_25:
|
|
|
|
PIOS_RFM22B_SetTxPower(pios_rfm22b_id, RFM22_tx_pwr_txpow_5);
|
|
|
|
break;
|
|
|
|
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;
|
|
|
|
default:
|
|
|
|
// do nothing
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2013-06-15 22:50:13 +02:00
|
|
|
// Configure our UAVObjects for updates.
|
|
|
|
UAVObjConnectQueue(UAVObjGetByID(OBJECTPERSISTENCE_OBJID), data->uavtalkEventQueue, EV_UPDATED | EV_UPDATED_MANUAL);
|
2014-01-06 21:35:00 +01:00
|
|
|
if (data->isCoordinator) {
|
2013-06-16 17:48:18 +02:00
|
|
|
UAVObjConnectQueue(UAVObjGetByID(OPLINKRECEIVER_OBJID), data->radioEventQueue, EV_UPDATED | EV_UPDATED_MANUAL | EV_UPDATE_REQ);
|
|
|
|
} else {
|
|
|
|
UAVObjConnectQueue(UAVObjGetByID(OPLINKRECEIVER_OBJID), data->uavtalkEventQueue, EV_UPDATED | EV_UPDATED_MANUAL | EV_UPDATE_REQ);
|
|
|
|
}
|
2016-07-09 23:57:22 +02:00
|
|
|
registerObject(OPLinkStatusHandle());
|
2013-06-16 17:48:18 +02:00
|
|
|
|
2014-01-06 21:35:00 +01:00
|
|
|
if (data->isCoordinator) {
|
|
|
|
registerObject(RadioComBridgeStatsHandle());
|
|
|
|
}
|
|
|
|
|
2013-06-16 17:48:18 +02:00
|
|
|
// Configure the UAVObject callbacks
|
|
|
|
ObjectPersistenceConnectCallback(&objectPersistenceUpdatedCb);
|
2013-04-06 02:32:15 +02:00
|
|
|
|
2013-02-18 02:49:13 +01:00
|
|
|
// Start the primary tasks for receiving/sending UAVTalk packets from the GCS.
|
2017-03-31 05:06:03 +02:00
|
|
|
// These tasks are always needed at least for configuration over HID.
|
|
|
|
xTaskCreate(telemetryTxTask, "telemetryTxTask", TELEM_STACK_SIZE_WORDS, NULL, TASK_PRIORITY, &(data->telemetryTxTaskHandle));
|
|
|
|
xTaskCreate(telemetryRxTask, "telemetryRxTask", TELEM_STACK_SIZE_WORDS, NULL, TASK_PRIORITY, &(data->telemetryRxTaskHandle));
|
|
|
|
#if defined(PIOS_INCLUDE_WDG) && defined(PIOS_WDG_TELEMETRYTX)
|
|
|
|
PIOS_WDG_RegisterFlag(PIOS_WDG_TELEMETRYTX);
|
2013-06-16 17:48:18 +02:00
|
|
|
#endif
|
2017-03-31 05:06:03 +02:00
|
|
|
#if defined(PIOS_INCLUDE_WDG) && defined(PIOS_WDG_TELEMETRYRX)
|
|
|
|
PIOS_WDG_RegisterFlag(PIOS_WDG_TELEMETRYRX);
|
|
|
|
#endif
|
|
|
|
// Start the tasks for sending/receiving telemetry over a radio link if a telemetry (GCS) link configured.
|
|
|
|
if (PIOS_COM_GCS_OUT) {
|
|
|
|
xTaskCreate(telemRadioTxTask, "telemRadioTxTask", TELEM_STACK_SIZE_WORDS, NULL, TASK_PRIORITY, &(data->telemRadioTxTaskHandle));
|
|
|
|
xTaskCreate(telemRadioRxTask, "telemRadioRxTask", TELEM_STACK_SIZE_WORDS, NULL, TASK_PRIORITY, &(data->telemRadioRxTaskHandle));
|
|
|
|
#if defined(PIOS_INCLUDE_WDG) && defined(PIOS_WDG_TELEMRADIOTX)
|
|
|
|
PIOS_WDG_RegisterFlag(PIOS_WDG_TELEMRADIOTX);
|
|
|
|
#endif
|
|
|
|
#if defined(PIOS_INCLUDE_WDG) && defined(PIOS_WDG_TELEMRADIORX)
|
|
|
|
PIOS_WDG_RegisterFlag(PIOS_WDG_TELEMRADIORX);
|
2013-06-26 05:54:35 +02:00
|
|
|
#endif
|
|
|
|
}
|
2013-02-18 02:49:13 +01:00
|
|
|
|
2017-03-31 05:06:03 +02:00
|
|
|
// Start the task for reading and processing PPM data if it's configured.
|
|
|
|
if (PIOS_PPM_RECEIVER) {
|
|
|
|
xTaskCreate(PPMInputTask, "PPMInputTask", PPM_STACK_SIZE_WORDS, NULL, TASK_PRIORITY, &(data->PPMInputTaskHandle));
|
|
|
|
#if defined(PIOS_INCLUDE_WDG) && defined(PIOS_WDG_PPMINPUT)
|
|
|
|
PIOS_WDG_RegisterFlag(PIOS_WDG_PPMINPUT);
|
2012-12-18 03:33:42 +01:00
|
|
|
#endif
|
2017-03-31 05:06:03 +02:00
|
|
|
}
|
|
|
|
|
2013-02-18 02:49:13 +01:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
return -1;
|
2012-02-25 15:37:05 +01:00
|
|
|
}
|
2012-03-16 03:29:54 +01:00
|
|
|
|
2012-02-25 15:37:05 +01:00
|
|
|
/**
|
2013-06-15 22:50:13 +02:00
|
|
|
* @brief Initialise the module
|
2013-04-13 18:52:48 +02:00
|
|
|
*
|
|
|
|
* @return -1 if initialisation failed on success
|
2012-02-25 15:37:05 +01:00
|
|
|
*/
|
|
|
|
static int32_t RadioComBridgeInitialize(void)
|
|
|
|
{
|
2013-04-13 18:52:48 +02:00
|
|
|
// allocate and initialize the static data storage only if module is enabled
|
2014-06-11 20:11:48 +02:00
|
|
|
data = (RadioComBridgeData *)pios_malloc(sizeof(RadioComBridgeData));
|
2013-04-13 18:52:48 +02:00
|
|
|
if (!data) {
|
|
|
|
return -1;
|
|
|
|
}
|
2012-02-25 15:37:05 +01:00
|
|
|
|
2013-04-13 18:52:48 +02:00
|
|
|
// Initialize the UAVObjects that we use
|
|
|
|
OPLinkStatusInitialize();
|
|
|
|
ObjectPersistenceInitialize();
|
2013-06-16 17:48:18 +02:00
|
|
|
OPLinkReceiverInitialize();
|
2014-01-06 21:35:00 +01:00
|
|
|
RadioComBridgeStatsInitialize();
|
2013-06-15 22:50:13 +02:00
|
|
|
|
2013-04-13 18:52:48 +02:00
|
|
|
// Initialise UAVTalk
|
2014-01-14 22:46:01 +01:00
|
|
|
data->telemUAVTalkCon = UAVTalkInitialize(&UAVTalkSendHandler);
|
|
|
|
data->radioUAVTalkCon = UAVTalkInitialize(&RadioSendHandler);
|
2012-04-18 02:36:05 +02:00
|
|
|
|
2013-04-13 18:52:48 +02:00
|
|
|
// Initialize the queues.
|
2014-01-14 22:46:01 +01:00
|
|
|
data->uavtalkEventQueue = xQueueCreate(EVENT_QUEUE_SIZE, sizeof(UAVObjEvent));
|
|
|
|
data->radioEventQueue = xQueueCreate(EVENT_QUEUE_SIZE, sizeof(UAVObjEvent));
|
2012-10-20 20:48:22 +02:00
|
|
|
|
2013-04-13 18:52:48 +02:00
|
|
|
// Initialize the statistics.
|
2014-01-14 22:46:01 +01:00
|
|
|
data->telemetryTxRetries = 0;
|
|
|
|
data->radioTxRetries = 0;
|
2014-01-06 21:35:00 +01:00
|
|
|
|
2013-04-13 18:52:48 +02:00
|
|
|
return 0;
|
2012-02-25 15:37:05 +01:00
|
|
|
}
|
2013-06-04 05:37:40 +02:00
|
|
|
MODULE_INITCALL(RadioComBridgeInitialize, RadioComBridgeStart);
|
2012-02-25 15:37:05 +01:00
|
|
|
|
2014-01-06 21:35:00 +01:00
|
|
|
|
|
|
|
// TODO this code (badly) duplicates code from telemetry.c
|
|
|
|
// This method should be used only for periodically updated objects.
|
|
|
|
// The register method defined in telemetry.c should be factored out in a shared location so it can be
|
|
|
|
// used from here...
|
|
|
|
static void registerObject(UAVObjHandle obj)
|
|
|
|
{
|
|
|
|
// Setup object for periodic updates
|
|
|
|
UAVObjEvent ev = {
|
2014-01-14 22:46:01 +01:00
|
|
|
.obj = obj,
|
|
|
|
.instId = UAVOBJ_ALL_INSTANCES,
|
|
|
|
.event = EV_UPDATED_PERIODIC,
|
2014-02-18 01:03:57 +01:00
|
|
|
.lowPriority = true,
|
2014-01-06 21:35:00 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
// Get metadata
|
|
|
|
UAVObjMetadata metadata;
|
2014-01-14 22:46:01 +01:00
|
|
|
|
2014-01-06 21:35:00 +01:00
|
|
|
UAVObjGetMetadata(obj, &metadata);
|
|
|
|
|
|
|
|
EventPeriodicQueueCreate(&ev, data->uavtalkEventQueue, metadata.telemetryUpdatePeriod);
|
|
|
|
UAVObjConnectQueue(obj, data->uavtalkEventQueue, EV_UPDATED_PERIODIC | EV_UPDATED_MANUAL | EV_UPDATE_REQ);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Update telemetry statistics
|
|
|
|
*/
|
|
|
|
static void updateRadioComBridgeStats()
|
|
|
|
{
|
|
|
|
UAVTalkStats telemetryUAVTalkStats;
|
|
|
|
UAVTalkStats radioUAVTalkStats;
|
|
|
|
RadioComBridgeStatsData radioComBridgeStats;
|
|
|
|
|
|
|
|
// Get telemetry stats
|
2014-03-04 09:56:42 +01:00
|
|
|
UAVTalkGetStats(data->telemUAVTalkCon, &telemetryUAVTalkStats, true);
|
2014-01-06 21:35:00 +01:00
|
|
|
|
|
|
|
// Get radio stats
|
2014-03-04 09:56:42 +01:00
|
|
|
UAVTalkGetStats(data->radioUAVTalkCon, &radioUAVTalkStats, true);
|
2014-01-06 21:35:00 +01:00
|
|
|
|
|
|
|
// Get stats object data
|
|
|
|
RadioComBridgeStatsGet(&radioComBridgeStats);
|
|
|
|
|
2014-04-01 22:58:23 +02:00
|
|
|
radioComBridgeStats.TelemetryTxRetries = data->telemetryTxRetries;
|
|
|
|
radioComBridgeStats.RadioTxRetries = data->radioTxRetries;
|
2014-03-04 09:51:45 +01:00
|
|
|
|
2014-01-06 21:35:00 +01:00
|
|
|
// Update stats object
|
2014-01-14 22:46:01 +01:00
|
|
|
radioComBridgeStats.TelemetryTxBytes += telemetryUAVTalkStats.txBytes;
|
|
|
|
radioComBridgeStats.TelemetryTxFailures += telemetryUAVTalkStats.txErrors;
|
2014-01-06 21:35:00 +01:00
|
|
|
|
2014-01-14 22:46:01 +01:00
|
|
|
radioComBridgeStats.TelemetryRxBytes += telemetryUAVTalkStats.rxBytes;
|
|
|
|
radioComBridgeStats.TelemetryRxFailures += telemetryUAVTalkStats.rxErrors;
|
2014-01-06 21:35:00 +01:00
|
|
|
radioComBridgeStats.TelemetryRxSyncErrors += telemetryUAVTalkStats.rxSyncErrors;
|
2014-01-14 22:46:01 +01:00
|
|
|
radioComBridgeStats.TelemetryRxCrcErrors += telemetryUAVTalkStats.rxCrcErrors;
|
2014-01-06 21:35:00 +01:00
|
|
|
|
2014-04-01 22:58:23 +02:00
|
|
|
radioComBridgeStats.RadioTxBytes += radioUAVTalkStats.txBytes;
|
|
|
|
radioComBridgeStats.RadioTxFailures += radioUAVTalkStats.txErrors;
|
2014-01-06 21:35:00 +01:00
|
|
|
|
2014-04-01 22:58:23 +02:00
|
|
|
radioComBridgeStats.RadioRxBytes += radioUAVTalkStats.rxBytes;
|
|
|
|
radioComBridgeStats.RadioRxFailures += radioUAVTalkStats.rxErrors;
|
|
|
|
radioComBridgeStats.RadioRxSyncErrors += radioUAVTalkStats.rxSyncErrors;
|
|
|
|
radioComBridgeStats.RadioRxCrcErrors += radioUAVTalkStats.rxCrcErrors;
|
2014-01-06 21:35:00 +01:00
|
|
|
|
|
|
|
// Update stats object data
|
|
|
|
RadioComBridgeStatsSet(&radioComBridgeStats);
|
|
|
|
}
|
|
|
|
|
2012-05-02 04:14:58 +02:00
|
|
|
/**
|
2017-03-31 05:06:03 +02:00
|
|
|
* @brief Reads the PPM input device and sends out OPLinkReceiver objects.
|
2013-04-13 18:52:48 +02:00
|
|
|
*
|
2017-03-31 05:06:03 +02:00
|
|
|
* @param[in] parameters The task parameters (unused)
|
|
|
|
*/
|
|
|
|
static void PPMInputTask(__attribute__((unused)) void *parameters)
|
|
|
|
{
|
|
|
|
xSemaphoreHandle sem = PIOS_RCVR_GetSemaphore(PIOS_PPM_RECEIVER, 1);
|
|
|
|
int16_t channels[RFM22B_PPM_NUM_CHANNELS];
|
|
|
|
|
|
|
|
while (1) {
|
|
|
|
#if defined(PIOS_INCLUDE_WDG) && defined(PIOS_WDG_PPMINPUT)
|
|
|
|
PIOS_WDG_UpdateFlag(PIOS_WDG_PPMINPUT);
|
|
|
|
#endif
|
|
|
|
|
|
|
|
// Wait for the receiver semaphore.
|
|
|
|
if (xSemaphoreTake(sem, PPM_INPUT_TIMEOUT) == pdTRUE) {
|
|
|
|
// Read the receiver inputs.
|
|
|
|
for (uint8_t i = 0; i < RFM22B_PPM_NUM_CHANNELS; ++i) {
|
|
|
|
channels[i] = PIOS_RCVR_Read(PIOS_PPM_RECEIVER, i + 1);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
// Failsafe
|
|
|
|
for (uint8_t i = 0; i < RFM22B_PPM_NUM_CHANNELS; ++i) {
|
|
|
|
channels[i] = PIOS_RCVR_INVALID;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Pass the channel values to the radio device.
|
|
|
|
PIOS_RFM22B_PPMSet(pios_rfm22b_id, channels, RFM22B_PPM_NUM_CHANNELS);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/****************************************************************************
|
|
|
|
* Telemetry tasks and functions
|
|
|
|
****************************************************************************/
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Receives events on the Radio->GCS telemetry stream and sends
|
|
|
|
* the requested object(s) to the GCS.
|
|
|
|
*
|
|
|
|
* @param[in] parameters None.
|
2012-05-02 04:14:58 +02:00
|
|
|
*/
|
2013-05-05 09:02:24 +02:00
|
|
|
static void telemetryTxTask(__attribute__((unused)) void *parameters)
|
2012-05-02 04:14:58 +02:00
|
|
|
{
|
2013-04-13 18:52:48 +02:00
|
|
|
UAVObjEvent ev;
|
2012-04-29 04:29:56 +02:00
|
|
|
|
2013-04-13 18:52:48 +02:00
|
|
|
// Loop forever
|
|
|
|
while (1) {
|
2017-03-31 05:06:03 +02:00
|
|
|
#if defined(PIOS_INCLUDE_WDG) && defined(PIOS_WDG_TELEMETRYTX)
|
2013-05-02 05:23:26 +02:00
|
|
|
PIOS_WDG_UpdateFlag(PIOS_WDG_TELEMETRYTX);
|
2012-12-18 03:33:42 +01:00
|
|
|
#endif
|
2013-04-13 18:52:48 +02:00
|
|
|
// Wait for queue message
|
|
|
|
if (xQueueReceive(data->uavtalkEventQueue, &ev, MAX_PORT_DELAY) == pdTRUE) {
|
2014-01-06 21:35:00 +01:00
|
|
|
if (ev.obj == RadioComBridgeStatsHandle()) {
|
|
|
|
updateRadioComBridgeStats();
|
|
|
|
}
|
|
|
|
// Send update (with retries)
|
2014-03-04 09:49:34 +01:00
|
|
|
int32_t ret = -1;
|
2014-01-06 21:35:00 +01:00
|
|
|
uint32_t retries = 0;
|
2014-03-04 09:49:34 +01:00
|
|
|
while (retries <= MAX_RETRIES && ret == -1) {
|
|
|
|
ret = UAVTalkSendObject(data->telemUAVTalkCon, ev.obj, ev.instId, 0, RETRY_TIMEOUT_MS);
|
|
|
|
if (ret == -1) {
|
2014-01-06 21:35:00 +01:00
|
|
|
++retries;
|
2013-04-13 18:52:48 +02:00
|
|
|
}
|
|
|
|
}
|
2014-01-06 21:35:00 +01:00
|
|
|
// Update stats
|
|
|
|
data->telemetryTxRetries += retries;
|
2013-04-13 18:52:48 +02:00
|
|
|
}
|
|
|
|
}
|
2012-02-25 15:37:05 +01:00
|
|
|
}
|
|
|
|
|
2012-03-16 03:29:54 +01:00
|
|
|
/**
|
2017-03-31 05:06:03 +02:00
|
|
|
* @brief Receives events on the GCS->Radio telemetry stream and sends
|
|
|
|
* the requested object(s) over the radio telenetry stream.
|
2013-04-13 18:52:48 +02:00
|
|
|
*
|
2017-03-31 05:06:03 +02:00
|
|
|
* @param[in] parameters none.
|
2012-03-16 03:29:54 +01:00
|
|
|
*/
|
2017-03-31 05:06:03 +02:00
|
|
|
static void telemRadioTxTask(__attribute__((unused)) void *parameters)
|
2012-02-25 15:37:05 +01:00
|
|
|
{
|
2013-04-13 18:52:48 +02:00
|
|
|
// Task loop
|
|
|
|
while (1) {
|
2017-03-31 05:06:03 +02:00
|
|
|
#if defined(PIOS_INCLUDE_WDG) && defined(PIOS_WDG_TELEMRADIOTX)
|
|
|
|
PIOS_WDG_UpdateFlag(PIOS_WDG_TELEMRADIOTX);
|
2012-12-18 03:33:42 +01:00
|
|
|
#endif
|
2013-05-02 05:42:16 +02:00
|
|
|
|
2013-06-15 22:50:13 +02:00
|
|
|
// Process the radio event queue, sending UAVObjects over the radio link as necessary.
|
|
|
|
UAVObjEvent ev;
|
2013-05-02 05:42:16 +02:00
|
|
|
|
2013-06-15 22:50:13 +02:00
|
|
|
// Wait for queue message
|
|
|
|
if (xQueueReceive(data->radioEventQueue, &ev, MAX_PORT_DELAY) == pdTRUE) {
|
|
|
|
if ((ev.event == EV_UPDATED) || (ev.event == EV_UPDATE_REQ)) {
|
|
|
|
// Send update (with retries)
|
2014-03-04 09:49:34 +01:00
|
|
|
int32_t ret = -1;
|
2013-06-15 22:50:13 +02:00
|
|
|
uint32_t retries = 0;
|
2014-03-04 09:49:34 +01:00
|
|
|
while (retries <= MAX_RETRIES && ret == -1) {
|
|
|
|
ret = UAVTalkSendObject(data->radioUAVTalkCon, ev.obj, ev.instId, 0, RETRY_TIMEOUT_MS);
|
|
|
|
if (ret == -1) {
|
2013-06-15 22:50:13 +02:00
|
|
|
++retries;
|
|
|
|
}
|
|
|
|
}
|
2014-01-06 21:35:00 +01:00
|
|
|
data->radioTxRetries += retries;
|
2013-06-15 22:50:13 +02:00
|
|
|
}
|
2013-04-13 18:52:48 +02:00
|
|
|
}
|
|
|
|
}
|
2012-02-25 15:37:05 +01:00
|
|
|
}
|
|
|
|
|
2012-05-21 03:30:37 +02:00
|
|
|
/**
|
2017-03-31 05:06:03 +02:00
|
|
|
* @brief Reads data from the radio telemetry port and processes it
|
|
|
|
* through the Radio->GCS telemetry stream.
|
2013-04-13 18:52:48 +02:00
|
|
|
*
|
|
|
|
* @param[in] parameters The task parameters
|
2012-05-21 03:30:37 +02:00
|
|
|
*/
|
2017-03-31 05:06:03 +02:00
|
|
|
static void telemRadioRxTask(__attribute__((unused)) void *parameters)
|
2012-05-21 03:30:37 +02:00
|
|
|
{
|
2013-04-13 18:52:48 +02:00
|
|
|
// Task loop
|
|
|
|
while (1) {
|
2017-03-31 05:06:03 +02:00
|
|
|
#if defined(PIOS_INCLUDE_WDG) && defined(PIOS_WDG_TELEMRADIORX)
|
|
|
|
PIOS_WDG_UpdateFlag(PIOS_WDG_TELEMRADIORX);
|
2012-12-18 03:33:42 +01:00
|
|
|
#endif
|
2017-03-31 05:06:03 +02:00
|
|
|
if (PIOS_COM_GCS_OUT) {
|
2015-03-11 00:54:02 +01:00
|
|
|
uint8_t serial_data[16];
|
2017-03-31 05:06:03 +02:00
|
|
|
uint16_t bytes_to_process = PIOS_COM_ReceiveBuffer(PIOS_COM_GCS_OUT, serial_data, sizeof(serial_data), MAX_PORT_DELAY);
|
2013-06-26 05:54:35 +02:00
|
|
|
if (bytes_to_process > 0) {
|
2017-03-31 05:06:03 +02:00
|
|
|
// Pass the data through the UAVTalk parser.
|
|
|
|
ProcessRadioStream(data->radioUAVTalkCon, data->telemUAVTalkCon, serial_data, bytes_to_process);
|
2013-05-02 05:42:16 +02:00
|
|
|
}
|
2013-06-26 05:54:35 +02:00
|
|
|
} else {
|
|
|
|
vTaskDelay(5);
|
2013-05-02 05:23:26 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2017-03-31 05:06:03 +02:00
|
|
|
* @brief Reads data from the GCS telemetry port and processes it
|
|
|
|
* through the GCS->Radio telemetry stream.
|
2013-05-02 05:23:26 +02:00
|
|
|
*
|
|
|
|
* @param[in] parameters The task parameters
|
|
|
|
*/
|
2013-05-05 09:02:24 +02:00
|
|
|
static void telemetryRxTask(__attribute__((unused)) void *parameters)
|
2013-05-02 05:23:26 +02:00
|
|
|
{
|
|
|
|
// Task loop
|
|
|
|
while (1) {
|
2017-03-31 05:06:03 +02:00
|
|
|
// uint32_t inputPort = data->parseUAVTalk ? PIOS_COM_TELEMETRY : 0;
|
|
|
|
uint32_t inputPort = PIOS_COM_GCS;
|
|
|
|
#if defined(PIOS_INCLUDE_WDG) && defined(PIOS_WDG_TELEMETRYRX)
|
2013-05-02 05:23:26 +02:00
|
|
|
PIOS_WDG_UpdateFlag(PIOS_WDG_TELEMETRYRX);
|
|
|
|
#endif
|
2012-10-20 20:48:22 +02:00
|
|
|
#if defined(PIOS_INCLUDE_USB)
|
2013-04-13 18:52:48 +02:00
|
|
|
// Determine output port (USB takes priority over telemetry port)
|
2017-03-31 05:06:03 +02:00
|
|
|
if (PIOS_USB_CheckAvailable(0) && PIOS_COM_HID) {
|
|
|
|
inputPort = PIOS_COM_HID;
|
2013-04-13 18:52:48 +02:00
|
|
|
}
|
2012-10-20 20:48:22 +02:00
|
|
|
#endif /* PIOS_INCLUDE_USB */
|
2013-05-19 16:37:30 +02:00
|
|
|
if (inputPort) {
|
2015-03-11 00:54:02 +01:00
|
|
|
uint8_t serial_data[16];
|
2013-04-13 18:52:48 +02:00
|
|
|
uint16_t bytes_to_process = PIOS_COM_ReceiveBuffer(inputPort, serial_data, sizeof(serial_data), MAX_PORT_DELAY);
|
|
|
|
if (bytes_to_process > 0) {
|
2015-03-11 00:54:02 +01:00
|
|
|
ProcessTelemetryStream(data->telemUAVTalkCon, data->radioUAVTalkCon, serial_data, bytes_to_process);
|
2013-04-13 18:52:48 +02:00
|
|
|
}
|
|
|
|
} else {
|
|
|
|
vTaskDelay(5);
|
|
|
|
}
|
|
|
|
}
|
2012-10-20 20:48:22 +02:00
|
|
|
}
|
2012-08-25 04:25:02 +02:00
|
|
|
|
2013-06-16 17:48:18 +02:00
|
|
|
/**
|
2017-03-31 05:06:03 +02:00
|
|
|
* @brief Send data from the Radio->GCS telemetry stream to the GCS port.
|
2013-04-13 18:52:48 +02:00
|
|
|
*
|
|
|
|
* @param[in] buf Data buffer to send
|
|
|
|
* @param[in] length Length of buffer
|
|
|
|
* @return -1 on failure
|
|
|
|
* @return number of bytes transmitted on success
|
2012-06-30 19:06:01 +02:00
|
|
|
*/
|
|
|
|
static int32_t UAVTalkSendHandler(uint8_t *buf, int32_t length)
|
|
|
|
{
|
2014-01-06 21:35:00 +01:00
|
|
|
int32_t ret;
|
2017-03-31 05:06:03 +02:00
|
|
|
uint32_t outputPort = PIOS_COM_GCS;
|
2013-05-19 16:37:30 +02:00
|
|
|
|
2012-10-20 20:48:22 +02:00
|
|
|
#if defined(PIOS_INCLUDE_USB)
|
2013-04-13 18:52:48 +02:00
|
|
|
// Determine output port (USB takes priority over telemetry port)
|
2017-03-31 05:06:03 +02:00
|
|
|
if (PIOS_COM_HID && PIOS_COM_Available(PIOS_COM_HID)) {
|
|
|
|
outputPort = PIOS_COM_HID;
|
2013-04-13 18:52:48 +02:00
|
|
|
}
|
2012-10-20 20:48:22 +02:00
|
|
|
#endif /* PIOS_INCLUDE_USB */
|
2013-05-19 16:37:30 +02:00
|
|
|
if (outputPort) {
|
2014-03-04 10:02:43 +01:00
|
|
|
// Following call can fail with -2 error code (buffer full) or -3 error code (could not acquire send mutex)
|
|
|
|
// It is the caller responsibility to retry in such cases...
|
2014-02-09 19:57:16 +01:00
|
|
|
ret = -2;
|
|
|
|
uint8_t count = 5;
|
2014-02-10 22:57:24 +01:00
|
|
|
while (count-- > 0 && ret < -1) {
|
2014-02-09 19:57:16 +01:00
|
|
|
ret = PIOS_COM_SendBufferNonBlocking(outputPort, buf, length);
|
|
|
|
}
|
2013-04-13 18:52:48 +02:00
|
|
|
} else {
|
2014-01-06 21:35:00 +01:00
|
|
|
ret = -1;
|
2013-04-13 18:52:48 +02:00
|
|
|
}
|
2014-01-06 21:35:00 +01:00
|
|
|
return ret;
|
2012-06-30 19:06:01 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2017-03-31 05:06:03 +02:00
|
|
|
* @brief Send data from the GCS telemetry stream to the Radio->GCS port.
|
2013-04-13 18:52:48 +02:00
|
|
|
*
|
|
|
|
* @param[in] buf Data buffer to send
|
|
|
|
* @param[in] length Length of buffer
|
|
|
|
* @return -1 on failure
|
|
|
|
* @return number of bytes transmitted on success
|
2012-06-30 19:06:01 +02:00
|
|
|
*/
|
2012-10-20 20:48:22 +02:00
|
|
|
static int32_t RadioSendHandler(uint8_t *buf, int32_t length)
|
2012-06-30 19:06:01 +02:00
|
|
|
{
|
2017-03-31 05:06:03 +02:00
|
|
|
uint32_t outputPort = PIOS_COM_GCS_OUT;
|
2013-05-19 16:37:30 +02:00
|
|
|
|
2013-02-18 02:49:13 +01:00
|
|
|
// Don't send any data unless the radio port is available.
|
2013-05-19 16:37:30 +02:00
|
|
|
if (outputPort && PIOS_COM_Available(outputPort)) {
|
2014-03-04 10:02:43 +01:00
|
|
|
// Following call can fail with -2 error code (buffer full) or -3 error code (could not acquire send mutex)
|
|
|
|
// It is the caller responsibility to retry in such cases...
|
2014-02-10 22:57:24 +01:00
|
|
|
int32_t ret = -2;
|
2014-02-09 19:57:16 +01:00
|
|
|
uint8_t count = 5;
|
2014-02-10 22:57:24 +01:00
|
|
|
while (count-- > 0 && ret < -1) {
|
2014-02-09 19:57:16 +01:00
|
|
|
ret = PIOS_COM_SendBufferNonBlocking(outputPort, buf, length);
|
|
|
|
}
|
|
|
|
return ret;
|
2013-02-18 02:49:13 +01:00
|
|
|
} else {
|
2014-01-06 21:35:00 +01:00
|
|
|
return -1;
|
2013-02-18 02:49:13 +01:00
|
|
|
}
|
2012-04-08 03:13:41 +02:00
|
|
|
}
|
|
|
|
|
2013-04-13 18:52:48 +02:00
|
|
|
/**
|
2013-06-15 22:50:13 +02:00
|
|
|
* @brief Process a byte of data received on the telemetry stream
|
2013-04-13 18:52:48 +02:00
|
|
|
*
|
2013-06-15 22:50:13 +02:00
|
|
|
* @param[in] inConnectionHandle The UAVTalk connection handle on the telemetry port
|
|
|
|
* @param[in] outConnectionHandle The UAVTalk connection handle on the radio port.
|
2013-04-13 18:52:48 +02:00
|
|
|
* @param[in] rxbyte The received byte.
|
|
|
|
*/
|
2015-03-14 14:39:02 +01:00
|
|
|
static void ProcessTelemetryStream(UAVTalkConnection inConnectionHandle, UAVTalkConnection outConnectionHandle, uint8_t *rxbuffer, uint8_t length)
|
2012-05-02 04:14:58 +02:00
|
|
|
{
|
2015-03-15 14:36:23 +01:00
|
|
|
uint8_t position = 0;
|
2015-03-11 00:54:02 +01:00
|
|
|
|
2013-04-13 18:52:48 +02:00
|
|
|
// Keep reading until we receive a completed packet.
|
2015-03-14 14:39:02 +01:00
|
|
|
while (position < length) {
|
2015-03-15 14:36:23 +01:00
|
|
|
UAVTalkRxState state = UAVTalkProcessInputStreamQuiet(inConnectionHandle, rxbuffer, length, &position);
|
2015-03-11 00:54:02 +01:00
|
|
|
if (state == UAVTALK_STATE_COMPLETE) {
|
|
|
|
// We only want to unpack certain telemetry objects
|
|
|
|
uint32_t objId = UAVTalkGetPacketObjId(inConnectionHandle);
|
|
|
|
switch (objId) {
|
|
|
|
case OPLINKSTATUS_OBJID:
|
|
|
|
case OPLINKSETTINGS_OBJID:
|
|
|
|
case OPLINKRECEIVER_OBJID:
|
|
|
|
case MetaObjectId(OPLINKSTATUS_OBJID):
|
|
|
|
case MetaObjectId(OPLINKSETTINGS_OBJID):
|
|
|
|
case MetaObjectId(OPLINKRECEIVER_OBJID):
|
|
|
|
UAVTalkReceiveObject(inConnectionHandle);
|
|
|
|
break;
|
|
|
|
case OBJECTPERSISTENCE_OBJID:
|
|
|
|
case MetaObjectId(OBJECTPERSISTENCE_OBJID):
|
|
|
|
// receive object locally
|
|
|
|
// some objects will send back a response to telemetry
|
|
|
|
// FIXME:
|
|
|
|
// OPLM will ack or nack all objects requests and acked object sends
|
|
|
|
// Receiver will probably also ack / nack the same messages
|
|
|
|
// This has some consequences like :
|
|
|
|
// Second ack/nack will not match an open transaction or will apply to wrong transaction
|
|
|
|
// Question : how does GCS handle receiving the same object twice
|
|
|
|
// The OBJECTPERSISTENCE logic can be broken too if for example OPLM nacks and then REVO acks...
|
|
|
|
UAVTalkReceiveObject(inConnectionHandle);
|
|
|
|
// relay packet to remote modem
|
|
|
|
UAVTalkRelayPacket(inConnectionHandle, outConnectionHandle);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
// all other packets are relayed to the remote modem
|
|
|
|
UAVTalkRelayPacket(inConnectionHandle, outConnectionHandle);
|
|
|
|
break;
|
|
|
|
}
|
2014-01-06 21:35:00 +01:00
|
|
|
}
|
2013-04-13 18:52:48 +02:00
|
|
|
}
|
2012-05-03 05:51:29 +02:00
|
|
|
}
|
2012-05-12 22:16:36 +02:00
|
|
|
|
2012-06-30 19:06:01 +02:00
|
|
|
/**
|
2013-06-15 22:50:13 +02:00
|
|
|
* @brief Process a byte of data received on the radio data stream.
|
2013-04-13 18:52:48 +02:00
|
|
|
*
|
2013-06-15 22:50:13 +02:00
|
|
|
* @param[in] inConnectionHandle The UAVTalk connection handle on the radio port.
|
|
|
|
* @param[in] outConnectionHandle The UAVTalk connection handle on the telemetry port.
|
2015-03-14 14:39:02 +01:00
|
|
|
* @param[in] rxbuffer The received buffer.
|
|
|
|
* @param[in] length buffer length
|
2012-11-26 03:40:49 +01:00
|
|
|
*/
|
2015-03-14 14:39:02 +01:00
|
|
|
static void ProcessRadioStream(UAVTalkConnection inConnectionHandle, UAVTalkConnection outConnectionHandle, uint8_t *rxbuffer, uint8_t length)
|
2012-11-26 03:40:49 +01:00
|
|
|
{
|
2015-03-14 13:46:08 +01:00
|
|
|
uint8_t position = 0;
|
2015-03-11 00:54:02 +01:00
|
|
|
|
2013-06-15 22:50:13 +02:00
|
|
|
// Keep reading until we receive a completed packet.
|
2015-03-14 14:39:02 +01:00
|
|
|
while (position < length) {
|
|
|
|
UAVTalkRxState state = UAVTalkProcessInputStreamQuiet(inConnectionHandle, rxbuffer, length, &position);
|
2015-03-11 00:54:02 +01:00
|
|
|
if (state == UAVTALK_STATE_COMPLETE) {
|
|
|
|
// We only want to unpack certain objects from the remote modem
|
|
|
|
// Similarly we only want to relay certain objects to the telemetry port
|
|
|
|
uint32_t objId = UAVTalkGetPacketObjId(inConnectionHandle);
|
|
|
|
switch (objId) {
|
|
|
|
case OPLINKSTATUS_OBJID:
|
|
|
|
case OPLINKSETTINGS_OBJID:
|
|
|
|
case MetaObjectId(OPLINKSTATUS_OBJID):
|
|
|
|
case MetaObjectId(OPLINKSETTINGS_OBJID):
|
|
|
|
// Ignore object...
|
|
|
|
// These objects are shadowed by the modem and are not transmitted to the telemetry port
|
|
|
|
// - OPLINKSTATUS_OBJID : ground station will receive the OPLM link status instead
|
|
|
|
// - OPLINKSETTINGS_OBJID : ground station will read and write the OPLM settings instead
|
|
|
|
break;
|
|
|
|
case OPLINKRECEIVER_OBJID:
|
|
|
|
case MetaObjectId(OPLINKRECEIVER_OBJID):
|
|
|
|
// Receive object locally
|
|
|
|
// These objects are received by the modem and are not transmitted to the telemetry port
|
|
|
|
// - OPLINKRECEIVER_OBJID : not sure why
|
|
|
|
// some objects will send back a response to the remote modem
|
|
|
|
UAVTalkReceiveObject(inConnectionHandle);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
// all other packets are relayed to the telemetry port
|
|
|
|
UAVTalkRelayPacket(inConnectionHandle, outConnectionHandle);
|
|
|
|
break;
|
|
|
|
}
|
2013-06-15 22:50:13 +02:00
|
|
|
}
|
2013-05-22 04:48:21 +02:00
|
|
|
}
|
2012-11-26 03:40:49 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2013-06-15 22:50:13 +02:00
|
|
|
* @brief Callback that is called when the ObjectPersistence UAVObject is changed.
|
|
|
|
* @param[in] objEv The event that precipitated the callback.
|
2012-05-12 22:16:36 +02:00
|
|
|
*/
|
2013-06-15 22:50:13 +02:00
|
|
|
static void objectPersistenceUpdatedCb(__attribute__((unused)) UAVObjEvent *objEv)
|
2012-05-12 22:16:36 +02:00
|
|
|
{
|
2013-06-15 22:50:13 +02:00
|
|
|
// Get the ObjectPersistence object.
|
|
|
|
ObjectPersistenceData obj_per;
|
|
|
|
|
|
|
|
ObjectPersistenceGet(&obj_per);
|
|
|
|
|
2014-01-06 21:35:00 +01:00
|
|
|
// Is this concerning our setting object?
|
2013-06-15 22:50:13 +02:00
|
|
|
if (obj_per.ObjectID == OPLINKSETTINGS_OBJID) {
|
|
|
|
// Is this a save, load, or delete?
|
2013-06-16 17:48:18 +02:00
|
|
|
bool success = false;
|
2013-06-15 22:50:13 +02:00
|
|
|
switch (obj_per.Operation) {
|
|
|
|
case OBJECTPERSISTENCE_OPERATION_LOAD:
|
|
|
|
{
|
|
|
|
#if defined(PIOS_INCLUDE_FLASH_LOGFS_SETTINGS)
|
|
|
|
// Load the settings.
|
|
|
|
void *obj = UAVObjGetByID(obj_per.ObjectID);
|
|
|
|
if (obj == 0) {
|
|
|
|
success = false;
|
|
|
|
} else {
|
|
|
|
// Load selected instance
|
|
|
|
success = (UAVObjLoad(obj, obj_per.InstanceID) == 0);
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case OBJECTPERSISTENCE_OPERATION_SAVE:
|
|
|
|
{
|
|
|
|
#if defined(PIOS_INCLUDE_FLASH_LOGFS_SETTINGS)
|
|
|
|
void *obj = UAVObjGetByID(obj_per.ObjectID);
|
|
|
|
if (obj == 0) {
|
|
|
|
success = false;
|
|
|
|
} else {
|
|
|
|
// Save selected instance
|
|
|
|
success = UAVObjSave(obj, obj_per.InstanceID) == 0;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case OBJECTPERSISTENCE_OPERATION_DELETE:
|
|
|
|
{
|
|
|
|
#if defined(PIOS_INCLUDE_FLASH_LOGFS_SETTINGS)
|
|
|
|
void *obj = UAVObjGetByID(obj_per.ObjectID);
|
|
|
|
if (obj == 0) {
|
|
|
|
success = false;
|
|
|
|
} else {
|
|
|
|
// Save selected instance
|
|
|
|
success = UAVObjDelete(obj, obj_per.InstanceID) == 0;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
if (success == true) {
|
|
|
|
obj_per.Operation = OBJECTPERSISTENCE_OPERATION_COMPLETED;
|
|
|
|
ObjectPersistenceSet(&obj_per);
|
|
|
|
}
|
2013-02-18 02:49:13 +01:00
|
|
|
}
|
2012-05-12 22:16:36 +02:00
|
|
|
}
|