1
0
mirror of https://bitbucket.org/librepilot/librepilot.git synced 2025-02-02 18:52:12 +01:00
Richard Flay (Hyper) a2d8544931 OP-931: adds -Wextra compiler option for the flight code, and makes the bazillion code changes required
to make the flight code compile again. Needs careful review, particularly all the fixes for the
signed vs unsigned comparisons.

+review OPReview-459
2013-05-05 16:32:24 +09:30

721 lines
25 KiB
C

/**
******************************************************************************
* @addtogroup OpenPilotModules OpenPilot Modules
* @{
* @addtogroup RadioComBridgeModule Com Port to Radio Bridge Module
* @brief Bridge Com and Radio ports
* @{
*
* @file RadioComBridge.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 <openpilot.h>
#include <radiocombridge.h>
#include <packet_handler.h>
#include <gcsreceiver.h>
#include <oplinkstatus.h>
#include <objectpersistence.h>
#include <oplinksettings.h>
#include <uavtalk_priv.h>
#include <pios_rfm22b.h>
#include <ecc.h>
#if defined(PIOS_INCLUDE_FLASH_EEPROM)
#include <pios_eeprom.h>
#endif
#include <stdbool.h>
// External functions
void PIOS_InitUartMainPort();
void PIOS_InitUartFlexiPort();
void PIOS_InitPPMMainPort(bool input);
void PIOS_InitPPMFlexiPort(bool input);
// ****************
// Private constants
#define STACK_SIZE_BYTES 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 EV_SEND_ACK 0x20
#define EV_SEND_NACK 0x30
// ****************
// Private types
typedef struct {
// The task handles.
xTaskHandle telemetryTxTaskHandle;
xTaskHandle telemetryRxTaskHandle;
xTaskHandle radioTxTaskHandle;
xTaskHandle radioRxTaskHandle;
// The UAVTalk connection on the com side.
UAVTalkConnection outUAVTalkCon;
UAVTalkConnection inUAVTalkCon;
// Queue handles.
xQueueHandle gcsEventQueue;
xQueueHandle uavtalkEventQueue;
// Error statistics.
uint32_t comTxErrors;
uint32_t comTxRetries;
uint32_t UAVTalkErrors;
uint32_t droppedPackets;
// Should we parse UAVTalk?
bool parseUAVTalk;
// We can only configure the hardware once.
bool configured;
// The current configured uart speed
OPLinkSettingsComSpeedOptions comSpeed;
} RadioComBridgeData;
// ****************
// Private functions
static void telemetryTxTask(void *parameters);
static void telemetryRxTask(void *parameters);
static void radioTxTask(void *parameters);
static void radioRxTask(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(OPLinkSettingsRemoteMainPortOptions main_port, OPLinkSettingsRemoteFlexiPortOptions flexi_port,
OPLinkSettingsRemoteVCPPortOptions vcp_port, OPLinkSettingsComSpeedOptions com_speed,
uint32_t min_frequency, uint32_t max_frequency, uint32_t channel_spacing);
static void updateSettings();
// ****************
// Private variables
static RadioComBridgeData *data;
/**
* Start the module
*
* @return -1 if initialisation failed, 0 on success
*/
static int32_t RadioComBridgeStart(void)
{
if(data) {
// Configure the com port configuration callback
PIOS_RFM22B_SetComConfigCallback(pios_rfm22b_id, &configureComCallback);
// Get the settings.
OPLinkSettingsData oplinkSettings;
OPLinkSettingsGet(&oplinkSettings);
// Set the baudrates, etc.
bool is_coordinator = PIOS_RFM22B_IsCoordinator(pios_rfm22b_id);
if (is_coordinator) {
// 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;
}
// Set the frequency range.
PIOS_RFM22B_SetFrequencyRange(pios_rfm22b_id, oplinkSettings.MinFrequency, oplinkSettings.MaxFrequency, oplinkSettings.ChannelSpacing);
// Reinitilize the modem.
PIOS_RFM22B_Reinit(pios_rfm22b_id);
// We will not parse/send UAVTalk if any ports are configured as Serial (except for over the USB HID port).
data->parseUAVTalk = ((oplinkSettings.MainPort != OPLINKSETTINGS_MAINPORT_SERIAL) &&
(oplinkSettings.FlexiPort != OPLINKSETTINGS_FLEXIPORT_SERIAL) &&
(oplinkSettings.VCPPort != OPLINKSETTINGS_VCPPORT_SERIAL));
}
// Set the initial frequency.
PIOS_RFM22B_SetInitialFrequency(pios_rfm22b_id, oplinkSettings.InitFrequency);
// Start the primary tasks for receiving/sending UAVTalk packets from the GCS.
xTaskCreate(telemetryTxTask, (signed char *)"telemetryTxTask", STACK_SIZE_BYTES, NULL, TASK_PRIORITY, &(data->telemetryTxTaskHandle));
xTaskCreate(telemetryRxTask, (signed char *)"telemetryRxTask", STACK_SIZE_BYTES, NULL, TASK_PRIORITY, &(data->telemetryRxTaskHandle));
xTaskCreate(radioTxTask, (signed char *)"radioTxTask", STACK_SIZE_BYTES, NULL, TASK_PRIORITY, &(data->radioTxTaskHandle));
xTaskCreate(radioRxTask, (signed char *)"radioRxTask", STACK_SIZE_BYTES, NULL, TASK_PRIORITY, &(data->radioRxTaskHandle));
// Register the watchdog timers.
#ifdef PIOS_INCLUDE_WDG
PIOS_WDG_RegisterFlag(PIOS_WDG_TELEMETRYTX);
PIOS_WDG_RegisterFlag(PIOS_WDG_TELEMETRYRX);
PIOS_WDG_RegisterFlag(PIOS_WDG_RADIOTX);
PIOS_WDG_RegisterFlag(PIOS_WDG_RADIORX);
#endif
return 0;
}
return -1;
}
/**
* Initialise the module
*
* @return -1 if initialisation failed on success
*/
static int32_t RadioComBridgeInitialize(void)
{
// allocate and initialize the static data storage only if module is enabled
data = (RadioComBridgeData *)pvPortMalloc(sizeof(RadioComBridgeData));
if (!data) {
return -1;
}
// Initialize the UAVObjects that we use
OPLinkStatusInitialize();
ObjectPersistenceInitialize();
// Initialise UAVTalk
data->outUAVTalkCon = UAVTalkInitialize(&UAVTalkSendHandler);
data->inUAVTalkCon = UAVTalkInitialize(&RadioSendHandler);
// Initialize the queues.
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);
#if defined(PIOS_INCLUDE_RFM22B_GCSRECEIVER)
UAVObjConnectQueue(UAVObjGetByID(GCSRECEIVER_OBJID), data->uavtalkEventQueue, EV_UPDATED | EV_UPDATED_MANUAL | EV_UPDATE_REQ);
#endif
// Initialize the statistics.
data->comTxErrors = 0;
data->comTxRetries = 0;
data->UAVTalkErrors = 0;
data->parseUAVTalk = true;
data->configured = false;
data->comSpeed = OPLINKSETTINGS_COMSPEED_9600;
PIOS_COM_RADIO = PIOS_COM_RFM22B;
return 0;
}
MODULE_INITCALL(RadioComBridgeInitialize, RadioComBridgeStart)
/**
* Telemetry transmit task, regular priority
*
* @param[in] parameters The task parameters
*/
static void telemetryTxTask(__attribute__((unused)) void *parameters)
{
UAVObjEvent ev;
// Loop forever
while (1) {
#ifdef PIOS_INCLUDE_WDG
PIOS_WDG_UpdateFlag(PIOS_WDG_TELEMETRYTX);
#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(data->outUAVTalkCon, ev.obj, 0, 0, RETRY_TIMEOUT_MS) == 0;
if (!success)
++retries;
}
data->comTxRetries += retries;
} else if(ev.event == EV_SEND_ACK) {
// Send the ACK
uint32_t retries = 0;
int32_t success = -1;
while (retries < MAX_RETRIES && success == -1) {
success = UAVTalkSendAck(data->outUAVTalkCon, ev.obj, ev.instId) == 0;
if (!success)
++retries;
}
data->comTxRetries += retries;
} else if(ev.event == EV_SEND_NACK) {
// Send the NACK
uint32_t retries = 0;
int32_t success = -1;
while (retries < MAX_RETRIES && success == -1) {
success = UAVTalkSendNack(data->outUAVTalkCon, UAVObjGetID(ev.obj)) == 0;
if (!success)
++retries;
}
data->comTxRetries += retries;
}
}
}
}
/**
* Radio tx task. Receive data packets from the com port and send to the radio.
*
* @param[in] parameters The task parameters
*/
static void radioTxTask(__attribute__((unused)) void *parameters)
{
// Task loop
while (1) {
#ifdef PIOS_INCLUDE_WDG
PIOS_WDG_UpdateFlag(PIOS_WDG_RADIOTX);
#endif
// Wait until the com port is available.
if (data->parseUAVTalk || !PIOS_COM_TELEMETRY) {
vTaskDelay(5);
continue;
}
// Read from the com port.
uint8_t serial_data[1];
uint16_t bytes_to_process = PIOS_COM_ReceiveBuffer(PIOS_COM_TELEMETRY, serial_data, sizeof(serial_data), MAX_PORT_DELAY);
if (bytes_to_process > 0) {
PIOS_COM_SendBufferNonBlocking(PIOS_COM_RADIO, serial_data, bytes_to_process);
}
}
}
/**
* Radio rx task. Receive data packets from the radio and pass them on.
*
* @param[in] parameters The task parameters
*/
static void radioRxTask(__attribute__((unused)) void *parameters)
{
// Task loop
while (1) {
#ifdef PIOS_INCLUDE_WDG
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) {
// Either pass the data through the UAVTalk parser, or just send it to the radio (if we're doing raw comms).
if (data->parseUAVTalk) {
for (uint8_t i = 0; i < bytes_to_process; i++) {
if (UAVTalkRelayInputStream(data->outUAVTalkCon, serial_data[i]) == UAVTALK_STATE_ERROR) {
data->UAVTalkErrors++;
}
}
} else if (PIOS_COM_TELEMETRY) {
PIOS_COM_SendBufferNonBlocking(PIOS_COM_TELEMETRY, serial_data, bytes_to_process);
}
}
}
}
/**
* Receive telemetry from the USB/COM port.
*
* @param[in] parameters The task parameters
*/
static void telemetryRxTask(__attribute__((unused)) void *parameters)
{
// Task loop
while (1) {
uint32_t inputPort = data->parseUAVTalk ? PIOS_COM_TELEMETRY : 0;
#ifdef PIOS_INCLUDE_WDG
PIOS_WDG_UpdateFlag(PIOS_WDG_TELEMETRYRX);
#endif
#if defined(PIOS_INCLUDE_USB)
// Determine output port (USB takes priority over telemetry port)
if (PIOS_USB_CheckAvailable(0) && PIOS_COM_TELEM_USB_HID) {
inputPort = PIOS_COM_TELEM_USB_HID;
}
#endif /* PIOS_INCLUDE_USB */
if(inputPort) {
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]);
}
} else {
vTaskDelay(5);
}
}
}
/**
* 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 UAVTalkSendHandler(uint8_t *buf, int32_t length)
{
uint32_t outputPort = data->parseUAVTalk ? PIOS_COM_TELEMETRY : 0;
#if defined(PIOS_INCLUDE_USB)
// Determine output port (USB takes priority over telemetry port)
if (PIOS_COM_TELEM_USB_HID && PIOS_COM_Available(PIOS_COM_TELEM_USB_HID)) {
outputPort = PIOS_COM_TELEM_USB_HID;
}
#endif /* PIOS_INCLUDE_USB */
if(outputPort) {
return PIOS_COM_SendBufferNonBlocking(outputPort, buf, length);
} else {
return -1;
}
}
/**
* 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 RadioSendHandler(uint8_t *buf, int32_t length)
{
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_SendBufferNonBlocking(outputPort, buf, length);
} else {
// For some reason, if this function returns failure, it prevents saving settings.
return length;
}
}
/**
* Process a byte of data received
*
* @param[in] connectionHandle The UAVTalk connection handle
* @param[in] rxbyte The received byte.
*/
static void ProcessInputStream(UAVTalkConnection connectionHandle, uint8_t rxbyte)
{
// Keep reading until we receive a completed packet.
UAVTalkRxState state = UAVTalkRelayInputStream(connectionHandle, rxbyte);
UAVTalkConnectionData *connection = (UAVTalkConnectionData*)(connectionHandle);
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 == OPLINKSETTINGS_OBJID) {
// Queue up the ACK.
queueEvent(data->uavtalkEventQueue, (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.
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;
}
}
}
} 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(data->uavtalkEventQueue, iproc->obj, iproc->instId, EV_SEND_NACK);
}
}
}
/**
* Queue and event into an event queue.
*
* @param[in] queue The event queue
* @param[in] obj The data pointer
* @param[in] type The event type
*/
static void queueEvent(xQueueHandle queue, void *obj, uint16_t instId, UAVObjEventType type)
{
UAVObjEvent ev;
ev.obj = (UAVObjHandle)obj;
ev.instId = instId;
ev.event = type;
xQueueSend(queue, &ev, portMAX_DELAY);
}
/**
* 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(OPLinkSettingsRemoteMainPortOptions main_port, OPLinkSettingsRemoteFlexiPortOptions flexi_port,
OPLinkSettingsRemoteVCPPortOptions vcp_port, OPLinkSettingsComSpeedOptions com_speed,
uint32_t min_frequency, uint32_t max_frequency, uint32_t channel_spacing)
{
// Update the com baud rate
data->comSpeed = com_speed;
// Set the output main/flexi/vcp port and speed.
bool is_coordinator = PIOS_RFM22B_IsCoordinator(pios_rfm22b_id);
if (!is_coordinator) {
// Get the settings.
OPLinkSettingsData oplinkSettings;
OPLinkSettingsGet(&oplinkSettings);
switch (main_port) {
case OPLINKSETTINGS_REMOTEMAINPORT_DISABLED:
oplinkSettings.MainPort = OPLINKSETTINGS_MAINPORT_DISABLED;
break;
case OPLINKSETTINGS_REMOTEMAINPORT_SERIAL:
oplinkSettings.MainPort = OPLINKSETTINGS_MAINPORT_SERIAL;
break;
case OPLINKSETTINGS_REMOTEMAINPORT_PPM:
oplinkSettings.MainPort = OPLINKSETTINGS_MAINPORT_PPM;
break;
}
switch (flexi_port) {
case OPLINKSETTINGS_REMOTEFLEXIPORT_DISABLED:
oplinkSettings.FlexiPort = OPLINKSETTINGS_FLEXIPORT_DISABLED;
break;
case OPLINKSETTINGS_REMOTEFLEXIPORT_SERIAL:
oplinkSettings.FlexiPort = OPLINKSETTINGS_FLEXIPORT_SERIAL;
break;
case OPLINKSETTINGS_REMOTEFLEXIPORT_PPM:
oplinkSettings.FlexiPort = OPLINKSETTINGS_FLEXIPORT_PPM;
break;
}
switch (vcp_port) {
case OPLINKSETTINGS_REMOTEVCPPORT_DISABLED:
oplinkSettings.VCPPort = OPLINKSETTINGS_VCPPORT_DISABLED;
break;
case OPLINKSETTINGS_REMOTEVCPPORT_SERIAL:
oplinkSettings.VCPPort = OPLINKSETTINGS_VCPPORT_SERIAL;
break;
}
// Set the frequency range.
PIOS_RFM22B_SetFrequencyRange(pios_rfm22b_id, min_frequency, max_frequency, channel_spacing);
// We will not parse/send UAVTalk if any ports are configured as Serial (except for over the USB HID port).
data->parseUAVTalk = ((oplinkSettings.MainPort != OPLINKSETTINGS_MAINPORT_SERIAL) &&
(oplinkSettings.FlexiPort != OPLINKSETTINGS_FLEXIPORT_SERIAL) &&
(oplinkSettings.VCPPort != OPLINKSETTINGS_VCPPORT_SERIAL));
// Update the OPLinkSettings object.
OPLinkSettingsSet(&oplinkSettings);
}
// Perform the update.
updateSettings();
}
/**
* Update the oplink settings.
*/
static void updateSettings()
{
// Get the settings.
OPLinkSettingsData oplinkSettings;
OPLinkSettingsGet(&oplinkSettings);
// We can only configure the hardware once.
if (data->configured) {
return;
}
data->configured = true;
// Configure the main port
bool is_coordinator = PIOS_RFM22B_IsCoordinator(pios_rfm22b_id);
switch (oplinkSettings.MainPort) {
case OPLINKSETTINGS_MAINPORT_TELEMETRY:
case OPLINKSETTINGS_MAINPORT_SERIAL:
/* Configure the main port for uart serial */
PIOS_InitUartMainPort();
PIOS_COM_TELEMETRY = PIOS_COM_TELEM_UART_MAIN;
break;
case OPLINKSETTINGS_MAINPORT_PPM:
PIOS_InitPPMMainPort(is_coordinator);
break;
case OPLINKSETTINGS_MAINPORT_DISABLED:
break;
}
// Configure the flexi port
switch (oplinkSettings.FlexiPort) {
case OPLINKSETTINGS_FLEXIPORT_TELEMETRY:
case OPLINKSETTINGS_FLEXIPORT_SERIAL:
/* Configure the flexi port as uart serial */
PIOS_InitUartFlexiPort();
PIOS_COM_TELEMETRY = PIOS_COM_TELEM_UART_FLEXI;
break;
case OPLINKSETTINGS_FLEXIPORT_PPM:
PIOS_InitPPMFlexiPort(is_coordinator);
break;
case OPLINKSETTINGS_FLEXIPORT_DISABLED:
break;
}
// Configure the USB VCP port
switch (oplinkSettings.VCPPort) {
case OPLINKSETTINGS_VCPPORT_SERIAL:
PIOS_COM_TELEMETRY = PIOS_COM_TELEM_USB_VCP;
break;
case OPLINKSETTINGS_VCPPORT_DISABLED:
break;
}
// Update the com baud rate.
uint32_t comBaud = 9600;
switch (data->comSpeed) {
case OPLINKSETTINGS_COMSPEED_2400:
comBaud = 2400;
break;
case OPLINKSETTINGS_COMSPEED_4800:
comBaud = 4800;
break;
case OPLINKSETTINGS_COMSPEED_9600:
comBaud = 9600;
break;
case OPLINKSETTINGS_COMSPEED_19200:
comBaud = 19200;
break;
case OPLINKSETTINGS_COMSPEED_38400:
comBaud = 38400;
break;
case OPLINKSETTINGS_COMSPEED_57600:
comBaud = 57600;
break;
case OPLINKSETTINGS_COMSPEED_115200:
comBaud = 115200;
break;
}
if (PIOS_COM_RADIO) {
PIOS_COM_ChangeBaud(PIOS_COM_RADIO, comBaud);
}
if (PIOS_COM_TELEMETRY) {
PIOS_COM_ChangeBaud(PIOS_COM_TELEMETRY, comBaud);
}
}