1
0
mirror of https://bitbucket.org/librepilot/librepilot.git synced 2024-12-01 09:24:10 +01:00

Merge branch 'next' into laurent/OP-1887_PFD_update

This commit is contained in:
Laurent Lalanne 2015-05-14 11:31:37 +02:00
commit 08536f3a01
23 changed files with 412 additions and 50 deletions

View File

@ -43,6 +43,7 @@
static void com2UsbBridgeTask(void *parameters);
static void usb2ComBridgeTask(void *parameters);
static void updateSettings(UAVObjEvent *ev);
static void usb2ComBridgeSetCtrlLine(uint32_t com_id, uint32_t mask, uint32_t state);
// ****************
// Private constants
@ -98,6 +99,14 @@ static int32_t comUsbBridgeInitialize(void)
usart_port = PIOS_COM_BRIDGE;
vcp_port = PIOS_COM_VCP;
// Register the call back handler for USB control line changes to simply
// pass these onto any handler registered on the USART
if (vcp_port) {
PIOS_COM_RegisterCtrlLineCallback(vcp_port,
usb2ComBridgeSetCtrlLine,
usart_port);
}
#ifdef MODULE_COMUSBBRIDGE_BUILTIN
bridge_enabled = true;
#else
@ -168,6 +177,14 @@ static void usb2ComBridgeTask(__attribute__((unused)) void *parameters)
}
}
/* This routine is registered with the USB driver and will be called in the
* event of a control line state change. It will then call down to the USART
* driver to drive the required control line state.
*/
static void usb2ComBridgeSetCtrlLine(uint32_t com_id, uint32_t mask, uint32_t state)
{
PIOS_COM_SetCtrlLine(com_id, mask, state);
}
static void updateSettings(__attribute__((unused)) UAVObjEvent *ev)
{

View File

@ -37,6 +37,7 @@
#include <manualcontrolsettings.h>
#include <manualcontrolcommand.h>
#include <receiveractivity.h>
#include <receiverstatus.h>
#include <flightstatus.h>
#include <flighttelemetrystats.h>
#ifndef PIOS_EXCLUDE_ADVANCED_FEATURES
@ -103,11 +104,16 @@ struct rcvr_activity_fsm {
ManualControlSettingsChannelGroupsOptions group;
uint16_t prev[RCVR_ACTIVITY_MONITOR_CHANNELS_PER_GROUP];
uint8_t sample_count;
uint8_t quality;
};
static struct rcvr_activity_fsm activity_fsm;
static void resetRcvrActivity(struct rcvr_activity_fsm *fsm);
static bool updateRcvrActivity(struct rcvr_activity_fsm *fsm);
static void resetRcvrStatus(struct rcvr_activity_fsm *fsm);
static bool updateRcvrStatus(
struct rcvr_activity_fsm *fsm,
ManualControlSettingsChannelGroupsOptions group);
#define assumptions \
( \
@ -143,6 +149,7 @@ int32_t ReceiverInitialize()
AccessoryDesiredInitialize();
ManualControlCommandInitialize();
ReceiverActivityInitialize();
ReceiverStatusInitialize();
ManualControlSettingsInitialize();
#ifndef PIOS_EXCLUDE_ADVANCED_FEATURES
StabilizationSettingsInitialize();
@ -208,6 +215,7 @@ static void receiverTask(__attribute__((unused)) void *parameters)
/* Initialize the RcvrActivty FSM */
portTickType lastActivityTime = xTaskGetTickCount();
resetRcvrActivity(&activity_fsm);
resetRcvrStatus(&activity_fsm);
// Main task loop
lastSysTime = xTaskGetTickCount();
@ -232,9 +240,13 @@ static void receiverTask(__attribute__((unused)) void *parameters)
/* Reset the aging timer because activity was detected */
lastActivityTime = lastSysTime;
}
/* Read signal quality from the group used for the throttle */
(void)updateRcvrStatus(&activity_fsm,
settings.ChannelGroups.Throttle);
}
if (timeDifferenceMs(lastActivityTime, lastSysTime) > 5000) {
resetRcvrActivity(&activity_fsm);
resetRcvrStatus(&activity_fsm);
lastActivityTime = lastSysTime;
}
@ -278,6 +290,10 @@ static void receiverTask(__attribute__((unused)) void *parameters)
}
}
/* Read signal quality from the group used for the throttle */
(void)updateRcvrStatus(&activity_fsm,
settings.ChannelGroups.Throttle);
// Sanity Check Throttle and Yaw
if (settings.ChannelGroups.Yaw >= MANUALCONTROLSETTINGS_CHANNELGROUPS_NONE
|| settings.ChannelGroups.Throttle >= MANUALCONTROLSETTINGS_CHANNELGROUPS_NONE
@ -568,6 +584,12 @@ static void resetRcvrActivity(struct rcvr_activity_fsm *fsm)
fsm->sample_count = 0;
}
static void resetRcvrStatus(struct rcvr_activity_fsm *fsm)
{
/* Reset the state */
fsm->quality = 0;
}
static void updateRcvrActivitySample(uint32_t rcvr_id, uint16_t samples[], uint8_t max_channels)
{
for (uint8_t channel = 1; channel <= max_channels; channel++) {
@ -641,6 +663,7 @@ static bool updateRcvrActivity(struct rcvr_activity_fsm *fsm)
if (fsm->group >= MANUALCONTROLSETTINGS_CHANNELGROUPS_NONE) {
/* We're out of range, reset things */
resetRcvrActivity(fsm);
resetRcvrStatus(fsm);
}
extern uint32_t pios_rcvr_group_map[];
@ -686,6 +709,32 @@ group_completed:
return activity_updated;
}
/* Read signal quality from the specified group */
static bool updateRcvrStatus(
struct rcvr_activity_fsm *fsm,
ManualControlSettingsChannelGroupsOptions group)
{
extern uint32_t pios_rcvr_group_map[];
bool activity_updated = false;
int8_t quality;
quality = PIOS_RCVR_GetQuality(pios_rcvr_group_map[group]);
/* If no driver is detected or any other error then return */
if (quality < 0) {
return activity_updated;
}
/* Compare with previous sample */
if (quality != fsm->quality) {
fsm->quality = quality;
ReceiverStatusQualitySet(&fsm->quality);
activity_updated = true;
}
return activity_updated;
}
/**
* Convert channel from servo pulse duration (microseconds) to scaled -1/+1 range.
*/

View File

@ -283,6 +283,56 @@ int32_t PIOS_COM_ChangeBaud(uint32_t com_id, uint32_t baud)
return 0;
}
/**
* Set control lines associated with the port
* \param[in] port COM port
* \param[in] mask Lines to change
* \param[in] state New state for lines
* \return -1 if port not available
* \return 0 on success
*/
int32_t PIOS_COM_SetCtrlLine(uint32_t com_id, uint32_t mask, uint32_t state)
{
struct pios_com_dev *com_dev = (struct pios_com_dev *)com_id;
if (!PIOS_COM_validate(com_dev)) {
/* Undefined COM port for this board (see pios_board.c) */
return -1;
}
/* Invoke the driver function if it exists */
if (com_dev->driver->set_ctrl_line) {
com_dev->driver->set_ctrl_line(com_dev->lower_id, mask, state);
}
return 0;
}
/**
* Set control lines associated with the port
* \param[in] port COM port
* \param[in] ctrl_line_cb Callback function
* \param[in] context context to pass to the callback function
* \return -1 if port not available
* \return 0 on success
*/
int32_t PIOS_COM_RegisterCtrlLineCallback(uint32_t com_id, pios_com_callback_ctrl_line ctrl_line_cb, uint32_t context)
{
struct pios_com_dev *com_dev = (struct pios_com_dev *)com_id;
if (!PIOS_COM_validate(com_dev)) {
/* Undefined COM port for this board (see pios_board.c) */
return -1;
}
/* Invoke the driver function if it exists */
if (com_dev->driver->bind_ctrl_line_cb) {
com_dev->driver->bind_ctrl_line_cb(com_dev->lower_id, ctrl_line_cb, context);
}
return 0;
}
static int32_t PIOS_COM_SendBufferNonBlockingInternal(struct pios_com_dev *com_dev, const uint8_t *buffer, uint16_t len)
{

View File

@ -34,6 +34,7 @@
#include <uavobjectmanager.h>
#include <oplinkreceiver.h>
#include <oplinkstatus.h>
#include <pios_oplinkrcvr_priv.h>
static OPLinkReceiverData oplinkreceiverdata;
@ -41,9 +42,11 @@ static OPLinkReceiverData oplinkreceiverdata;
/* Provide a RCVR driver */
static int32_t PIOS_OPLinkRCVR_Get(uint32_t rcvr_id, uint8_t channel);
static void PIOS_oplinkrcvr_Supervisor(uint32_t ppm_id);
static uint8_t PIOS_OPLinkRCVR_Quality_Get(uint32_t oplinkrcvr_id);
const struct pios_rcvr_driver pios_oplinkrcvr_rcvr_driver = {
.read = PIOS_OPLinkRCVR_Get,
.get_quality = PIOS_OPLinkRCVR_Quality_Get
};
/* Local Variables */
@ -186,6 +189,16 @@ static void PIOS_oplinkrcvr_Supervisor(uint32_t oplinkrcvr_id)
oplinkrcvr_dev->Fresh = false;
}
static uint8_t PIOS_OPLinkRCVR_Quality_Get(__attribute__((unused)) uint32_t oplinkrcvr_id)
{
uint8_t oplink_quality;
OPLinkStatusLinkQualityGet(&oplink_quality);
/* link_status is in the range 0-128, so scale to a % */
return oplink_quality * 100 / 128;
}
#endif /* PIOS_INCLUDE_OPLINKRCVR */
/**

View File

@ -113,6 +113,34 @@ int32_t PIOS_RCVR_Read(uint32_t rcvr_id, uint8_t channel)
return rcvr_dev->driver->read(rcvr_dev->lower_id, channel);
}
/**
* @brief Reads input quality from the appropriate driver
* @param[in] rcvr_id driver to read from
* @returns received signal quality expressed as a %
* @retval PIOS_RCVR_NODRIVER driver was not initialized
*/
uint8_t PIOS_RCVR_GetQuality(uint32_t rcvr_id)
{
if (rcvr_id == 0) {
return PIOS_RCVR_NODRIVER;
}
struct pios_rcvr_dev *rcvr_dev = (struct pios_rcvr_dev *)rcvr_id;
if (!PIOS_RCVR_validate(rcvr_dev)) {
/* Undefined RCVR port for this board (see pios_board.c) */
/* As no receiver is available assume min */
return 0;
}
if (!rcvr_dev->driver->get_quality) {
/* If no quality is available assume max */
return 100;
}
return rcvr_dev->driver->get_quality(rcvr_dev->lower_id);
}
/**
* @brief Get a semaphore that signals when a new sample is available.
* @param[in] rcvr_id driver to read from

View File

@ -32,6 +32,10 @@
#ifdef PIOS_INCLUDE_SBUS
// Define to report number of frames since last dropped instead of weighted ave
#undef SBUS_GOOD_FRAME_COUNT
#include <uavobjectmanager.h>
#include "pios_sbus_priv.h"
/* Forward Declarations */
@ -42,11 +46,12 @@ static uint16_t PIOS_SBus_RxInCallback(uint32_t context,
uint16_t *headroom,
bool *need_yield);
static void PIOS_SBus_Supervisor(uint32_t sbus_id);
static uint8_t PIOS_SBus_Quality_Get(uint32_t rcvr_id);
/* Local Variables */
const struct pios_rcvr_driver pios_sbus_rcvr_driver = {
.read = PIOS_SBus_Get,
.get_quality = PIOS_SBus_Quality_Get
};
enum pios_sbus_dev_magic {
@ -60,8 +65,17 @@ struct pios_sbus_state {
uint8_t failsafe_timer;
uint8_t frame_found;
uint8_t byte_count;
float quality;
#ifdef SBUS_GOOD_FRAME_COUNT
uint8_t frame_count;
#endif /* SBUS_GOOD_FRAME_COUNT */
};
/* With an S.Bus frame rate of 7ms (130Hz) averaging over 26 samples
* gives about a 200ms response.
*/
#define SBUS_FL_WEIGHTED_AVE 26
struct pios_sbus_dev {
enum pios_sbus_dev_magic magic;
const struct pios_sbus_cfg *cfg;
@ -120,6 +134,10 @@ static void PIOS_SBus_ResetState(struct pios_sbus_state *state)
state->receive_timer = 0;
state->failsafe_timer = 0;
state->frame_found = 0;
state->quality = 0.0f;
#ifdef SBUS_GOOD_FRAME_COUNT
state->frame_count = 0;
#endif /* SBUS_GOOD_FRAME_COUNT */
PIOS_SBus_ResetChannels(state);
}
@ -251,11 +269,29 @@ static void PIOS_SBus_UpdateState(struct pios_sbus_state *state, uint8_t b)
state->byte_count++;
} else {
if (b == SBUS_EOF_BYTE || (b & SBUS_R7008SB_EOF_COUNTER_MASK) == 0) {
#ifndef SBUS_GOOD_FRAME_COUNT
/* Quality trend is towards 0% by default*/
uint8_t quality_trend = 0;
#endif /* SBUS_GOOD_FRAME_COUNT */
/* full frame received */
uint8_t flags = state->received_data[SBUS_FRAME_LENGTH - 3];
if (flags & SBUS_FLAG_FL) {
/* frame lost, do not update */
} else if (flags & SBUS_FLAG_FS) {
#ifdef SBUS_GOOD_FRAME_COUNT
state->quality = state->frame_count;
state->frame_count = 0;
#endif /* SBUS_GOOD_FRAME_COUNT */
} else {
#ifdef SBUS_GOOD_FRAME_COUNT
if (++state->frame_count == 255) {
state->quality = state->frame_count--;
}
#else /* SBUS_GOOD_FRAME_COUNT */
/* Quality trend is towards 100% */
quality_trend = 100;
#endif /* SBUS_GOOD_FRAME_COUNT */
if (flags & SBUS_FLAG_FS) {
/* failsafe flag active */
PIOS_SBus_ResetChannels(state);
} else {
@ -263,6 +299,12 @@ static void PIOS_SBus_UpdateState(struct pios_sbus_state *state, uint8_t b)
PIOS_SBus_UnrollChannels(state);
state->failsafe_timer = 0;
}
}
#ifndef SBUS_GOOD_FRAME_COUNT
/* Present quality as a weighted average of good frames */
state->quality = ((state->quality * (SBUS_FL_WEIGHTED_AVE - 1)) +
quality_trend) / SBUS_FL_WEIGHTED_AVE;
#endif /* SBUS_GOOD_FRAME_COUNT */
} else {
/* discard whole frame */
}
@ -341,6 +383,19 @@ static void PIOS_SBus_Supervisor(uint32_t sbus_id)
}
}
static uint8_t PIOS_SBus_Quality_Get(uint32_t sbus_id)
{
struct pios_sbus_dev *sbus_dev = (struct pios_sbus_dev *)sbus_id;
bool valid = PIOS_SBus_Validate(sbus_dev);
PIOS_Assert(valid);
struct pios_sbus_state *state = &(sbus_dev->state);
return (uint8_t)(state->quality + 0.5f);
}
#endif /* PIOS_INCLUDE_SBUS */
/**

View File

@ -8,6 +8,7 @@
*
* @file pios_com.h
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
* Parts by Thorsten Klose (tk@midibox.org)
* @brief COM layer functions header
* @see The GNU Public License (GPL) Version 3
*
@ -35,19 +36,29 @@
#include <stdbool.h> /* bool */
typedef uint16_t (*pios_com_callback)(uint32_t context, uint8_t *buf, uint16_t buf_len, uint16_t *headroom, bool *task_woken);
typedef void (*pios_com_callback_ctrl_line)(uint32_t context, uint32_t mask, uint32_t state);
struct pios_com_driver {
void (*init)(uint32_t id);
void (*set_baud)(uint32_t id, uint32_t baud);
void (*set_ctrl_line)(uint32_t id, uint32_t mask, uint32_t state);
void (*tx_start)(uint32_t id, uint16_t tx_bytes_avail);
void (*rx_start)(uint32_t id, uint16_t rx_bytes_avail);
void (*bind_rx_cb)(uint32_t id, pios_com_callback rx_in_cb, uint32_t context);
void (*bind_tx_cb)(uint32_t id, pios_com_callback tx_out_cb, uint32_t context);
void (*bind_ctrl_line_cb)(uint32_t id, pios_com_callback_ctrl_line ctrl_line_cb, uint32_t context);
bool (*available)(uint32_t id);
};
/* Control line definitions */
#define COM_CTRL_LINE_DTR_MASK 0x01
#define COM_CTRL_LINE_RTS_MASK 0x02
/* Public Functions */
extern int32_t PIOS_COM_Init(uint32_t *com_id, const struct pios_com_driver *driver, uint32_t lower_id, uint8_t *rx_buffer, uint16_t rx_buffer_len, uint8_t *tx_buffer, uint16_t tx_buffer_len);
extern int32_t PIOS_COM_ChangeBaud(uint32_t com_id, uint32_t baud);
extern int32_t PIOS_COM_SetCtrlLine(uint32_t com_id, uint32_t mask, uint32_t state);
extern int32_t PIOS_COM_RegisterCtrlLineCallback(uint32_t usart_id, pios_com_callback_ctrl_line ctrl_line_cb, uint32_t context);
extern int32_t PIOS_COM_SendCharNonBlocking(uint32_t com_id, char c);
extern int32_t PIOS_COM_SendChar(uint32_t com_id, char c);
extern int32_t PIOS_COM_SendBufferNonBlocking(uint32_t com_id, const uint8_t *buffer, uint16_t len);

