diff --git a/flight/modules/RadioComBridge/RadioComBridge.c b/flight/modules/RadioComBridge/RadioComBridge.c index 1cd712656..29fb53f16 100644 --- a/flight/modules/RadioComBridge/RadioComBridge.c +++ b/flight/modules/RadioComBridge/RadioComBridge.c @@ -551,11 +551,9 @@ static void ProcessTelemetryStream(UAVTalkConnection inConnectionHandle, UAVTalk 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); + UAVTalkReceiveObject(inConnectionHandle, true); break; case OBJECTPERSISTENCE_OBJID: case MetaObjectId(OBJECTPERSISTENCE_OBJID): @@ -568,7 +566,7 @@ static void ProcessTelemetryStream(UAVTalkConnection inConnectionHandle, UAVTalk // 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); + UAVTalkReceiveObject(inConnectionHandle, true); // relay packet to remote modem UAVTalkRelayPacket(inConnectionHandle, outConnectionHandle); break; @@ -616,7 +614,9 @@ static void ProcessRadioStream(UAVTalkConnection inConnectionHandle, UAVTalkConn // 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); + UAVTalkReceiveObject(inConnectionHandle, true); + // all other packets are relayed to the telemetry port + UAVTalkRelayPacket(inConnectionHandle, outConnectionHandle); break; default: // all other packets are relayed to the telemetry port diff --git a/flight/modules/UAVOMSPBridge/UAVOMSPBridge.c b/flight/modules/UAVOMSPBridge/UAVOMSPBridge.c index 841276623..d5d44a9a7 100644 --- a/flight/modules/UAVOMSPBridge/UAVOMSPBridge.c +++ b/flight/modules/UAVOMSPBridge/UAVOMSPBridge.c @@ -43,7 +43,7 @@ #include "gpspositionsensor.h" #include "manualcontrolcommand.h" #include "manualcontrolsettings.h" -#include "oplinkstatus.h" +#include "oplinkreceiver.h" #include "accessorydesired.h" #include "attitudestate.h" #include "airspeedstate.h" @@ -481,7 +481,7 @@ static void msp_send_analog(struct msp_bridge *m) #ifdef PIOS_INCLUDE_OPLINKRCVR if (channelGroups.Throttle == MANUALCONTROLSETTINGS_CHANNELGROUPS_OPLINK) { int8_t rssi; - OPLinkStatusRSSIGet(&rssi); + OPLinkReceiverRSSIGet(&rssi); // MSP values have no units, and OSD rssi display requires calibration anyway, so we will translate OPLINK_LOW_RSSI to OPLINK_HIGH_RSSI -> 0-1023 if (rssi < OPLINK_LOW_RSSI) { diff --git a/flight/modules/UAVOMavlinkBridge/UAVOMavlinkBridge.c b/flight/modules/UAVOMavlinkBridge/UAVOMavlinkBridge.c index ab834b7a3..664fa8c08 100644 --- a/flight/modules/UAVOMavlinkBridge/UAVOMavlinkBridge.c +++ b/flight/modules/UAVOMavlinkBridge/UAVOMavlinkBridge.c @@ -52,7 +52,7 @@ #include "taskinfo.h" #include "mavlink.h" #include "hwsettings.h" -#include "oplinkstatus.h" +#include "oplinkreceiver.h" #include "receiverstatus.h" #include "manualcontrolsettings.h" @@ -250,7 +250,7 @@ static void mavlink_send_rc_channels() #ifdef PIOS_INCLUDE_OPLINKRCVR if (channelGroups.Throttle == MANUALCONTROLSETTINGS_CHANNELGROUPS_OPLINK) { int8_t rssi; - OPLinkStatusRSSIGet(&rssi); + OPLinkReceiverRSSIGet(&rssi); if (rssi < OPLINK_LOW_RSSI) { rssi = OPLINK_LOW_RSSI; diff --git a/flight/pios/common/pios_board_io.c b/flight/pios/common/pios_board_io.c index 6da534b1c..441bad18f 100644 --- a/flight/pios/common/pios_board_io.c +++ b/flight/pios/common/pios_board_io.c @@ -54,14 +54,16 @@ # ifdef PIOS_INCLUDE_GCSRCVR # include # endif +# ifdef PIOS_INCLUDE_OPLINKRCVR +# include +# include +# endif #endif /* PIOS_INCLUDE_RCVR */ #ifdef PIOS_INCLUDE_RFM22B # include # include # ifdef PIOS_INCLUDE_RCVR -# include -# include # include # include # endif /* PIOS_INCLUDE_RCVR */ @@ -525,7 +527,7 @@ void PIOS_BOARD_IO_Configure_PPM_RCVR(const struct pios_ppm_cfg *ppm_cfg) } #endif /* PIOS_INCLUDE_PPM */ -#ifdef PIOS_INCLUDE_GCSRCVR +#if defined(PIOS_INCLUDE_GCSRCVR) void PIOS_BOARD_IO_Configure_GCS_RCVR() { GCSReceiverInitialize(); @@ -539,6 +541,24 @@ void PIOS_BOARD_IO_Configure_GCS_RCVR() } #endif /* PIOS_INCLUDE_GCSRCVR */ +#if defined(PIOS_INCLUDE_OPLINKRCVR) && defined(PIOS_INCLUDE_RCVR) +void PIOS_BOARD_IO_Configure_OPLink_RCVR() +{ + uint32_t pios_oplinkrcvr_id; + OPLinkReceiverInitialize(); +#if defined(PIOS_INCLUDE_RFM22B) + PIOS_OPLinkRCVR_Init(&pios_oplinkrcvr_id, pios_rfm22b_id); +#else /* PIOS_INCLUDE_RFM22B */ + PIOS_OPLinkRCVR_Init(&pios_oplinkrcvr_id); +#endif /* PIOS_INCLUDE_RFM22B */ + uint32_t pios_oplinkrcvr_rcvr_id; + if (PIOS_RCVR_Init(&pios_oplinkrcvr_rcvr_id, &pios_oplinkrcvr_rcvr_driver, pios_oplinkrcvr_id)) { + PIOS_Assert(0); + } + pios_rcvr_group_map[MANUALCONTROLSETTINGS_CHANNELGROUPS_OPLINK] = pios_oplinkrcvr_rcvr_id; +} +#endif /* PIOS_INCLUDE_OPLINKRCVR && PIOS_INCLUDE_RCVR */ + #ifdef PIOS_INCLUDE_RFM22B void PIOS_BOARD_IO_Configure_RFM22B() @@ -596,15 +616,6 @@ void PIOS_BOARD_IO_Configure_RFM22B() if (PIOS_RFM22B_Init(&pios_rfm22b_id, PIOS_SPI_RFM22B_ADAPTER, rfm22b_cfg->slave_num, rfm22b_cfg, oplinkSettings.RFBand)) { PIOS_Assert(0); } -#if defined(PIOS_INCLUDE_OPLINKRCVR) && defined(PIOS_INCLUDE_RCVR) - uint32_t pios_oplinkrcvr_id; - PIOS_OPLinkRCVR_Init(&pios_oplinkrcvr_id, pios_rfm22b_id); - uint32_t pios_oplinkrcvr_rcvr_id; - if (PIOS_RCVR_Init(&pios_oplinkrcvr_rcvr_id, &pios_oplinkrcvr_rcvr_driver, pios_oplinkrcvr_id)) { - PIOS_Assert(0); - } - pios_rcvr_group_map[MANUALCONTROLSETTINGS_CHANNELGROUPS_OPLINK] = pios_oplinkrcvr_rcvr_id; -#endif /* PIOS_INCLUDE_OPLINKRCVR && PIOS_INCLUDE_RCVR */ /* Configure the radio com interface */ if (PIOS_COM_Init(&pios_com_pri_radio_id, &pios_rfm22b_com_driver, pios_rfm22b_id, diff --git a/flight/pios/common/pios_oplinkrcvr.c b/flight/pios/common/pios_oplinkrcvr.c index a51b1b4ea..678e330c3 100644 --- a/flight/pios/common/pios_oplinkrcvr.c +++ b/flight/pios/common/pios_oplinkrcvr.c @@ -60,11 +60,14 @@ struct pios_oplinkrcvr_dev { bool Fresh; }; +static struct pios_oplinkrcvr_dev *global_oplinkrcvr_dev; + static bool PIOS_oplinkrcvr_validate(struct pios_oplinkrcvr_dev *oplinkrcvr_dev) { return oplinkrcvr_dev->magic == PIOS_OPLINKRCVR_DEV_MAGIC; } +#if defined(PIOS_INCLUDE_RFM22B) static void PIOS_oplinkrcvr_ppm_callback(uint32_t oplinkrcvr_id, const int16_t *channels) { /* Recover our device context */ @@ -78,10 +81,21 @@ static void PIOS_oplinkrcvr_ppm_callback(uint32_t oplinkrcvr_id, const int16_t * for (uint8_t i = 0; i < OPLINKRECEIVER_CHANNEL_NUMELEM; ++i) { oplinkrcvr_dev->oplinkreceiverdata.Channel[i] = (i < RFM22B_PPM_NUM_CHANNELS) ? channels[i] : PIOS_RCVR_TIMEOUT; } - OPLinkReceiverSet(&oplinkrcvr_dev->oplinkreceiverdata); + + // Update the RSSI and quality fields. + int8_t rssi; + OPLinkReceiverRSSIGet(&rssi); + oplinkrcvr_dev->oplinkreceiverdata.RSSI = rssi; + uint8_t quality; + OPLinkReceiverLinkQualityGet(&quality); + // Link quality is 0-128, so scale it down to 0-100 + oplinkrcvr_dev->oplinkreceiverdata.LinkQuality = quality * 100 / 128; + + //OPLinkReceiverSet(&oplinkrcvr_dev->oplinkreceiverdata); oplinkrcvr_dev->Fresh = true; } +#endif /* PIOS_INCLUDE_RFM22B */ #if defined(PIOS_INCLUDE_FREERTOS) static struct pios_oplinkrcvr_dev *PIOS_oplinkrcvr_alloc(void) @@ -96,6 +110,9 @@ static struct pios_oplinkrcvr_dev *PIOS_oplinkrcvr_alloc(void) oplinkrcvr_dev->magic = PIOS_OPLINKRCVR_DEV_MAGIC; oplinkrcvr_dev->Fresh = false; oplinkrcvr_dev->supv_timer = 0; + + /* The update callback cannot receive the device pointer, so set it in a global */ + global_oplinkrcvr_dev = oplinkrcvr_dev; return oplinkrcvr_dev; } @@ -119,7 +136,21 @@ static struct pios_oplinkrcvr_dev *PIOS_oplinkrcvr_alloc(void) } #endif /* if defined(PIOS_INCLUDE_FREERTOS) */ +static void oplinkreceiver_updated(UAVObjEvent *ev) +{ + struct pios_oplinkrcvr_dev *oplinkrcvr_dev = global_oplinkrcvr_dev; + + if (ev->obj == OPLinkReceiverHandle()) { + OPLinkReceiverGet(&oplinkrcvr_dev->oplinkreceiverdata); + oplinkrcvr_dev->Fresh = true; + } +} + +#if defined(PIOS_INCLUDE_RFM22B) extern int32_t PIOS_OPLinkRCVR_Init(uint32_t *oplinkrcvr_id, uint32_t rfm22b_id) +#else +extern int32_t PIOS_OPLinkRCVR_Init(uint32_t *oplinkrcvr_id) +#endif { struct pios_oplinkrcvr_dev *oplinkrcvr_dev; @@ -134,8 +165,13 @@ extern int32_t PIOS_OPLinkRCVR_Init(uint32_t *oplinkrcvr_id, uint32_t rfm22b_id) oplinkrcvr_dev->oplinkreceiverdata.Channel[i] = PIOS_RCVR_TIMEOUT; } +#if defined(PIOS_INCLUDE_RFM22B) /* Register ppm callback */ PIOS_RFM22B_SetPPMCallback(rfm22b_id, PIOS_oplinkrcvr_ppm_callback, (uint32_t)oplinkrcvr_dev); +#endif + + /* Updates could come over the telemetry channel, so register uavobj callback */ + OPLinkReceiverConnectCallback(oplinkreceiver_updated); /* Register the failsafe timer callback. */ if (!PIOS_RTC_RegisterTickCallback(PIOS_oplinkrcvr_Supervisor, (uint32_t)oplinkrcvr_dev)) { @@ -199,14 +235,17 @@ 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) +static uint8_t PIOS_OPLinkRCVR_Quality_Get(uint32_t oplinkrcvr_id) { - uint16_t oplink_quality; + /* Recover our device context */ + struct pios_oplinkrcvr_dev *oplinkrcvr_dev = (struct pios_oplinkrcvr_dev *)oplinkrcvr_id; - OPLinkStatusLinkQualityGet(&oplink_quality); + if (!PIOS_oplinkrcvr_validate(oplinkrcvr_dev)) { + /* Invalid device specified */ + return 0; + } - /* link_status is in the range 0-128, so scale to a % */ - return oplink_quality * 100 / 128; + return oplinkrcvr_dev->oplinkreceiverdata.LinkQuality; } #endif /* PIOS_INCLUDE_OPLINKRCVR */ diff --git a/flight/pios/common/pios_rfm22b.c b/flight/pios/common/pios_rfm22b.c index 13ea92948..9b7f3f5e3 100644 --- a/flight/pios/common/pios_rfm22b.c +++ b/flight/pios/common/pios_rfm22b.c @@ -1798,6 +1798,7 @@ static enum pios_radio_event radio_txStart(struct pios_rfm22b_dev *radio_dev) } // Should we append PPM data to the packet? + bool ppm_valid = false; if (radio_dev->ppm_send_mode) { len = RFM22B_PPM_NUM_CHANNELS + (radio_dev->ppm_only_mode ? 2 : 1); @@ -1817,10 +1818,13 @@ static enum pios_radio_event radio_txStart(struct pios_rfm22b_dev *radio_dev) if ((val == PIOS_RCVR_INVALID) || (val == PIOS_RCVR_TIMEOUT)) { val = RFM22B_PPM_INVALID; } else if (val > RFM22B_PPM_MAX_US) { + ppm_valid = true; val = RFM22B_PPM_MAX; } else if (val < RFM22B_PPM_MIN_US) { + ppm_valid = true; val = RFM22B_PPM_MIN; } else { + ppm_valid = true; val = (val - RFM22B_PPM_MIN_US) / RFM22B_PPM_SCALE + RFM22B_PPM_MIN; } @@ -1844,6 +1848,7 @@ static enum pios_radio_event radio_txStart(struct pios_rfm22b_dev *radio_dev) } // Append data from the com interface if applicable. + bool packet_data = false; if (!radio_dev->ppm_only_mode) { uint8_t newlen = 0; bool need_yield = false; @@ -1863,6 +1868,7 @@ static enum pios_radio_event radio_txStart(struct pios_rfm22b_dev *radio_dev) i++; } if (newlen) { + packet_data = true; *(p + len) = radio_dev->last_stream_sent; len += newlen + 1; } @@ -1885,7 +1891,7 @@ static enum pios_radio_event radio_txStart(struct pios_rfm22b_dev *radio_dev) } // Only count the packet if it contains valid data. - if (radio_dev->ppm_only_mode || (len > RS_ECC_NPARITY)) { + if (ppm_valid || packet_data) { TX_LED_ON; radio_dev->stats.tx_byte_count += len; } diff --git a/flight/pios/inc/pios_board_io.h b/flight/pios/inc/pios_board_io.h index 758051acc..1f8500fd9 100644 --- a/flight/pios/inc/pios_board_io.h +++ b/flight/pios/inc/pios_board_io.h @@ -268,4 +268,8 @@ void PIOS_BOARD_IO_Configure_RadioAuxStream(HwSettingsRadioAuxStreamOptions radi void PIOS_BOARD_IO_Configure_GCS_RCVR(); #endif +#ifdef PIOS_INCLUDE_OPLINKRCVR +void PIOS_BOARD_IO_Configure_OPLink_RCVR(); +#endif + #endif /* PIOS_BOARD_IO_H */ diff --git a/flight/pios/inc/pios_oplinkrcvr_priv.h b/flight/pios/inc/pios_oplinkrcvr_priv.h index dc59812b4..c8b948ae6 100644 --- a/flight/pios/inc/pios_oplinkrcvr_priv.h +++ b/flight/pios/inc/pios_oplinkrcvr_priv.h @@ -35,7 +35,11 @@ extern const struct pios_rcvr_driver pios_oplinkrcvr_rcvr_driver; +#if defined(PIOS_INCLUDE_RFM22B) extern int32_t PIOS_OPLinkRCVR_Init(uint32_t *oplinkrcvr_id, uint32_t rfm22b_id); +#else +extern int32_t PIOS_OPLinkRCVR_Init(uint32_t *oplinkrcvr_id); +#endif #endif /* PIOS_OPLINKRCVR_PRIV_H */ diff --git a/flight/targets/boards/ccf3d/firmware/inc/pios_config.h b/flight/targets/boards/ccf3d/firmware/inc/pios_config.h index 110c74bcb..6645c1340 100644 --- a/flight/targets/boards/ccf3d/firmware/inc/pios_config.h +++ b/flight/targets/boards/ccf3d/firmware/inc/pios_config.h @@ -105,8 +105,8 @@ #define PIOS_INCLUDE_SRXL #define PIOS_INCLUDE_HOTT #define PIOS_INCLUDE_IBUS -/* #define PIOS_INCLUDE_GCSRCVR */ -/* #define PIOS_INCLUDE_OPLINKRCVR */ +#define PIOS_INCLUDE_GCSRCVR +#define PIOS_INCLUDE_OPLINKRCVR /* PIOS abstract receiver interface */ #define PIOS_INCLUDE_RCVR diff --git a/flight/targets/boards/ccf3d/firmware/pios_board.c b/flight/targets/boards/ccf3d/firmware/pios_board.c index 69a00535d..73a7d6004 100644 --- a/flight/targets/boards/ccf3d/firmware/pios_board.c +++ b/flight/targets/boards/ccf3d/firmware/pios_board.c @@ -251,10 +251,13 @@ void PIOS_Board_Init(void) break; } +#ifdef PIOS_INCLUDE_GCSRCVR + PIOS_BOARD_IO_Configure_GCS_RCVR(); +#endif -#if defined(PIOS_INCLUDE_GCSRCVR) - PIOS_BOARD_IO_Configure_GCSRCVR(); -#endif /* PIOS_INCLUDE_GCSRCVR */ +#ifdef PIOS_INCLUDE_OPLINKRCVR + PIOS_BOARD_IO_Configure_OPLink_RCVR(); +#endif #ifndef PIOS_ENABLE_DEBUG_PINS switch ((HwSettingsCC_RcvrPortOptions)hwsettings_rcvrport) { diff --git a/flight/targets/boards/ccf3d/pios_board.h b/flight/targets/boards/ccf3d/pios_board.h index 6d0f67d46..cb0b43b4d 100644 --- a/flight/targets/boards/ccf3d/pios_board.h +++ b/flight/targets/boards/ccf3d/pios_board.h @@ -204,6 +204,7 @@ extern uint32_t pios_ws2811_id; #define PIOS_RCVR_MAX_DEVS 3 #define PIOS_RCVR_MAX_CHANNELS 12 #define PIOS_GCSRCVR_TIMEOUT_MS 100 +#define PIOS_OPLINK_RCVR_TIMEOUT_MS 100 // ------------------------- // Receiver PPM input diff --git a/flight/targets/boards/coptercontrol/firmware/pios_board.c b/flight/targets/boards/coptercontrol/firmware/pios_board.c index 06f9d54ac..22a8eeecb 100644 --- a/flight/targets/boards/coptercontrol/firmware/pios_board.c +++ b/flight/targets/boards/coptercontrol/firmware/pios_board.c @@ -281,6 +281,10 @@ void PIOS_Board_Init(void) PIOS_BOARD_IO_Configure_GCS_RCVR(); #endif +#ifdef PIOS_INCLUDE_OPLINKRCVR + PIOS_BOARD_IO_Configure_OPLink_RCVR(); +#endif + /* Remap AFIO pin for PB4 (Servo 5 Out)*/ GPIO_PinRemapConfig(GPIO_Remap_SWJ_NoJTRST, ENABLE); diff --git a/flight/targets/boards/coptercontrol/pios_board.h b/flight/targets/boards/coptercontrol/pios_board.h index 370955e2a..ef61a0006 100644 --- a/flight/targets/boards/coptercontrol/pios_board.h +++ b/flight/targets/boards/coptercontrol/pios_board.h @@ -228,6 +228,7 @@ extern uint32_t pios_spi_flash_accel_adapter_id; #define PIOS_RCVR_MAX_DEVS 3 #define PIOS_RCVR_MAX_CHANNELS 12 #define PIOS_GCSRCVR_TIMEOUT_MS 100 +#define PIOS_OPLINK_RCVR_TIMEOUT_MS 100 // ------------------------- // Receiver PPM input diff --git a/flight/targets/boards/discoveryf4bare/firmware/pios_board.c b/flight/targets/boards/discoveryf4bare/firmware/pios_board.c index b40deb990..eedfab1e7 100644 --- a/flight/targets/boards/discoveryf4bare/firmware/pios_board.c +++ b/flight/targets/boards/discoveryf4bare/firmware/pios_board.c @@ -315,6 +315,10 @@ void PIOS_Board_Init(void) PIOS_BOARD_IO_Configure_GCS_RCVR(); #endif +#ifdef PIOS_INCLUDE_OPLINKRCVR + PIOS_BOARD_IO_Configure_OPLink_RCVR(); +#endif + #ifndef PIOS_ENABLE_DEBUG_PINS // pios_servo_cfg points to the correct configuration based on input port settings PIOS_Servo_Init(pios_servo_cfg); diff --git a/flight/targets/boards/oplinkmini/firmware/Makefile b/flight/targets/boards/oplinkmini/firmware/Makefile index 534bbf5e2..abb6b7781 100644 --- a/flight/targets/boards/oplinkmini/firmware/Makefile +++ b/flight/targets/boards/oplinkmini/firmware/Makefile @@ -28,7 +28,8 @@ include $(FLIGHT_ROOT_DIR)/make/firmware-defs.mk override USE_DSP_LIB := NO # List of mandatory modules to include -MODULES += RadioComBridge +MODULES += \ + RadioComBridge # List of optional modules to include OPTMODULES = diff --git a/flight/targets/boards/oplinkmini/firmware/pios_board.c b/flight/targets/boards/oplinkmini/firmware/pios_board.c index 4cdbb83ad..2de96a068 100644 --- a/flight/targets/boards/oplinkmini/firmware/pios_board.c +++ b/flight/targets/boards/oplinkmini/firmware/pios_board.c @@ -32,6 +32,7 @@ #include #include #include +#include #include #include #ifdef PIOS_INCLUDE_SERVO @@ -133,6 +134,7 @@ void PIOS_Board_Init(void) } OPLinkSettingsInitialize(); + OPLinkReceiverInitialize(); /* Retrieve the settings object. */ OPLinkSettingsData oplinkSettings; @@ -450,6 +452,25 @@ static void PIOS_Board_PPM_callback(__attribute__((unused)) uint32_t context, co ppm_value = 1000 + ((rssi + 127) * 9); PIOS_PPM_OUT_Set(PIOS_PPM_OUTPUT, RFM22B_PPM_NUM_CHANNELS, ppm_value); } + } else { + // If there is no PPM output defined, try sending the control outputs as a UAVObject. + OPLinkReceiverData recv_data; + for (uint8_t i = 0; i < OPLINKRECEIVER_CHANNEL_NUMELEM; ++i) { + if (i < RFM22B_PPM_NUM_CHANNELS) { + recv_data.Channel[i] = channels[i]; + } else { + recv_data.Channel[i] = PIOS_RCVR_TIMEOUT; + } + } + // Update the RSSI and quality fields. + int8_t rssi; + OPLinkStatusRSSIGet(&rssi); + recv_data.RSSI = rssi; + uint16_t quality; + OPLinkStatusLinkQualityGet(&quality); + // Link quality is 0-128, so scale it down to 0-100 + recv_data.LinkQuality = quality * 100 / 128; + OPLinkReceiverSet(&recv_data); } #if defined(PIOS_INCLUDE_SERVO) for (uint8_t i = 0; i < servo_count; ++i) { diff --git a/flight/targets/boards/pikoblx/firmware/inc/pios_config.h b/flight/targets/boards/pikoblx/firmware/inc/pios_config.h index 83237b45c..71b840b8e 100644 --- a/flight/targets/boards/pikoblx/firmware/inc/pios_config.h +++ b/flight/targets/boards/pikoblx/firmware/inc/pios_config.h @@ -111,8 +111,8 @@ #define PIOS_INCLUDE_SRXL #define PIOS_INCLUDE_HOTT #define PIOS_INCLUDE_IBUS -/* #define PIOS_INCLUDE_GCSRCVR */ -/* #define PIOS_INCLUDE_OPLINKRCVR */ +#define PIOS_INCLUDE_GCSRCVR +#define PIOS_INCLUDE_OPLINKRCVR /* PIOS abstract receiver interface */ #define PIOS_INCLUDE_RCVR diff --git a/flight/targets/boards/pikoblx/firmware/pios_board.c b/flight/targets/boards/pikoblx/firmware/pios_board.c index 9aa8b0c2f..bf07da223 100644 --- a/flight/targets/boards/pikoblx/firmware/pios_board.c +++ b/flight/targets/boards/pikoblx/firmware/pios_board.c @@ -226,6 +226,14 @@ void PIOS_Board_Init(void) PIOS_BOARD_IO_Configure_PPM_RCVR(&pios_ppm_cfg); #endif +#ifdef PIOS_INCLUDE_GCSRCVR + PIOS_BOARD_IO_Configure_GCS_RCVR(); +#endif + +#ifdef PIOS_INCLUDE_OPLINKRCVR + PIOS_BOARD_IO_Configure_OPLink_RCVR(); +#endif + #ifndef PIOS_ENABLE_DEBUG_PINS PIOS_Servo_Init(&pios_servo_cfg); #else diff --git a/flight/targets/boards/pikoblx/pios_board.h b/flight/targets/boards/pikoblx/pios_board.h index f3654b0b0..cb0b0cdca 100644 --- a/flight/targets/boards/pikoblx/pios_board.h +++ b/flight/targets/boards/pikoblx/pios_board.h @@ -161,6 +161,7 @@ extern uint32_t pios_ws2811_id; #define PIOS_RCVR_MAX_DEVS 3 #define PIOS_RCVR_MAX_CHANNELS 12 #define PIOS_GCSRCVR_TIMEOUT_MS 100 +#define PIOS_OPLINK_RCVR_TIMEOUT_MS 100 // ------------------------- // Receiver PPM input diff --git a/flight/targets/boards/revolution/firmware/pios_board.c b/flight/targets/boards/revolution/firmware/pios_board.c index 273d4a052..0f2bc336a 100644 --- a/flight/targets/boards/revolution/firmware/pios_board.c +++ b/flight/targets/boards/revolution/firmware/pios_board.c @@ -315,6 +315,10 @@ void PIOS_Board_Init(void) PIOS_BOARD_IO_Configure_GCS_RCVR(); #endif +#ifdef PIOS_INCLUDE_OPLINKRCVR + PIOS_BOARD_IO_Configure_OPLink_RCVR(); +#endif + #ifndef PIOS_ENABLE_DEBUG_PINS // pios_servo_cfg points to the correct configuration based on input port settings PIOS_Servo_Init(pios_servo_cfg); diff --git a/flight/targets/boards/revonano/firmware/pios_board.c b/flight/targets/boards/revonano/firmware/pios_board.c index 050652a1a..fa667f917 100644 --- a/flight/targets/boards/revonano/firmware/pios_board.c +++ b/flight/targets/boards/revonano/firmware/pios_board.c @@ -258,6 +258,10 @@ void PIOS_Board_Init(void) PIOS_BOARD_IO_Configure_GCS_RCVR(); #endif +#ifdef PIOS_INCLUDE_OPLINKRCVR + PIOS_BOARD_IO_Configure_OPLink_RCVR(); +#endif + #ifdef PIOS_INCLUDE_WS2811 #include HwSettingsWS2811LED_OutOptions ws2811_pin_settings; diff --git a/flight/targets/boards/revoproto/firmware/pios_board.c b/flight/targets/boards/revoproto/firmware/pios_board.c index bf957aeb1..2e78c7363 100644 --- a/flight/targets/boards/revoproto/firmware/pios_board.c +++ b/flight/targets/boards/revoproto/firmware/pios_board.c @@ -326,6 +326,10 @@ void PIOS_Board_Init(void) PIOS_BOARD_IO_Configure_GCS_RCVR(); #endif +#ifdef PIOS_INCLUDE_OPLINKRCVR + PIOS_BOARD_IO_Configure_OPLink_RCVR(); +#endif + #ifndef PIOS_ENABLE_DEBUG_PINS switch (hwsettings_rcvrport) { case HWSETTINGS_RV_RCVRPORT_DISABLED: diff --git a/flight/targets/boards/revoproto/pios_board.h b/flight/targets/boards/revoproto/pios_board.h index 960334acf..d4fd93808 100644 --- a/flight/targets/boards/revoproto/pios_board.h +++ b/flight/targets/boards/revoproto/pios_board.h @@ -196,6 +196,7 @@ extern uint32_t pios_ws2811_id; #define PIOS_RCVR_MAX_DEVS 3 #define PIOS_RCVR_MAX_CHANNELS 12 #define PIOS_GCSRCVR_TIMEOUT_MS 100 +#define PIOS_OPLINK_RCVR_TIMEOUT_MS 100 // ------------------------- // Receiver PPM input diff --git a/flight/targets/boards/sparky2/firmware/pios_board.c b/flight/targets/boards/sparky2/firmware/pios_board.c index 3843d0f25..f65cc1de7 100644 --- a/flight/targets/boards/sparky2/firmware/pios_board.c +++ b/flight/targets/boards/sparky2/firmware/pios_board.c @@ -274,6 +274,10 @@ void PIOS_Board_Init(void) PIOS_BOARD_IO_Configure_GCS_RCVR(); #endif +#ifdef PIOS_INCLUDE_OPLINKRCVR + PIOS_BOARD_IO_Configure_OPLink_RCVR(); +#endif + #ifndef PIOS_ENABLE_DEBUG_PINS PIOS_Servo_Init(&pios_servo_cfg_out); #else diff --git a/flight/targets/boards/spracingf3/firmware/inc/pios_config.h b/flight/targets/boards/spracingf3/firmware/inc/pios_config.h index 9ea6910e8..b4f856a2b 100644 --- a/flight/targets/boards/spracingf3/firmware/inc/pios_config.h +++ b/flight/targets/boards/spracingf3/firmware/inc/pios_config.h @@ -108,8 +108,8 @@ #define PIOS_INCLUDE_SRXL #define PIOS_INCLUDE_HOTT #define PIOS_INCLUDE_IBUS -/* #define PIOS_INCLUDE_GCSRCVR */ -/* #define PIOS_INCLUDE_OPLINKRCVR */ +#define PIOS_INCLUDE_GCSRCVR +#define PIOS_INCLUDE_OPLINKRCVR /* PIOS abstract receiver interface */ #define PIOS_INCLUDE_RCVR diff --git a/flight/targets/boards/spracingf3/firmware/pios_board.c b/flight/targets/boards/spracingf3/firmware/pios_board.c index 3833aa96c..e9a56d0c5 100644 --- a/flight/targets/boards/spracingf3/firmware/pios_board.c +++ b/flight/targets/boards/spracingf3/firmware/pios_board.c @@ -239,6 +239,14 @@ void PIOS_Board_Init(void) #endif /* if defined(PIOS_INCLUDE_PWM) */ } +#ifdef PIOS_INCLUDE_GCSRCVR + PIOS_BOARD_IO_Configure_GCS_RCVR(); +#endif + +#ifdef PIOS_INCLUDE_OPLINKRCVR + PIOS_BOARD_IO_Configure_OPLink_RCVR(); +#endif + #ifndef PIOS_ENABLE_DEBUG_PINS // TODO: make use of HWSPRACINGF3SETTINGS_IOPORTS_[PPM]OUTPUTS PIOS_Servo_Init(&pios_servo_cfg); diff --git a/flight/targets/boards/spracingf3/pios_board.h b/flight/targets/boards/spracingf3/pios_board.h index 988cdb661..c41f2abe0 100644 --- a/flight/targets/boards/spracingf3/pios_board.h +++ b/flight/targets/boards/spracingf3/pios_board.h @@ -167,6 +167,7 @@ extern uint32_t pios_ws2811_id; #define PIOS_RCVR_MAX_DEVS 3 #define PIOS_RCVR_MAX_CHANNELS 12 #define PIOS_GCSRCVR_TIMEOUT_MS 100 +#define PIOS_OPLINK_RCVR_TIMEOUT_MS 100 // ------------------------- // Receiver PPM input diff --git a/flight/targets/boards/spracingf3evo/firmware/inc/pios_config.h b/flight/targets/boards/spracingf3evo/firmware/inc/pios_config.h index a8864df84..89bd45e3b 100644 --- a/flight/targets/boards/spracingf3evo/firmware/inc/pios_config.h +++ b/flight/targets/boards/spracingf3evo/firmware/inc/pios_config.h @@ -111,8 +111,8 @@ #define PIOS_INCLUDE_SRXL #define PIOS_INCLUDE_HOTT #define PIOS_INCLUDE_IBUS -/* #define PIOS_INCLUDE_GCSRCVR */ -/* #define PIOS_INCLUDE_OPLINKRCVR */ +#define PIOS_INCLUDE_GCSRCVR +#define PIOS_INCLUDE_OPLINKRCVR /* PIOS abstract receiver interface */ #define PIOS_INCLUDE_RCVR diff --git a/flight/targets/boards/spracingf3evo/firmware/pios_board.c b/flight/targets/boards/spracingf3evo/firmware/pios_board.c index a9e5a7cdb..87b1949ae 100644 --- a/flight/targets/boards/spracingf3evo/firmware/pios_board.c +++ b/flight/targets/boards/spracingf3evo/firmware/pios_board.c @@ -227,6 +227,14 @@ void PIOS_Board_Init(void) PIOS_BOARD_IO_Configure_PPM_RCVR(&pios_ppm_cfg); } +#ifdef PIOS_INCLUDE_GCSRCVR + PIOS_BOARD_IO_Configure_GCS_RCVR(); +#endif + +#ifdef PIOS_INCLUDE_OPLINKRCVR + PIOS_BOARD_IO_Configure_OPLink_RCVR(); +#endif + #ifndef PIOS_ENABLE_DEBUG_PINS PIOS_Servo_Init(&pios_servo_cfg); #else diff --git a/flight/targets/boards/spracingf3evo/pios_board.h b/flight/targets/boards/spracingf3evo/pios_board.h index 629b33783..412071ecb 100644 --- a/flight/targets/boards/spracingf3evo/pios_board.h +++ b/flight/targets/boards/spracingf3evo/pios_board.h @@ -172,6 +172,7 @@ extern uint32_t pios_ws2811_id; #define PIOS_RCVR_MAX_DEVS 3 #define PIOS_RCVR_MAX_CHANNELS 12 #define PIOS_GCSRCVR_TIMEOUT_MS 100 +#define PIOS_OPLINK_RCVR_TIMEOUT_MS 100 // ------------------------- // Receiver PPM input diff --git a/flight/targets/boards/tinyfish/firmware/inc/pios_config.h b/flight/targets/boards/tinyfish/firmware/inc/pios_config.h index 64815d3fd..c25d039fc 100644 --- a/flight/targets/boards/tinyfish/firmware/inc/pios_config.h +++ b/flight/targets/boards/tinyfish/firmware/inc/pios_config.h @@ -111,8 +111,8 @@ #define PIOS_INCLUDE_SRXL #define PIOS_INCLUDE_HOTT #define PIOS_INCLUDE_IBUS -/* #define PIOS_INCLUDE_GCSRCVR */ -/* #define PIOS_INCLUDE_OPLINKRCVR */ +#define PIOS_INCLUDE_GCSRCVR +#define PIOS_INCLUDE_OPLINKRCVR #define PIOS_INCLUDE_FRSKY_SENSORHUB diff --git a/flight/targets/boards/tinyfish/firmware/pios_board.c b/flight/targets/boards/tinyfish/firmware/pios_board.c index 9abcb9624..502748c8f 100644 --- a/flight/targets/boards/tinyfish/firmware/pios_board.c +++ b/flight/targets/boards/tinyfish/firmware/pios_board.c @@ -254,6 +254,14 @@ void PIOS_Board_Init(void) PIOS_BOARD_IO_Configure_UART(&pios_usart_cfg[0], PIOS_BOARD_IO_UART_COMBRIDGE); } +#ifdef PIOS_INCLUDE_GCSRCVR + PIOS_BOARD_IO_Configure_GCS_RCVR(); +#endif + +#ifdef PIOS_INCLUDE_OPLINKRCVR + PIOS_BOARD_IO_Configure_OPLink_RCVR(); +#endif + #ifdef PIOS_ENABLE_DEBUG_PINS PIOS_DEBUG_Init(&pios_servo_cfg.channels, pios_servo_cfg.num_channels); #else diff --git a/flight/targets/boards/tinyfish/pios_board.h b/flight/targets/boards/tinyfish/pios_board.h index 45e4f69e4..9c9ec5e66 100644 --- a/flight/targets/boards/tinyfish/pios_board.h +++ b/flight/targets/boards/tinyfish/pios_board.h @@ -135,6 +135,7 @@ extern uint32_t pios_ws2811_id; #define PIOS_RCVR_MAX_DEVS 3 #define PIOS_RCVR_MAX_CHANNELS 12 #define PIOS_GCSRCVR_TIMEOUT_MS 100 +#define PIOS_OPLINK_RCVR_TIMEOUT_MS 100 // ------------------------- // Receiver PPM input diff --git a/flight/uavobjects/inc/uavobjectmanager.h b/flight/uavobjects/inc/uavobjectmanager.h index e73ac86a6..4831e79db 100644 --- a/flight/uavobjects/inc/uavobjectmanager.h +++ b/flight/uavobjects/inc/uavobjectmanager.h @@ -202,7 +202,7 @@ bool UAVObjIsSingleInstance(UAVObjHandle obj); bool UAVObjIsMetaobject(UAVObjHandle obj); bool UAVObjIsSettings(UAVObjHandle obj); bool UAVObjIsPriority(UAVObjHandle obj); -int32_t UAVObjUnpack(UAVObjHandle obj_handle, uint16_t instId, const uint8_t *dataIn); +int32_t UAVObjUnpack(UAVObjHandle obj_handle, uint16_t instId, const uint8_t *dataIn, bool create); int32_t UAVObjPack(UAVObjHandle obj_handle, uint16_t instId, uint8_t *dataOut); uint8_t UAVObjUpdateCRC(UAVObjHandle obj_handle, uint16_t instId, uint8_t crc); int32_t UAVObjSave(UAVObjHandle obj_handle, uint16_t instId); diff --git a/flight/uavobjects/uavobjectmanager.c b/flight/uavobjects/uavobjectmanager.c index 0d9de00ea..5967482ee 100644 --- a/flight/uavobjects/uavobjectmanager.c +++ b/flight/uavobjects/uavobjectmanager.c @@ -513,7 +513,7 @@ unlock_exit: * \param[in] dataIn The byte array * \return 0 if success or -1 if failure */ -int32_t UAVObjUnpack(UAVObjHandle obj_handle, uint16_t instId, const uint8_t *dataIn) +int32_t UAVObjUnpack(UAVObjHandle obj_handle, uint16_t instId, const uint8_t *dataIn, bool create) { PIOS_Assert(obj_handle); @@ -538,12 +538,13 @@ int32_t UAVObjUnpack(UAVObjHandle obj_handle, uint16_t instId, const uint8_t *da instEntry = getInstance(obj, instId); // If the instance does not exist create it and any other instances before it - if (instEntry == NULL) { + if ((instEntry == NULL) && create) { instEntry = createInstance(obj, instId); - if (instEntry == NULL) { - goto unlock_exit; - } } + if (instEntry == NULL) { + goto unlock_exit; + } + // Set the data memcpy(InstanceData(instEntry), dataIn, obj->type->instance_size); } diff --git a/flight/uavtalk/inc/uavtalk.h b/flight/uavtalk/inc/uavtalk.h index e485882ef..b4a8b44bc 100644 --- a/flight/uavtalk/inc/uavtalk.h +++ b/flight/uavtalk/inc/uavtalk.h @@ -60,7 +60,7 @@ int32_t UAVTalkSendObjectRequest(UAVTalkConnection connection, UAVObjHandle obj, UAVTalkRxState UAVTalkProcessInputStream(UAVTalkConnection connectionHandle, uint8_t *rxbuffer, uint8_t length); UAVTalkRxState UAVTalkProcessInputStreamQuiet(UAVTalkConnection connectionHandle, uint8_t *rxbuffer, uint8_t length, uint8_t *position); int32_t UAVTalkRelayPacket(UAVTalkConnection inConnectionHandle, UAVTalkConnection outConnectionHandle); -int32_t UAVTalkReceiveObject(UAVTalkConnection connectionHandle); +int32_t UAVTalkReceiveObject(UAVTalkConnection connectionHandle, bool create); void UAVTalkGetStats(UAVTalkConnection connection, UAVTalkStats *stats, bool reset); void UAVTalkAddStats(UAVTalkConnection connection, UAVTalkStats *stats, bool reset); void UAVTalkResetStats(UAVTalkConnection connection); diff --git a/flight/uavtalk/uavtalk.c b/flight/uavtalk/uavtalk.c index c537fba67..4fa4b29ba 100644 --- a/flight/uavtalk/uavtalk.c +++ b/flight/uavtalk/uavtalk.c @@ -51,7 +51,7 @@ static int32_t objectTransaction(UAVTalkConnectionData *connection, uint8_t type, UAVObjHandle obj, uint16_t instId, int32_t timeout); static int32_t sendObject(UAVTalkConnectionData *connection, uint8_t type, uint32_t objId, uint16_t instId, UAVObjHandle obj); static int32_t sendSingleObject(UAVTalkConnectionData *connection, uint8_t type, uint32_t objId, uint16_t instId, UAVObjHandle obj); -static int32_t receiveObject(UAVTalkConnectionData *connection, uint8_t type, uint32_t objId, uint16_t instId, uint8_t *data); +static int32_t receiveObject(UAVTalkConnectionData *connection, uint8_t type, uint32_t objId, uint16_t instId, uint8_t *data, bool create); static void updateAck(UAVTalkConnectionData *connection, uint8_t type, uint32_t objId, uint16_t instId); // UavTalk Process FSM functions static bool UAVTalkProcess_SYNC(UAVTalkConnectionData *connection, UAVTalkInputProcessor *iproc, uint8_t *rxbuffer, uint8_t length, uint8_t *position); @@ -444,7 +444,7 @@ UAVTalkRxState UAVTalkProcessInputStream(UAVTalkConnection connectionHandle, uin while (position < length) { state = UAVTalkProcessInputStreamQuiet(connectionHandle, rxbuffer, length, &position); if (state == UAVTALK_STATE_COMPLETE) { - UAVTalkReceiveObject(connectionHandle); + UAVTalkReceiveObject(connectionHandle, true); } } return state; @@ -546,7 +546,7 @@ int32_t UAVTalkRelayPacket(UAVTalkConnection inConnectionHandle, UAVTalkConnecti * \return 0 Success * \return -1 Failure */ -int32_t UAVTalkReceiveObject(UAVTalkConnection connectionHandle) +int32_t UAVTalkReceiveObject(UAVTalkConnection connectionHandle, bool create) { UAVTalkConnectionData *connection; @@ -557,7 +557,7 @@ int32_t UAVTalkReceiveObject(UAVTalkConnection connectionHandle) return -1; } - return receiveObject(connection, iproc->type, iproc->objId, iproc->instId, connection->rxBuffer); + return receiveObject(connection, iproc->type, iproc->objId, iproc->instId, connection->rxBuffer, create); } /** @@ -592,7 +592,7 @@ uint32_t UAVTalkGetPacketObjId(UAVTalkConnection connectionHandle) * \return 0 Success * \return -1 Failure */ -static int32_t receiveObject(UAVTalkConnectionData *connection, uint8_t type, uint32_t objId, uint16_t instId, uint8_t *data) +static int32_t receiveObject(UAVTalkConnectionData *connection, uint8_t type, uint32_t objId, uint16_t instId, uint8_t *data, bool create) { UAVObjHandle obj; int32_t ret = 0; @@ -613,8 +613,8 @@ static int32_t receiveObject(UAVTalkConnectionData *connection, uint8_t type, ui case UAVTALK_TYPE_OBJ_TS: // All instances not allowed for OBJ messages if (obj && (instId != UAVOBJ_ALL_INSTANCES)) { - // Unpack object, if the instance does not exist it will be created! - if (UAVObjUnpack(obj, instId, data) == 0) { + // Unpack object, if create is true and the instance does not exist it will be created! + if (UAVObjUnpack(obj, instId, data, create) == 0) { // Check if this object acks a pending OBJ_REQ message // any OBJ message can ack a pending OBJ_REQ message // even one that was not sent in response to the OBJ_REQ message @@ -632,8 +632,8 @@ static int32_t receiveObject(UAVTalkConnectionData *connection, uint8_t type, ui UAVT_DEBUGLOG_CPRINTF(objId, "OBJ_ACK %X %d", objId, instId); // All instances not allowed for OBJ_ACK messages if (obj && (instId != UAVOBJ_ALL_INSTANCES)) { - // Unpack object, if the instance does not exist it will be created! - if (UAVObjUnpack(obj, instId, data) == 0) { + // Unpack object, if create is true and the instance does not exist it will be created! + if (UAVObjUnpack(obj, instId, data, create) == 0) { UAVT_DEBUGLOG_CPRINTF(objId, "OBJ ACK %X %d", objId, instId); // Object updated or created, transmit ACK sendObject(connection, UAVTALK_TYPE_ACK, objId, instId, NULL); diff --git a/python/examples/example.py b/python/examples/example.py index a22769f02..4a3d84e39 100644 --- a/python/examples/example.py +++ b/python/examples/example.py @@ -56,7 +56,7 @@ class UavtalkDemo(): _port = int(port[3:]) - 1 else: _port = port - serPort = serial.Serial(_port, 57600, timeout=.5) + serPort = serial.Serial(port, 115200, timeout=.5) if not serPort.isOpen(): raise IOError("Failed to open serial port") diff --git a/shared/uavobjectdefinition/oplinkreceiver.xml b/shared/uavobjectdefinition/oplinkreceiver.xml index 6539d8952..eab503e76 100644 --- a/shared/uavobjectdefinition/oplinkreceiver.xml +++ b/shared/uavobjectdefinition/oplinkreceiver.xml @@ -2,6 +2,8 @@ A receiver channel group carried over the OPLink radio. + +