View File

@ -35,10 +35,12 @@ struct pios_rcvr_driver {
void (*init)(uint32_t id);
int32_t (*read)(uint32_t id, uint8_t channel);
xSemaphoreHandle (*get_semaphore)(uint32_t id, uint8_t channel);
uint8_t (*get_quality)(uint32_t id);
};
/* Public Functions */
extern int32_t PIOS_RCVR_Read(uint32_t rcvr_id, uint8_t channel);
extern uint8_t PIOS_RCVR_GetQuality(uint32_t rcvr_id);
extern xSemaphoreHandle PIOS_RCVR_GetSemaphore(uint32_t rcvr_id, uint8_t channel);
/*! Define error codes for PIOS_RCVR_Get */

View File

@ -44,6 +44,7 @@ struct pios_usart_cfg {
USART_InitTypeDef init;
struct stm32_gpio rx;
struct stm32_gpio tx;
struct stm32_gpio dtr;
struct stm32_irq irq;
};

View File

@ -34,9 +34,12 @@
#include "pios_dsm_priv.h"
// *** UNTESTED CODE ***
#undef DSM_LINK_QUALITY
/* Forward Declarations */
static int32_t PIOS_DSM_Get(uint32_t rcvr_id, uint8_t channel);
static uint8_t PIOS_DSM_Quality_Get(uint32_t rcvr_id);
static uint16_t PIOS_DSM_RxInCallback(uint32_t context,
uint8_t *buf,
uint16_t buf_len,
@ -47,6 +50,7 @@ static void PIOS_DSM_Supervisor(uint32_t dsm_id);
/* Local Variables */
const struct pios_rcvr_driver pios_dsm_rcvr_driver = {
.read = PIOS_DSM_Get,
.get_quality = PIOS_DSM_Quality_Get
};
enum pios_dsm_dev_magic {
@ -60,12 +64,15 @@ struct pios_dsm_state {
uint8_t failsafe_timer;
uint8_t frame_found;
uint8_t byte_count;
#ifdef DSM_LOST_FRAME_COUNTER
uint8_t frames_lost_last;
uint16_t frames_lost;
#endif
float quality;
};
/* With an DSM frame rate of 11ms (90Hz) averaging over 18 samples
* gives about a 200ms response.
*/
#define DSM_FL_WEIGHTED_AVE 18
struct pios_dsm_dev {
enum pios_dsm_dev_magic magic;
const struct pios_dsm_cfg *cfg;
@ -164,10 +171,8 @@ static void PIOS_DSM_ResetState(struct pios_dsm_dev *dsm_dev)
state->receive_timer = 0;
state->failsafe_timer = 0;
state->frame_found = 0;
#ifdef DSM_LOST_FRAME_COUNTER
state->quality = 0.0f;
state->frames_lost_last = 0;
state->frames_lost = 0;
#endif
PIOS_DSM_ResetChannels(dsm_dev);
}
@ -183,13 +188,24 @@ static int PIOS_DSM_UnrollChannels(struct pios_dsm_dev *dsm_dev)
static uint8_t resolution = 11;
uint32_t channel_log = 0;
#ifdef DSM_LOST_FRAME_COUNTER
// *** UNTESTED CODE ***
#ifdef DSM_LINK_QUALITY
/* increment the lost frame counter */
uint8_t frames_lost = state->received_data[0];
state->frames_lost += (frames_lost - state->frames_lost_last);
state->frames_lost_last = frames_lost;
#endif
/* We only get a lost frame count when the next good frame comes in */
/* Present quality as a weighted average of good frames */
/* First consider the bad frames */
for (int i = 0; i < frames_lost - state->frames_lost_last; i++) {
state->quality = (state->quality * (DSM_FL_WEIGHTED_AVE - 1)) /
DSM_FL_WEIGHTED_AVE;
}
/* And now the good frame */
state->quality = ((state->quality * (DSM_FL_WEIGHTED_AVE - 1)) +
100) / DSM_FL_WEIGHTED_AVE;
state->frames_lost_last = frames_lost;
#endif /* DSM_LINK_QUALITY */
/* unroll channels */
uint8_t *s = &(state->received_data[2]);
@ -238,11 +254,6 @@ static int PIOS_DSM_UnrollChannels(struct pios_dsm_dev *dsm_dev)
}
}
#ifdef DSM_LOST_FRAME_COUNTER
/* put lost frames counter into the last channel for debugging */
state->channel_data[PIOS_DSM_NUM_INPUTS - 1] = state->frames_lost;
#endif
/* all channels processed */
return 0;
@ -406,6 +417,19 @@ static void PIOS_DSM_Supervisor(uint32_t dsm_id)
}
}
static uint8_t PIOS_DSM_Quality_Get(uint32_t dsm_id)
{
struct pios_dsm_dev *dsm_dev = (struct pios_dsm_dev *)dsm_id;
bool valid = PIOS_DSM_Validate(dsm_dev);
PIOS_Assert(valid);
struct pios_dsm_state *state = &(dsm_dev->state);
return (uint8_t)(state->quality + 0.5f);
}
#endif /* PIOS_INCLUDE_DSM */
/**

View File

@ -34,12 +34,16 @@
#include "pios_dsm_priv.h"
// *** UNTESTED CODE ***
#undef DSM_LINK_QUALITY
#ifndef PIOS_INCLUDE_RTC
#error PIOS_INCLUDE_RTC must be used to use DSM
#endif
/* Forward Declarations */
static int32_t PIOS_DSM_Get(uint32_t rcvr_id, uint8_t channel);
static uint8_t PIOS_DSM_Quality_Get(uint32_t rcvr_id);
static uint16_t PIOS_DSM_RxInCallback(uint32_t context,
uint8_t *buf,
uint16_t buf_len,
@ -50,6 +54,7 @@ static void PIOS_DSM_Supervisor(uint32_t dsm_id);
/* Local Variables */
const struct pios_rcvr_driver pios_dsm_rcvr_driver = {
.read = PIOS_DSM_Get,
.get_quality = PIOS_DSM_Quality_Get
};
enum pios_dsm_dev_magic {
@ -63,12 +68,15 @@ struct pios_dsm_state {
uint8_t failsafe_timer;
uint8_t frame_found;
uint8_t byte_count;
#ifdef DSM_LOST_FRAME_COUNTER
uint8_t frames_lost_last;
uint16_t frames_lost;
#endif
float quality;
};
/* With an DSM frame rate of 11ms (90Hz) averaging over 18 samples
* gives about a 200ms response.
*/
#define DSM_FL_WEIGHTED_AVE 18
struct pios_dsm_dev {
enum pios_dsm_dev_magic magic;
const struct pios_dsm_cfg *cfg;
@ -167,10 +175,8 @@ static void PIOS_DSM_ResetState(struct pios_dsm_dev *dsm_dev)
state->receive_timer = 0;
state->failsafe_timer = 0;
state->frame_found = 0;
#ifdef DSM_LOST_FRAME_COUNTER
state->quality = 0.0f;
state->frames_lost_last = 0;
state->frames_lost = 0;
#endif
PIOS_DSM_ResetChannels(dsm_dev);
}
@ -186,12 +192,24 @@ static int PIOS_DSM_UnrollChannels(struct pios_dsm_dev *dsm_dev)
static uint8_t resolution = 11;
uint32_t channel_log = 0;
#ifdef DSM_LOST_FRAME_COUNTER
// *** UNTESTED CODE ***
#ifdef DSM_LINK_QUALITY
/* increment the lost frame counter */
uint8_t frames_lost = state->received_data[0];
state->frames_lost += (frames_lost - state->frames_lost_last);
/* We only get a lost frame count when the next good frame comes in */
/* Present quality as a weighted average of good frames */
/* First consider the bad frames */
for (int i = 0; i < frames_lost - state->frames_lost_last; i++) {
state->quality = (state->quality * (DSM_FL_WEIGHTED_AVE - 1)) /
DSM_FL_WEIGHTED_AVE;
}
/* And now the good frame */
state->quality = ((state->quality * (DSM_FL_WEIGHTED_AVE - 1)) +
100) / DSM_FL_WEIGHTED_AVE;
state->frames_lost_last = frames_lost;
#endif
#endif /* DSM_LINK_QUALITY */
/* unroll channels */
uint8_t *s = &(state->received_data[2]);
@ -240,11 +258,6 @@ static int PIOS_DSM_UnrollChannels(struct pios_dsm_dev *dsm_dev)
}
}
#ifdef DSM_LOST_FRAME_COUNTER
/* put lost frames counter into the last channel for debugging */
state->channel_data[PIOS_DSM_NUM_INPUTS - 1] = state->frames_lost;
#endif
/* all channels processed */
return 0;
@ -408,6 +421,19 @@ static void PIOS_DSM_Supervisor(uint32_t dsm_id)
}
}
static uint8_t PIOS_DSM_Quality_Get(uint32_t dsm_id)
{
struct pios_dsm_dev *dsm_dev = (struct pios_dsm_dev *)dsm_id;
bool valid = PIOS_DSM_Validate(dsm_dev);
PIOS_Assert(valid);
struct pios_dsm_state *state = &(dsm_dev->state);
return (uint8_t)(state->quality + 0.5f);
}
#endif /* PIOS_INCLUDE_DSM */
/**

View File

@ -40,6 +40,7 @@
/* Provide a COM driver */
static void PIOS_USART_ChangeBaud(uint32_t usart_id, uint32_t baud);
static void PIOS_USART_SetCtrlLine(uint32_t usart_id, uint32_t mask, uint32_t state);
static void PIOS_USART_RegisterRxCallback(uint32_t usart_id, pios_com_callback rx_in_cb, uint32_t context);
static void PIOS_USART_RegisterTxCallback(uint32_t usart_id, pios_com_callback tx_out_cb, uint32_t context);
static void PIOS_USART_TxStart(uint32_t usart_id, uint16_t tx_bytes_avail);
@ -47,6 +48,7 @@ static void PIOS_USART_RxStart(uint32_t usart_id, uint16_t rx_bytes_avail);
const struct pios_com_driver pios_usart_com_driver = {
.set_baud = PIOS_USART_ChangeBaud,
.set_ctrl_line = PIOS_USART_SetCtrlLine,
.tx_start = PIOS_USART_TxStart,
.rx_start = PIOS_USART_RxStart,
.bind_tx_cb = PIOS_USART_RegisterTxCallback,
@ -189,6 +191,12 @@ int32_t PIOS_USART_Init(uint32_t *usart_id, const struct pios_usart_cfg *cfg)
GPIO_Init(usart_dev->cfg->rx.gpio, (GPIO_InitTypeDef *)&usart_dev->cfg->rx.init);
GPIO_Init(usart_dev->cfg->tx.gpio, (GPIO_InitTypeDef *)&usart_dev->cfg->tx.init);
/* If a DTR line is specified, initialize it */
if (usart_dev->cfg->dtr.gpio) {
GPIO_Init(usart_dev->cfg->dtr.gpio, (GPIO_InitTypeDef *)&usart_dev->cfg->dtr.init);
PIOS_USART_SetCtrlLine((uint32_t)usart_dev, COM_CTRL_LINE_DTR_MASK, 0);
}
/* Configure the USART */
USART_Init(usart_dev->cfg->regs, (USART_InitTypeDef *)&usart_dev->cfg->init);
@ -276,6 +284,22 @@ static void PIOS_USART_ChangeBaud(uint32_t usart_id, uint32_t baud)
USART_Init(usart_dev->cfg->regs, &USART_InitStructure);
}
static void PIOS_USART_SetCtrlLine(uint32_t usart_id, uint32_t mask, uint32_t state)
{
struct pios_usart_dev *usart_dev = (struct pios_usart_dev *)usart_id;
bool valid = PIOS_USART_validate(usart_dev);
PIOS_Assert(valid);
/* Only attempt to drive DTR if this USART has a GPIO line defined */
if (usart_dev->cfg->dtr.gpio && (mask & COM_CTRL_LINE_DTR_MASK)) {
GPIO_WriteBit(usart_dev->cfg->dtr.gpio,
usart_dev->cfg->dtr.init.GPIO_Pin,
state & COM_CTRL_LINE_DTR_MASK ? Bit_RESET : Bit_SET);
}
}
static void PIOS_USART_RegisterRxCallback(uint32_t usart_id, pios_com_callback rx_in_cb, uint32_t context)
{
struct pios_usart_dev *usart_dev = (struct pios_usart_dev *)usart_id;

View File

@ -40,6 +40,7 @@
/* Implement COM layer driver API */
static void PIOS_USB_CDC_RegisterTxCallback(uint32_t usbcdc_id, pios_com_callback tx_out_cb, uint32_t context);
static void PIOS_USB_CDC_RegisterRxCallback(uint32_t usbcdc_id, pios_com_callback rx_in_cb, uint32_t context);
static void PIOS_USB_CDC_RegisterCtrlLineCallback(uint32_t usbcdc_id, pios_com_callback_ctrl_line ctrl_line_cb, uint32_t context);
static void PIOS_USB_CDC_TxStart(uint32_t usbcdc_id, uint16_t tx_bytes_avail);
static void PIOS_USB_CDC_RxStart(uint32_t usbcdc_id, uint16_t rx_bytes_avail);
static bool PIOS_USB_CDC_Available(uint32_t usbcdc_id);
@ -49,6 +50,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,
.bind_ctrl_line_cb = PIOS_USB_CDC_RegisterCtrlLineCallback,
.available = PIOS_USB_CDC_Available,
};
@ -66,6 +68,8 @@ struct pios_usb_cdc_dev {
uint32_t rx_in_context;
pios_com_callback tx_out_cb;
uint32_t tx_out_context;
pios_com_callback_ctrl_line ctrl_line_cb;
uint32_t ctrl_line_context;
bool usb_ctrl_if_enabled;
bool usb_data_if_enabled;
@ -323,6 +327,23 @@ static void PIOS_USB_CDC_RegisterTxCallback(uint32_t usbcdc_id, pios_com_callbac
usb_cdc_dev->tx_out_cb = tx_out_cb;
}
static void PIOS_USB_CDC_RegisterCtrlLineCallback(uint32_t usbcdc_id, pios_com_callback_ctrl_line ctrl_line_cb, uint32_t context)
{
struct pios_usb_cdc_dev *usb_cdc_dev = (struct pios_usb_cdc_dev *)usbcdc_id;
bool valid = PIOS_USB_CDC_validate(usb_cdc_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
*/
usb_cdc_dev->ctrl_line_context = context;
usb_cdc_dev->ctrl_line_cb = ctrl_line_cb;
}
static bool PIOS_USB_CDC_CTRL_EP_IN_Callback(uint32_t usb_cdc_id, uint8_t epnum, uint16_t len);
static void PIOS_USB_CDC_CTRL_IF_Init(uint32_t usb_cdc_id)
@ -403,6 +424,11 @@ static bool PIOS_USB_CDC_CTRL_IF_Setup(uint32_t usb_cdc_id, struct usb_setup_req
break;
case USB_CDC_REQ_SET_CONTROL_LINE_STATE:
control_line_state = req->wValue;
if (usb_cdc_dev->ctrl_line_cb) {
(usb_cdc_dev->ctrl_line_cb)(usb_cdc_dev->ctrl_line_context,
0xff,
control_line_state);
}
break;
default:
/* Unhandled class request */

View File

@ -108,6 +108,7 @@ UAVOBJSRCFILENAMES += watchdogstatus
UAVOBJSRCFILENAMES += flightstatus
UAVOBJSRCFILENAMES += hwsettings
UAVOBJSRCFILENAMES += receiveractivity
UAVOBJSRCFILENAMES += receiverstatus
UAVOBJSRCFILENAMES += cameradesired
UAVOBJSRCFILENAMES += camerastabsettings
UAVOBJSRCFILENAMES += altitudeholdsettings

View File

@ -1159,6 +1159,17 @@ static const struct pios_usart_cfg pios_usart_rcvrport_cfg = {
},
},
.dtr = {
// FlexIO pin 9
.gpio = GPIOC,
.init = {
.GPIO_Pin = GPIO_Pin_8,
.GPIO_Speed = GPIO_Speed_25MHz,
.GPIO_Mode = GPIO_Mode_OUT,
.GPIO_OType = GPIO_OType_PP,
},
},
.tx = {
// * 7: PC6 = TIM8 CH1, USART6 TX
.gpio = GPIOC,

View File

@ -108,6 +108,7 @@ UAVOBJSRCFILENAMES += watchdogstatus
UAVOBJSRCFILENAMES += flightstatus
UAVOBJSRCFILENAMES += hwsettings
UAVOBJSRCFILENAMES += receiveractivity
UAVOBJSRCFILENAMES += receiverstatus
UAVOBJSRCFILENAMES += cameradesired
UAVOBJSRCFILENAMES += camerastabsettings
UAVOBJSRCFILENAMES += altitudeholdsettings

View File

@ -887,6 +887,9 @@ void PIOS_Board_Init(void)
case HWSETTINGS_RM_RCVRPORT_TELEMETRY:
PIOS_Board_configure_com(&pios_usart_rcvrport_cfg, PIOS_COM_TELEM_RF_RX_BUF_LEN, PIOS_COM_TELEM_RF_TX_BUF_LEN, &pios_usart_com_driver, &pios_com_telem_rf_id);
break;
case HWSETTINGS_RM_RCVRPORT_COMBRIDGE:
PIOS_Board_configure_com(&pios_usart_rcvrport_cfg, PIOS_COM_BRIDGE_RX_BUF_LEN, PIOS_COM_BRIDGE_TX_BUF_LEN, &pios_usart_com_driver, &pios_com_bridge_id);
break;
}
#if defined(PIOS_INCLUDE_GCSRCVR)

View File

@ -108,6 +108,7 @@ UAVOBJSRCFILENAMES += watchdogstatus
UAVOBJSRCFILENAMES += flightstatus
UAVOBJSRCFILENAMES += hwsettings
UAVOBJSRCFILENAMES += receiveractivity
UAVOBJSRCFILENAMES += receiverstatus
UAVOBJSRCFILENAMES += cameradesired
UAVOBJSRCFILENAMES += camerastabsettings
UAVOBJSRCFILENAMES += altitudeholdsettings

View File

@ -151,6 +151,12 @@ void ConfigRevoHWWidget::usbVCPPortChanged(int index)
m_ui->cbMain->model()->setData(m_ui->cbMain->model()->index(HwSettings::RM_MAINPORT_COMBRIDGE, 0),
!vcpComBridgeEnabled ? QVariant(0) : QVariant(1 | 32), Qt::UserRole - 1);
if (!vcpComBridgeEnabled && m_ui->cbRcvr->currentIndex() == HwSettings::RM_RCVRPORT_COMBRIDGE) {
m_ui->cbRcvr->setCurrentIndex(HwSettings::RM_RCVRPORT_DISABLED);
}
m_ui->cbRcvr->model()->setData(m_ui->cbRcvr->model()->index(HwSettings::RM_RCVRPORT_COMBRIDGE, 0),
!vcpComBridgeEnabled ? QVariant(0) : QVariant(1 | 32), Qt::UserRole - 1);
// _DEBUGCONSOLE modes are mutual exclusive
if (m_ui->cbUSBVCPFunction->currentIndex() == HwSettings::USB_VCPPORT_DEBUGCONSOLE) {
if (m_ui->cbMain->currentIndex() == HwSettings::RM_MAINPORT_DEBUGCONSOLE) {

View File

@ -117,6 +117,7 @@ HEADERS += \
$$UAVOBJECT_SYNTHETICS/hwsettings.h \
$$UAVOBJECT_SYNTHETICS/gcsreceiver.h \
$$UAVOBJECT_SYNTHETICS/receiveractivity.h \
$$UAVOBJECT_SYNTHETICS/receiverstatus.h \
$$UAVOBJECT_SYNTHETICS/attitudesettings.h \
$$UAVOBJECT_SYNTHETICS/txpidsettings.h \
$$UAVOBJECT_SYNTHETICS/cameradesired.h \
@ -229,6 +230,7 @@ SOURCES += \
$$UAVOBJECT_SYNTHETICS/hwsettings.cpp \
$$UAVOBJECT_SYNTHETICS/gcsreceiver.cpp \
$$UAVOBJECT_SYNTHETICS/receiveractivity.cpp \
$$UAVOBJECT_SYNTHETICS/receiverstatus.cpp \
$$UAVOBJECT_SYNTHETICS/attitudesettings.cpp \
$$UAVOBJECT_SYNTHETICS/txpidsettings.cpp \
$$UAVOBJECT_SYNTHETICS/cameradesired.cpp \

View File

@ -6,7 +6,7 @@
<field name="MaxPDOP" units="" type="float" elements="1" defaultvalue="3.5"/>
<!-- Ubx self configuration. Enable to allow the flight board to auto configure ubx GPS options,
store does AutoConfig and save GPS settings (i.e. to prevent issues if gps is power cycled) -->
<field name="UbxAutoConfig" units="" type="enum" elements="1" options="Disabled,Configure,ConfigureAndStore" defaultvalue="Configure"/>
<field name="UbxAutoConfig" units="" type="enum" elements="1" options="Disabled,Configure,ConfigureAndStore" defaultvalue="Disabled"/>
<!-- Ubx position update rate, -1 for auto -->
<field name="UbxRate" units="Hz" type="int8" elements="1" defaultvalue="5" />
<!-- Ubx dynamic model, see UBX datasheet for more details -->

View File

@ -12,7 +12,7 @@
<field name="RV_TelemetryPort" units="function" type="enum" elements="1" options="Disabled,Telemetry,ComAux,ComBridge" defaultvalue="Telemetry"/>
<field name="RV_GPSPort" units="function" type="enum" elements="1" options="Disabled,Telemetry,GPS,ComAux,ComBridge" defaultvalue="GPS"/>
<field name="RM_RcvrPort" units="function" type="enum" elements="1" options="Disabled,PWM,PPM,PPM+PWM,PPM+Telemetry,PPM+Outputs,Outputs,Telemetry" defaultvalue="PWM"/>
<field name="RM_RcvrPort" units="function" type="enum" elements="1" options="Disabled,PWM,PPM,PPM+PWM,PPM+Telemetry,PPM+Outputs,Outputs,Telemetry,ComBridge" defaultvalue="PWM"/>
<field name="RM_MainPort" units="function" type="enum" elements="1" options="Disabled,Telemetry,GPS,S.Bus,DSM,DebugConsole,ComBridge,OsdHk" defaultvalue="Disabled"/>
<field name="RM_FlexiPort" units="function" type="enum" elements="1" options="Disabled,Telemetry,GPS,I2C,DSM,SRXL,DebugConsole,ComBridge,OsdHk" defaultvalue="Disabled"/>

View File

@ -0,0 +1,11 @@
<xml>
<object name="ReceiverStatus" singleinstance="true" settings="false" category="System" priority="true">
<description>Receiver status.</description>
<field name="Quality" units="%" type="uint8" elements="1" defaultvalue="0"/>
<access gcs="readonly" flight="readwrite"/>
<telemetrygcs acked="false" updatemode="manual" period="0"/>
<telemetryflight acked="false" updatemode="periodic" period="1000"/>
<logging updatemode="manual" period="0"/>
</object>
</xml>