1
0
mirror of https://bitbucket.org/librepilot/librepilot.git synced 2025-01-18 03:52:11 +01:00

Added PipXStatus and PipXSettings UAVObjects and added support the sending/receiving UAVTalk objects on the PipX.

This commit is contained in:
Brian Webb 2012-04-10 20:22:53 -07:00
parent 3914d22b09
commit 4936cd8fd2
14 changed files with 602 additions and 437 deletions

View File

@ -77,7 +77,6 @@ typedef struct {
typedef struct {
uint8_t txWinSize;
uint16_t maxConnections;
uint32_t id;
} PacketHandlerConfig;
typedef int32_t (*PHOutputStream)(PHPacketHandle packet);

View File

@ -363,7 +363,6 @@ static uint8_t PHLSendAck(PHPacketDataHandle data, PHPacketHandle p)
// Create the ACK message
PHPacketHeader ack;
ack.source_id = data->cfg.id;
ack.destination_id = p->header.source_id;
ack.type = PACKET_TYPE_ACK;
ack.rx_seq = p->header.tx_seq;
@ -385,7 +384,6 @@ static uint8_t PHLSendNAck(PHPacketDataHandle data, PHPacketHandle p)
// Create the NAck message
PHPacketHeader ack;
ack.source_id = data->cfg.id;
ack.destination_id = p->header.source_id;
ack.type = PACKET_TYPE_NACK;
ack.rx_seq = p->header.tx_seq;

View File

@ -38,7 +38,7 @@
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "openpilot.h"
#include <openpilot.h>
#include "systemmod.h"
// Private constants

View File

@ -34,7 +34,10 @@
#include <radiocombridge.h>
#include <packet_handler.h>
#include <gcsreceiver.h>
#include <pipxstatus.h>
#include <pipxsettings.h>
#include <uavtalk_priv.h>
#include <pios_rfm22b.h>
#include <ecc.h>
#include <stdbool.h>
@ -46,10 +49,13 @@
static void radio2ComBridgeTask(void *parameters);
static void com2RadioBridgeTask(void *parameters);
static void radioStatusTask(void *parameters);
static void updatePipXStatus(void);
static int32_t transmitData(uint8_t * data, int32_t length);
static int32_t transmitPacket(PHPacketHandle packet);
static void receiveData(uint8_t *buf, uint8_t len);
static void SendGCSReceiver(void);
static void SendPipXStatus(void);
static void PPMHandler(uint16_t *channels);
static void updateSettings();
@ -64,6 +70,8 @@ static void updateSettings();
#define MAX_RETRIES 2
#define REQ_TIMEOUT_MS 10
#define STATS_UPDATE_PERIOD_MS 250
// ****************
// Private types
@ -71,6 +79,7 @@ typedef struct {
// The task handles.
xTaskHandle radio2ComBridgeTaskHandle;
xTaskHandle com2RadioBridgeTaskHandle;
xTaskHandle radioStatusTaskHandle;
// The com buffers.
uint8_t *radio2com_buf;
@ -84,15 +93,20 @@ typedef struct {
UAVTalkConnection uavTalkCon;
// Error statistics.
uint32_t com_tx_errors;
uint32_t radio_tx_errors;
uint32_t comTxErrors;
uint32_t comTxRetries;
uint32_t comRxErrors;
uint32_t radioTxErrors;
uint32_t radioTxRetries;
uint32_t radioRxErrors;
// The packet timeout.
portTickType send_timeout;
uint16_t min_packet_size;
// Flag used to indicate an update of the GCSReceiver object.
// Flag used to indicate an update of the UAVObjects.
bool send_gcsreceiver;
bool send_pipxstatus;
// Tracks the UAVTalk messages transmitted from radio to com.
bool uavtalk_idle;
@ -117,6 +131,7 @@ static int32_t RadioComBridgeStart(void)
// Start the tasks
xTaskCreate(radio2ComBridgeTask, (signed char *)"Radio2ComBridge", STACK_SIZE_BYTES/2, NULL, TASK_PRIORITY, &(data->radio2ComBridgeTaskHandle));
xTaskCreate(com2RadioBridgeTask, (signed char *)"Com2RadioBridge", STACK_SIZE_BYTES/2, NULL, TASK_PRIORITY, &(data->com2RadioBridgeTaskHandle));
xTaskCreate(radioStatusTask, (signed char *)"RadioStatus", STACK_SIZE_BYTES/2, NULL, TASK_PRIORITY, &(data->radioStatusTaskHandle));
#ifdef PIOS_INCLUDE_WDG
PIOS_WDG_RegisterFlag(PIOS_WDG_RADIOCOM);
PIOS_WDG_RegisterFlag(PIOS_WDG_COMRADIO);
@ -140,9 +155,12 @@ static int32_t RadioComBridgeInitialize(void)
if (!data)
return -1;
// Initialize the GCSReceiver object.
// Initialize the UAVObjects that we use
GCSReceiverInitialize();
PipXStatusInitialize();
PipXSettingsInitialize();
data->send_gcsreceiver = false;
data->send_pipxstatus = false;
// TODO: Get from settings object
data->com_port = PIOS_COM_BRIDGE_COM;
@ -158,8 +176,12 @@ static int32_t RadioComBridgeInitialize(void)
data->uavTalkCon = UAVTalkInitialize(&transmitData);
// Initialize the statistics.
data->com_tx_errors = 0;
data->radio_tx_errors = 0;
data->radioTxErrors = 0;
data->radioTxRetries = 0;
data->radioRxErrors = 0;
data->comTxErrors = 0;
data->comTxRetries = 0;
data->comRxErrors = 0;
// Register the callbacks with the packet handler
PHRegisterOutputStream(pios_packet_handler, transmitPacket);
@ -288,6 +310,44 @@ static void com2RadioBridgeTask(void * parameters)
}
}
/**
* The stats update task.
*/
static void radioStatusTask(void *parameters)
{
while (1) {
#ifdef PIOS_INCLUDE_WDG
// Update the watchdog timer.
PIOS_WDG_UpdateFlag(PIOS_WDG_RADIOCOM);
#endif /* PIOS_INCLUDE_WDG */
// Update the status
updatePipXStatus();
data->send_pipxstatus = true;
// Delay until the next update period.
vTaskDelay(STATS_UPDATE_PERIOD_MS / portTICK_RATE_MS);
}
}
/**
* Update the PipX status
*/
static void updatePipXStatus(void)
{
PipXStatusData pipxStatus;
// Get object data
PipXStatusGet(&pipxStatus);
// Update the status
pipxStatus.DeviceID = PIOS_RFM22B_DeviceID(pios_rfm22b_id);
pipxStatus.RSSI = PIOS_RFM22B_RSSI(pios_rfm22b_id);
// Update the object
PipXStatusSet(&pipxStatus);
}
/**
* Transmit data buffer to the com port.
@ -336,6 +396,8 @@ static void receiveData(uint8_t *buf, uint8_t len)
// Send a local UAVTalk message if one is waiting to be sent.
if (data->send_gcsreceiver && data->uavtalk_idle)
SendGCSReceiver();
if (data->send_pipxstatus && data->uavtalk_idle)
SendPipXStatus();
// Parse the data for UAVTalk packets.
uint8_t sent_bytes = 0;
@ -372,12 +434,14 @@ static void receiveData(uint8_t *buf, uint8_t len)
uint8_t send_bytes = len - sent_bytes;
if (PIOS_COM_SendBuffer(outputPort, buf + sent_bytes, send_bytes) != send_bytes)
// Error on transmit
data->com_tx_errors++;
data->comTxErrors++;
sent_bytes = i;
// Send any UAVTalk messages that need to be sent.
if (data->send_gcsreceiver)
SendGCSReceiver();
if (data->send_pipxstatus)
SendPipXStatus();
}
++(data->uavtalk_packet_index);
}
@ -387,7 +451,7 @@ static void receiveData(uint8_t *buf, uint8_t len)
uint8_t send_bytes = len - sent_bytes;
if (PIOS_COM_SendBuffer(outputPort, buf + sent_bytes, send_bytes) != send_bytes)
// Error on transmit
data->com_tx_errors++;
data->comTxErrors++;
}
/**
@ -407,6 +471,17 @@ static void SendGCSReceiver(void)
data->send_gcsreceiver = false;
}
/**
* Transmit the GCSReceiver object using UAVTalk
* \param[in] channels The ppm channels
*/
static void SendPipXStatus(void)
{
// Transmit the PipXStatus
UAVTalkSendObject(data->uavTalkCon, PipXStatusHandle(), 0, 0, REQ_TIMEOUT_MS);
data->send_pipxstatus = false;
}
/**
* Receive a ppm packet
* \param[in] channels The ppm channels

View File

@ -261,9 +261,9 @@ extern uint32_t pios_com_rfm22b_id;
// RFM22
//-------------------------
extern uint32_t pios_rfm22b_id;
#define RFM22_EXT_INT_USE
#define RFM22_PIOS_SPI PIOS_SPI_PORT // SPIx
#define RFM22_PIOS_SPI PIOS_SPI_PORT // SPIx
#if defined(RFM22_EXT_INT_USE)
#define PIOS_RFM22_EXTI_GPIO_PORT GPIOA

View File

@ -149,14 +149,13 @@ struct pios_rfm22b_dev {
enum pios_rfm22b_dev_magic magic;
const struct pios_rfm22b_cfg *cfg;
uint32_t countdownTimer;
uint32_t deviceID;
// The COM callback functions.
pios_com_callback rx_in_cb;
uint32_t rx_in_context;
pios_com_callback tx_out_cb;
uint32_t tx_out_context;
PHPacketHandle cur_tx_packet;
};
uint32_t random32 = 0x459ab8d8;
@ -441,14 +440,25 @@ int32_t PIOS_RFM22B_Init(uint32_t *rfm22b_id, const struct pios_rfm22b_cfg *cfg)
// Bind the configuration to the device instance
rfm22b_dev->cfg = cfg;
rfm22b_dev->cur_tx_packet = 0;
*rfm22b_id = (uint32_t)rfm22b_dev;
// Initialize the TX pre-buffer pointer.
tx_pre_buffer_size = 0;
// Create our (hopefully) unique 32 bit id from the processor serial number.
uint8_t crcs[] = { 0, 0, 0, 0 };
{
char serial_no_str[33];
PIOS_SYS_SerialNumberGet(serial_no_str);
// Create a 32 bit value using 4 8 bit CRC values.
for (uint8_t i = 0; serial_no_str[i] != 0; ++i)
crcs[i % 4] = PIOS_CRC_updateByte(crcs[i % 4], serial_no_str[i]);
}
rfm22b_dev->deviceID = crcs[0] | crcs[1] << 8 | crcs[2] << 16 | crcs[3] << 24;
DEBUG_PRINTF(2, "RF device ID: %x\n\r", rfm22b_dev->deviceID);
// Initialize the radio device.
DEBUG_PRINTF(2, "Init Radio\n\r");
int initval = rfm22_init_normal(cfg->minFrequencyHz, cfg->maxFrequencyHz, 50000);
if (initval < 0)
@ -487,6 +497,7 @@ int32_t PIOS_RFM22B_Init(uint32_t *rfm22b_id, const struct pios_rfm22b_cfg *cfg)
rfm22_setTxPower(cfg->maxTxPower);
DEBUG_PRINTF(2, "\n\r");
DEBUG_PRINTF(2, "RF device ID: %x\n\r", rfm22b_dev->deviceID);
DEBUG_PRINTF(2, "RF datarate: %dbps\n\r", rfm22_getDatarate());
DEBUG_PRINTF(2, "RF frequency: %dHz\n\r", rfm22_getNominalCarrierFrequency());
DEBUG_PRINTF(2, "RF TX power: %d\n\r", rfm22_getTxPower());
@ -494,6 +505,18 @@ int32_t PIOS_RFM22B_Init(uint32_t *rfm22b_id, const struct pios_rfm22b_cfg *cfg)
return(0);
}
uint32_t PIOS_RFM22B_DeviceID(uint32_t rfm22b_id)
{
struct pios_rfm22b_dev *rfm22b_dev = (struct pios_rfm22b_dev *)rfm22b_id;
return rfm22b_dev->deviceID;
}
int16_t PIOS_RFM22B_RSSI(uint32_t rfb22b_id)
{
return rssi_dBm;
}
static void PIOS_RFM22B_RxStart(uint32_t rfm22b_id, uint16_t rx_bytes_avail)
{
struct pios_rfm22b_dev * rfm22b_dev = (struct pios_rfm22b_dev *)rfm22b_id;
@ -2384,12 +2407,45 @@ int rfm22_init_normal(uint32_t min_frequency_hz, uint32_t max_frequency_hz, uint
// x-nibbles rx preamble detection
rfm22_write(RFM22_preamble_detection_ctrl1, RX_PREAMBLE_NIBBLES << 3);
#ifdef PIOS_RFM22_NO_HEADER
// header control - we are not using the header
rfm22_write(RFM22_header_control1, RFM22_header_cntl1_bcen_none | RFM22_header_cntl1_hdch_none);
// no header bytes, synchronization word length 3, 2, 1 & 0 used, packet length included in header.
rfm22_write(RFM22_header_control2, RFM22_header_cntl2_hdlen_none |
RFM22_header_cntl2_synclen_3210 | ((TX_PREAMBLE_NIBBLES >> 8) & 0x01));
#else
// header control - using a 4 by header with broadcast of 0xffffffff
rfm22_write(RFM22_header_control1,
RFM22_header_cntl1_bcen_0 |
RFM22_header_cntl1_bcen_1 |
RFM22_header_cntl1_bcen_2 |
RFM22_header_cntl1_bcen_3 |
RFM22_header_cntl1_hdch_0 |
RFM22_header_cntl1_hdch_1 |
RFM22_header_cntl1_hdch_2 |
RFM22_header_cntl1_hdch_3);
// Check all bit of all bytes of the header
rfm22_write(RFM22_header_enable0, 0xff);
rfm22_write(RFM22_header_enable1, 0xff);
rfm22_write(RFM22_header_enable2, 0xff);
rfm22_write(RFM22_header_enable3, 0xff);
// Set the ID to be checked
rfm22_write(RFM22_check_header0, 0x11);
rfm22_write(RFM22_check_header1, 0x22);
rfm22_write(RFM22_check_header2, 0x33);
rfm22_write(RFM22_check_header3, 0x44);
// Set our address in the transmit header.
rfm22_write(RFM22_transmit_header0, 0x11);
rfm22_write(RFM22_transmit_header1, 0x22);
rfm22_write(RFM22_transmit_header2, 0x33);
rfm22_write(RFM22_transmit_header3, 0x44);
// 4 header bytes, synchronization word length 3, 2, 1 & 0 used, packet length included in header.
rfm22_write(RFM22_header_control2,
RFM22_header_cntl2_hdlen_3210 |
RFM22_header_cntl2_synclen_3210 |
((TX_PREAMBLE_NIBBLES >> 8) & 0x01));
#endif
// sync word
rfm22_write(RFM22_sync_word3, SYNC_BYTE_1);

View File

@ -32,7 +32,23 @@
#define PIOS_RFM22B_H
/* Global Types */
struct pios_rfm22b_cfg {
uint32_t frequencyHz;
uint32_t minFrequencyHz;
uint32_t maxFrequencyHz;
uint8_t RFXtalCap;
uint32_t maxRFBandwidth;
uint8_t maxTxPower;
uint32_t sendTimeout;
uint8_t minPacketSize;
uint8_t txWinSize;
uint8_t maxConnections;
};
/* Public Functions */
extern int32_t PIOS_RFM22B_Init(uint32_t *rfb22b_id, const struct pios_rfm22b_cfg *cfg);
extern uint32_t PIOS_RFM22B_DeviceID(uint32_t rfb22b_id);
extern int16_t PIOS_RFM22B_RSSI(uint32_t rfb22b_id);
#endif /* PIOS_RFM22B_H */

View File

@ -37,21 +37,6 @@
extern const struct pios_com_driver pios_rfm22b_com_driver;
struct pios_rfm22b_cfg {
uint32_t frequencyHz;
uint32_t minFrequencyHz;
uint32_t maxFrequencyHz;
uint8_t RFXtalCap;
uint32_t maxRFBandwidth;
uint8_t maxTxPower;
uint32_t sendTimeout;
uint8_t minPacketSize;
uint8_t txWinSize;
uint8_t maxConnections;
};
extern int32_t PIOS_RFM22B_Init(uint32_t *rfb22b_id, const struct pios_rfm22b_cfg *cfg);
// ************************************
#define RFM22_DEVICE_VERSION_V2 0x02
@ -410,11 +395,13 @@ enum { RX_SCAN_SPECTRUM = 0,
#define RFM22_header_cntl1_bcen_none 0x00 // No broadcast address enable.
#define RFM22_header_cntl1_bcen_0 0x10 // Broadcast address enable for header byte 0.
#define RFM22_header_cntl1_bcen_1 0x20 // Broadcast address enable for header byte 1.
#define RFM22_header_cntl1_bcen_01 0x30 // Broadcast address enable for header bytes 0 & 1.
#define RFM22_header_cntl1_bcen_2 0x40 // Broadcast address enable for header byte 2.
#define RFM22_header_cntl1_bcen_3 0x80 // Broadcast address enable for header byte 3.
#define RFM22_header_cntl1_hdch_none 0x00 // No Received Header check
#define RFM22_header_cntl1_hdch_0 0x01 // Received Header check for byte 0.
#define RFM22_header_cntl1_hdch_1 0x02 // Received Header check for byte 1.
#define RFM22_header_cntl1_hdch_01 0x03 // Received Header check for bytes 0 & 1.
#define RFM22_header_cntl1_hdch_2 0x04 // Received Header check for byte 2.
#define RFM22_header_cntl1_hdch_3 0x08 // Received Header check for byte 3.
#define RFM22_header_control2 0x33 // R/W
#define RFM22_header_cntl2_prealen 0x01 // MSB of Preamble Length. See register Preamble Length.

View File

@ -138,6 +138,8 @@ endif
## UAVOBJECTS
ifndef TESTAPP
SRC += $(OPUAVSYNTHDIR)/gcsreceiver.c
SRC += $(OPUAVSYNTHDIR)/pipxstatus.c
SRC += $(OPUAVSYNTHDIR)/pipxsettings.c
endif

View File

@ -52,6 +52,7 @@ uint32_t pios_com_vcp_usb_id;
uint32_t pios_com_usart1_id;
uint32_t pios_com_usart3_id;
uint32_t pios_com_rfm22b_id;
uint32_t pios_rfm22b_id;
/**
* PIOS_Board_Init()
@ -99,18 +100,6 @@ void PIOS_Board_Init(void) {
#endif /* PIOS_INCLUDE_TIM */
#if defined(PIOS_INCLUDE_PACKET_HANDLER)
// Create our (hopefully) unique 32 bit id from the processor serial number.
uint32_t crc32 = 0;
{
char serial_no_str[33];
PIOS_SYS_SerialNumberGet(serial_no_str);
// Create a 32 bit value using 4 8 bit CRC values.
crc32 = PIOS_CRC_updateCRC(0, (uint8_t*)serial_no_str, 8) << 24;
crc32 |= PIOS_CRC_updateCRC(0, (uint8_t*)serial_no_str + 8, 8) << 16;
crc32 |= PIOS_CRC_updateCRC(0, (uint8_t*)serial_no_str + 16, 8) << 8;
crc32 |= PIOS_CRC_updateCRC(0, (uint8_t*)serial_no_str + 24, 8);
}
pios_ph_cfg.id = crc32;
pios_packet_handler = PHInitialize(&pios_ph_cfg);
#endif /* PIOS_INCLUDE_PACKET_HANDLER */
@ -220,7 +209,6 @@ void PIOS_Board_Init(void) {
#if defined(PIOS_INCLUDE_RFM22B)
/* Initalize the RFM22B radio COM device. */
{
uint32_t pios_rfm22b_id;
if (PIOS_RFM22B_Init(&pios_rfm22b_id, &pios_rfm22b_cfg)) {
PIOS_Assert(0);
}

View File

@ -483,7 +483,8 @@ const struct pios_rfm22b_cfg pios_rfm22b_cfg = {
.maxFrequencyHz = 434000000 + 2000000,
.RFXtalCap = 0x7f,
.maxRFBandwidth = 128000,
.maxTxPower = RFM22_tx_pwr_txpow_0, // +1dBm ... 1.25mW
//.maxTxPower = RFM22_tx_pwr_txpow_0, // +1dBm ... 1.25mW
.maxTxPower = RFM22_tx_pwr_txpow_7, // +20dBm .. 100mW
.sendTimeout = 15, /* ms */
.minPacketSize = 50,
.txWinSize = 4,

View File

@ -1,12 +1,12 @@
/**
******************************************************************************
*
* @file pipxtremegadgetwidget.cpp
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
* @addtogroup GCSPlugins GCS Plugins
* @{
* @{
*****************************************************************************/
******************************************************************************
*
* @file pipxtremegadgetwidget.cpp
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
* @addtogroup GCSPlugins GCS Plugins
* @{
* @{
*****************************************************************************/
/*
* 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
@ -31,6 +31,8 @@
#include <QFileDialog>
#include <stdlib.h>
#include <pipxsettings.h>
#include <pipxstatus.h>
#include "pipxtremegadgetwidget.h"
#define NO_PORT 0
@ -86,38 +88,38 @@ enum {
#define Poly32 0x04c11db7 // 32-bit polynomial .. this should produce the same as the STM32 hardware CRC
uint32_t CRC_Table32[] = {
0x00000000, 0x04c11db7, 0x09823b6e, 0x0d4326d9, 0x130476dc, 0x17c56b6b, 0x1a864db2, 0x1e475005,
0x2608edb8, 0x22c9f00f, 0x2f8ad6d6, 0x2b4bcb61, 0x350c9b64, 0x31cd86d3, 0x3c8ea00a, 0x384fbdbd,
0x4c11db70, 0x48d0c6c7, 0x4593e01e, 0x4152fda9, 0x5f15adac, 0x5bd4b01b, 0x569796c2, 0x52568b75,
0x6a1936c8, 0x6ed82b7f, 0x639b0da6, 0x675a1011, 0x791d4014, 0x7ddc5da3, 0x709f7b7a, 0x745e66cd,
0x9823b6e0, 0x9ce2ab57, 0x91a18d8e, 0x95609039, 0x8b27c03c, 0x8fe6dd8b, 0x82a5fb52, 0x8664e6e5,
0xbe2b5b58, 0xbaea46ef, 0xb7a96036, 0xb3687d81, 0xad2f2d84, 0xa9ee3033, 0xa4ad16ea, 0xa06c0b5d,
0xd4326d90, 0xd0f37027, 0xddb056fe, 0xd9714b49, 0xc7361b4c, 0xc3f706fb, 0xceb42022, 0xca753d95,
0xf23a8028, 0xf6fb9d9f, 0xfbb8bb46, 0xff79a6f1, 0xe13ef6f4, 0xe5ffeb43, 0xe8bccd9a, 0xec7dd02d,
0x34867077, 0x30476dc0, 0x3d044b19, 0x39c556ae, 0x278206ab, 0x23431b1c, 0x2e003dc5, 0x2ac12072,
0x128e9dcf, 0x164f8078, 0x1b0ca6a1, 0x1fcdbb16, 0x018aeb13, 0x054bf6a4, 0x0808d07d, 0x0cc9cdca,
0x7897ab07, 0x7c56b6b0, 0x71159069, 0x75d48dde, 0x6b93dddb, 0x6f52c06c, 0x6211e6b5, 0x66d0fb02,
0x5e9f46bf, 0x5a5e5b08, 0x571d7dd1, 0x53dc6066, 0x4d9b3063, 0x495a2dd4, 0x44190b0d, 0x40d816ba,
0xaca5c697, 0xa864db20, 0xa527fdf9, 0xa1e6e04e, 0xbfa1b04b, 0xbb60adfc, 0xb6238b25, 0xb2e29692,
0x8aad2b2f, 0x8e6c3698, 0x832f1041, 0x87ee0df6, 0x99a95df3, 0x9d684044, 0x902b669d, 0x94ea7b2a,
0xe0b41de7, 0xe4750050, 0xe9362689, 0xedf73b3e, 0xf3b06b3b, 0xf771768c, 0xfa325055, 0xfef34de2,
0xc6bcf05f, 0xc27dede8, 0xcf3ecb31, 0xcbffd686, 0xd5b88683, 0xd1799b34, 0xdc3abded, 0xd8fba05a,
0x690ce0ee, 0x6dcdfd59, 0x608edb80, 0x644fc637, 0x7a089632, 0x7ec98b85, 0x738aad5c, 0x774bb0eb,
0x4f040d56, 0x4bc510e1, 0x46863638, 0x42472b8f, 0x5c007b8a, 0x58c1663d, 0x558240e4, 0x51435d53,
0x251d3b9e, 0x21dc2629, 0x2c9f00f0, 0x285e1d47, 0x36194d42, 0x32d850f5, 0x3f9b762c, 0x3b5a6b9b,
0x0315d626, 0x07d4cb91, 0x0a97ed48, 0x0e56f0ff, 0x1011a0fa, 0x14d0bd4d, 0x19939b94, 0x1d528623,
0xf12f560e, 0xf5ee4bb9, 0xf8ad6d60, 0xfc6c70d7, 0xe22b20d2, 0xe6ea3d65, 0xeba91bbc, 0xef68060b,
0xd727bbb6, 0xd3e6a601, 0xdea580d8, 0xda649d6f, 0xc423cd6a, 0xc0e2d0dd, 0xcda1f604, 0xc960ebb3,
0xbd3e8d7e, 0xb9ff90c9, 0xb4bcb610, 0xb07daba7, 0xae3afba2, 0xaafbe615, 0xa7b8c0cc, 0xa379dd7b,
0x9b3660c6, 0x9ff77d71, 0x92b45ba8, 0x9675461f, 0x8832161a, 0x8cf30bad, 0x81b02d74, 0x857130c3,
0x5d8a9099, 0x594b8d2e, 0x5408abf7, 0x50c9b640, 0x4e8ee645, 0x4a4ffbf2, 0x470cdd2b, 0x43cdc09c,
0x7b827d21, 0x7f436096, 0x7200464f, 0x76c15bf8, 0x68860bfd, 0x6c47164a, 0x61043093, 0x65c52d24,
0x119b4be9, 0x155a565e, 0x18197087, 0x1cd86d30, 0x029f3d35, 0x065e2082, 0x0b1d065b, 0x0fdc1bec,
0x3793a651, 0x3352bbe6, 0x3e119d3f, 0x3ad08088, 0x2497d08d, 0x2056cd3a, 0x2d15ebe3, 0x29d4f654,
0xc5a92679, 0xc1683bce, 0xcc2b1d17, 0xc8ea00a0, 0xd6ad50a5, 0xd26c4d12, 0xdf2f6bcb, 0xdbee767c,
0xe3a1cbc1, 0xe760d676, 0xea23f0af, 0xeee2ed18, 0xf0a5bd1d, 0xf464a0aa, 0xf9278673, 0xfde69bc4,
0x89b8fd09, 0x8d79e0be, 0x803ac667, 0x84fbdbd0, 0x9abc8bd5, 0x9e7d9662, 0x933eb0bb, 0x97ffad0c,
0xafb010b1, 0xab710d06, 0xa6322bdf, 0xa2f33668, 0xbcb4666d, 0xb8757bda, 0xb5365d03, 0xb1f740b4
0x00000000, 0x04c11db7, 0x09823b6e, 0x0d4326d9, 0x130476dc, 0x17c56b6b, 0x1a864db2, 0x1e475005,
0x2608edb8, 0x22c9f00f, 0x2f8ad6d6, 0x2b4bcb61, 0x350c9b64, 0x31cd86d3, 0x3c8ea00a, 0x384fbdbd,
0x4c11db70, 0x48d0c6c7, 0x4593e01e, 0x4152fda9, 0x5f15adac, 0x5bd4b01b, 0x569796c2, 0x52568b75,
0x6a1936c8, 0x6ed82b7f, 0x639b0da6, 0x675a1011, 0x791d4014, 0x7ddc5da3, 0x709f7b7a, 0x745e66cd,
0x9823b6e0, 0x9ce2ab57, 0x91a18d8e, 0x95609039, 0x8b27c03c, 0x8fe6dd8b, 0x82a5fb52, 0x8664e6e5,
0xbe2b5b58, 0xbaea46ef, 0xb7a96036, 0xb3687d81, 0xad2f2d84, 0xa9ee3033, 0xa4ad16ea, 0xa06c0b5d,
0xd4326d90, 0xd0f37027, 0xddb056fe, 0xd9714b49, 0xc7361b4c, 0xc3f706fb, 0xceb42022, 0xca753d95,
0xf23a8028, 0xf6fb9d9f, 0xfbb8bb46, 0xff79a6f1, 0xe13ef6f4, 0xe5ffeb43, 0xe8bccd9a, 0xec7dd02d,
0x34867077, 0x30476dc0, 0x3d044b19, 0x39c556ae, 0x278206ab, 0x23431b1c, 0x2e003dc5, 0x2ac12072,
0x128e9dcf, 0x164f8078, 0x1b0ca6a1, 0x1fcdbb16, 0x018aeb13, 0x054bf6a4, 0x0808d07d, 0x0cc9cdca,
0x7897ab07, 0x7c56b6b0, 0x71159069, 0x75d48dde, 0x6b93dddb, 0x6f52c06c, 0x6211e6b5, 0x66d0fb02,
0x5e9f46bf, 0x5a5e5b08, 0x571d7dd1, 0x53dc6066, 0x4d9b3063, 0x495a2dd4, 0x44190b0d, 0x40d816ba,
0xaca5c697, 0xa864db20, 0xa527fdf9, 0xa1e6e04e, 0xbfa1b04b, 0xbb60adfc, 0xb6238b25, 0xb2e29692,
0x8aad2b2f, 0x8e6c3698, 0x832f1041, 0x87ee0df6, 0x99a95df3, 0x9d684044, 0x902b669d, 0x94ea7b2a,
0xe0b41de7, 0xe4750050, 0xe9362689, 0xedf73b3e, 0xf3b06b3b, 0xf771768c, 0xfa325055, 0xfef34de2,
0xc6bcf05f, 0xc27dede8, 0xcf3ecb31, 0xcbffd686, 0xd5b88683, 0xd1799b34, 0xdc3abded, 0xd8fba05a,
0x690ce0ee, 0x6dcdfd59, 0x608edb80, 0x644fc637, 0x7a089632, 0x7ec98b85, 0x738aad5c, 0x774bb0eb,
0x4f040d56, 0x4bc510e1, 0x46863638, 0x42472b8f, 0x5c007b8a, 0x58c1663d, 0x558240e4, 0x51435d53,
0x251d3b9e, 0x21dc2629, 0x2c9f00f0, 0x285e1d47, 0x36194d42, 0x32d850f5, 0x3f9b762c, 0x3b5a6b9b,
0x0315d626, 0x07d4cb91, 0x0a97ed48, 0x0e56f0ff, 0x1011a0fa, 0x14d0bd4d, 0x19939b94, 0x1d528623,
0xf12f560e, 0xf5ee4bb9, 0xf8ad6d60, 0xfc6c70d7, 0xe22b20d2, 0xe6ea3d65, 0xeba91bbc, 0xef68060b,
0xd727bbb6, 0xd3e6a601, 0xdea580d8, 0xda649d6f, 0xc423cd6a, 0xc0e2d0dd, 0xcda1f604, 0xc960ebb3,
0xbd3e8d7e, 0xb9ff90c9, 0xb4bcb610, 0xb07daba7, 0xae3afba2, 0xaafbe615, 0xa7b8c0cc, 0xa379dd7b,
0x9b3660c6, 0x9ff77d71, 0x92b45ba8, 0x9675461f, 0x8832161a, 0x8cf30bad, 0x81b02d74, 0x857130c3,
0x5d8a9099, 0x594b8d2e, 0x5408abf7, 0x50c9b640, 0x4e8ee645, 0x4a4ffbf2, 0x470cdd2b, 0x43cdc09c,
0x7b827d21, 0x7f436096, 0x7200464f, 0x76c15bf8, 0x68860bfd, 0x6c47164a, 0x61043093, 0x65c52d24,
0x119b4be9, 0x155a565e, 0x18197087, 0x1cd86d30, 0x029f3d35, 0x065e2082, 0x0b1d065b, 0x0fdc1bec,
0x3793a651, 0x3352bbe6, 0x3e119d3f, 0x3ad08088, 0x2497d08d, 0x2056cd3a, 0x2d15ebe3, 0x29d4f654,
0xc5a92679, 0xc1683bce, 0xcc2b1d17, 0xc8ea00a0, 0xd6ad50a5, 0xd26c4d12, 0xdf2f6bcb, 0xdbee767c,
0xe3a1cbc1, 0xe760d676, 0xea23f0af, 0xeee2ed18, 0xf0a5bd1d, 0xf464a0aa, 0xf9278673, 0xfde69bc4,
0x89b8fd09, 0x8d79e0be, 0x803ac667, 0x84fbdbd0, 0x9abc8bd5, 0x9e7d9662, 0x933eb0bb, 0x97ffad0c,
0xafb010b1, 0xab710d06, 0xa6322bdf, 0xa2f33668, 0xbcb4666d, 0xb8757bda, 0xb5365d03, 0xb1f740b4
};
// ***************************************************************************************
@ -132,11 +134,20 @@ PipXtremeGadgetWidget::PipXtremeGadgetWidget(QWidget *parent) :
m_widget = new Ui_PipXtremeWidget();
m_widget->setupUi(this);
#if QT_VERSION >= 0x040700
qsrand(QDateTime::currentDateTime().toMSecsSinceEpoch());
#else
qsrand(QDateTime::currentDateTime().toTime_t());
#endif
#if QT_VERSION >= 0x040700
qsrand(QDateTime::currentDateTime().toMSecsSinceEpoch());
#else
qsrand(QDateTime::currentDateTime().toTime_t());
#endif
// Connect to the PipXStatus object updates
ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance();
UAVObjectManager *objManager = pm->getObject<UAVObjectManager>();
pipxStatusObj = dynamic_cast<UAVDataObject*>(objManager->getObject("PipXStatus"));
if (pipxStatusObj != NULL ) {
connect(pipxStatusObj, SIGNAL(objectUpdated(UAVObject*)), this, SLOT(updateStatus(UAVObject*)));
} else {
qDebug() << "Error: Object is unknown (PipXStatus).";
}
device_input_buffer.size = 8192;
device_input_buffer.used = 0;
@ -154,11 +165,11 @@ PipXtremeGadgetWidget::PipXtremeGadgetWidget(QWidget *parent) :
m_widget->comboBox_SerialBaudrate->addItem("38400", 38400);
m_widget->comboBox_SerialBaudrate->addItem("57600", 57600);
m_widget->comboBox_SerialBaudrate->addItem("115200", 115200);
#if (defined Q_OS_WIN)
m_widget->comboBox_SerialBaudrate->addItem("230400", 230400);
m_widget->comboBox_SerialBaudrate->addItem("460800", 460800);
m_widget->comboBox_SerialBaudrate->addItem("921600", 921600);
#endif
#if (defined Q_OS_WIN)
m_widget->comboBox_SerialBaudrate->addItem("230400", 230400);
m_widget->comboBox_SerialBaudrate->addItem("460800", 460800);
m_widget->comboBox_SerialBaudrate->addItem("921600", 921600);
#endif
m_widget->comboBox_SerialBaudrate->setCurrentIndex(m_widget->comboBox_SerialBaudrate->findText("57600"));
m_widget->comboBox_Mode->clear();
@ -218,15 +229,15 @@ PipXtremeGadgetWidget::PipXtremeGadgetWidget(QWidget *parent) :
m_widget->graphicsView_Spectrum->setCacheMode(QGraphicsView::CacheBackground);
m_widget->graphicsView_Spectrum->setRenderHints(QPainter::Antialiasing | QPainter::TextAntialiasing | QPainter::SmoothPixmapTransform | QPainter::HighQualityAntialiasing);
QGraphicsScene *spec_scene = m_widget->graphicsView_Spectrum->scene();
if (spec_scene)
{
if (spec_scene)
{
spec_scene->setBackgroundBrush(QColor(80, 80, 80));
spec_scene->clear();
spec_scene->clear();
// spec_scene->addItem(m_background);
// spec_scene->addItem(m_joystickEnd);
// spec_scene->setSceneRect(m_background->boundingRect());
}
}
m_widget->pushButton_Save->setEnabled(false);
m_widget->pushButton_ScanSpectrum->setEnabled(false);
@ -269,32 +280,69 @@ PipXtremeGadgetWidget::~PipXtremeGadgetWidget()
disconnectPort(false);
device_input_buffer.mutex.lock();
if (device_input_buffer.buffer)
{
delete [] device_input_buffer.buffer;
device_input_buffer.buffer = NULL;
device_input_buffer.size = 0;
device_input_buffer.used = 0;
}
if (device_input_buffer.buffer)
{
delete [] device_input_buffer.buffer;
device_input_buffer.buffer = NULL;
device_input_buffer.size = 0;
device_input_buffer.used = 0;
}
device_input_buffer.mutex.unlock();
}
/*!
\brief Called by updates to @PipXStatus
*/
void PipXtremeGadgetWidget::updateStatus(UAVObject *object) {
UAVObjectField* rssiField = object->getField("RSSI");
if (rssiField) {
m_widget->widgetRSSI->setValue(rssiField->getDouble());
} else {
qDebug() << "PipXtremeGadgetWidget: Count not read RSSI field.";
}
UAVObjectField* idField = object->getField("DeviceID");
if (idField) {
m_widget->lineEdit_SerialNumber->setText(QString::number(idField->getValue().toInt(), 16).toUpper());
} else {
qDebug() << "PipXtremeGadgetWidget: Count not read RSSI field.";
}
UAVObjectField* linkField = object->getField("linkState");
if (idField) {
char *msg = "Unknown";
switch (linkField->getValue().toInt())
{
case PipXStatus::LINKSTATE_DISCONNECTED:
msg = "Disconnected";
break;
case PipXStatus::LINKSTATE_CONNECTING:
msg = "Connecting";
break;
case PipXStatus::LINKSTATE_CONNECTED:
msg = "Connected";
break;
}
m_widget->lineEdit_LinkState->setText(msg);
} else {
qDebug() << "PipXtremeGadgetWidget: Count not read link state field.";
}
}
// ***************************************************************************************
void PipXtremeGadgetWidget::resizeEvent(QResizeEvent *event)
{
if (m_widget)
{
{
if (m_widget->graphicsView_Spectrum)
{
{
QGraphicsScene *spec_scene = m_widget->graphicsView_Spectrum->scene();
if (spec_scene)
{
if (spec_scene)
{
// spec_scene->setSceneRect(QRect(QPoint(0, 0), event->size()));
// spec_scene->setBackgroundBrush(Qt::black);
}
}
}
}
}
}
// PipXtremeGadgetWidget::resizeEvent(event);
}
@ -350,13 +398,13 @@ QString PipXtremeGadgetWidget::getSerialPortDevice(const QString &friendName)
foreach (QextPortInfo port, ports)
{
#ifdef Q_OS_WIN
if (port.friendName == friendName)
return port.portName;
#else
if (port.friendName == friendName)
return port.physName;
#endif
#ifdef Q_OS_WIN
if (port.friendName == friendName)
return port.portName;
#else
if (port.friendName == friendName)
return port.physName;
#endif
}
return "";
@ -364,7 +412,7 @@ QString PipXtremeGadgetWidget::getSerialPortDevice(const QString &friendName)
bool sortSerialPorts(const QextPortInfo &s1, const QextPortInfo &s2)
{
return (s1.portName < s2.portName);
return (s1.portName < s2.portName);
}
void PipXtremeGadgetWidget::getPorts()
@ -373,8 +421,8 @@ void PipXtremeGadgetWidget::getPorts()
m_widget->comboBox_Ports->clear();
// ********************************
// Populate the telemetry combo box with serial ports
// ********************************
// Populate the telemetry combo box with serial ports
QList<QextPortInfo> serial_ports = QextSerialEnumerator::getPorts();
@ -383,35 +431,35 @@ void PipXtremeGadgetWidget::getPorts()
QStringList list;
foreach (QextPortInfo port, serial_ports)
list.append(port.friendName);
list.append(port.friendName);
for (int i = 0; i < list.count(); i++)
m_widget->comboBox_Ports->addItem("com: " + list.at(i), SERIAL_PORT);
// ********************************
// Populate the telemetry combo box with usb ports
// ********************************
// Populate the telemetry combo box with usb ports
pjrc_rawhid *rawHidHandle = new pjrc_rawhid();
if (rawHidHandle)
{
int opened = rawHidHandle->open(10, 0x20A0, 0x415C, 0xFF9C, 0x0001);
if (opened > 0)
{
QList<QString> usb_ports;
pjrc_rawhid *rawHidHandle = new pjrc_rawhid();
if (rawHidHandle)
{
int opened = rawHidHandle->open(10, 0x20A0, 0x415C, 0xFF9C, 0x0001);
if (opened > 0)
{
QList<QString> usb_ports;
for (int i = 0; i < opened; i++)
usb_ports.append(rawHidHandle->getserial(i));
for (int i = 0; i < opened; i++)
usb_ports.append(rawHidHandle->getserial(i));
qSort(usb_ports.begin(), usb_ports.end());
for (int i = 0; i < usb_ports.count(); i++)
m_widget->comboBox_Ports->addItem("usb: " + usb_ports.at(i), USB_PORT);
}
}
delete rawHidHandle;
}
delete rawHidHandle;
}
// ********************************
// ********************************
connect(m_widget->comboBox_Ports, SIGNAL(currentIndexChanged(int)), this, SLOT(onComboBoxPorts_currentIndexChanged(int)));
@ -477,11 +525,11 @@ void PipXtremeGadgetWidget::enableTelemetry()
void PipXtremeGadgetWidget::randomiseAESKey()
{
#if QT_VERSION >= 0x040700
uint32_t crc = ((uint32_t)qrand() << 16) ^ qrand() ^ QDateTime::currentDateTime().toMSecsSinceEpoch(); // only available with Qt 4.7.1 and later
#else
uint32_t crc = ((uint32_t)qrand() << 16) ^ qrand() ^ QDateTime::currentDateTime().toTime_t();
#endif
#if QT_VERSION >= 0x040700
uint32_t crc = ((uint32_t)qrand() << 16) ^ qrand() ^ QDateTime::currentDateTime().toMSecsSinceEpoch(); // only available with Qt 4.7.1 and later
#else
uint32_t crc = ((uint32_t)qrand() << 16) ^ qrand() ^ QDateTime::currentDateTime().toTime_t();
#endif
QString key = "";
for (int i = 0; i < 4; i++)
@ -614,8 +662,8 @@ void PipXtremeGadgetWidget::sendRequestDetails(uint32_t serial_number)
Q_UNUSED(bytes_written)
// *****************
}
// *****************
}
void PipXtremeGadgetWidget::sendRequestSettings(uint32_t serial_number)
{
@ -649,8 +697,8 @@ void PipXtremeGadgetWidget::sendRequestSettings(uint32_t serial_number)
// error("Bytes written", bytes_written); // TEST ONLY
// *****************
}
// *****************
}
void PipXtremeGadgetWidget::sendRequestState(uint32_t serial_number)
{
@ -684,8 +732,8 @@ void PipXtremeGadgetWidget::sendRequestState(uint32_t serial_number)
// error("Bytes written", bytes_written); // TEST ONLY
// *****************
}
// *****************
}
void PipXtremeGadgetWidget::sendSettings(uint32_t serial_number, t_pipx_config_settings *settings)
{
@ -726,8 +774,8 @@ void PipXtremeGadgetWidget::sendSettings(uint32_t serial_number, t_pipx_config_s
Q_UNUSED(bytes_written)
// *****************
}
// *****************
}
// ***************************************************************************************
// process rx stream data
@ -864,179 +912,164 @@ void PipXtremeGadgetWidget::processRxPacket(quint8 *packet, int packet_size)
switch (header->type)
{
case PIPX_PACKET_TYPE_REQ_DETAILS:
break;
case PIPX_PACKET_TYPE_REQ_DETAILS:
break;
case PIPX_PACKET_TYPE_DETAILS:
if (m_stage == PIPX_REQ_DETAILS)
case PIPX_PACKET_TYPE_DETAILS:
if (m_stage == PIPX_REQ_DETAILS)
{
m_stage_retries = 0;
m_stage = PIPX_REQ_SETTINGS;
if (packet_size < (int)sizeof(t_pipx_config_header) + (int)sizeof(t_pipx_config_details))
break; // packet size is too small - error
memcpy(&pipx_config_details, data, sizeof(t_pipx_config_details));
if (pipx_config_details.major_version < 0 || (pipx_config_details.major_version <= 0 && pipx_config_details.minor_version < 6))
{
m_stage_retries = 0;
m_stage = PIPX_REQ_SETTINGS;
QMessageBox msgBox;
msgBox.setIcon(QMessageBox::Critical);
msgBox.setText("You need to update your PipX modem firmware to V0.5 or later");
msgBox.exec();
disconnectPort(true);
return;
}
if (packet_size < (int)sizeof(t_pipx_config_header) + (int)sizeof(t_pipx_config_details))
break; // packet size is too small - error
m_widget->lineEdit_FirmwareVersion->setText(QString::number(pipx_config_details.major_version) + "." + QString::number(pipx_config_details.minor_version));
memcpy(&pipx_config_details, data, sizeof(t_pipx_config_details));
m_widget->lineEdit_SerialNumber->setText(QString::number(pipx_config_details.serial_number, 16).toUpper());
if (pipx_config_details.major_version < 0 || (pipx_config_details.major_version <= 0 && pipx_config_details.minor_version < 6))
{
QMessageBox msgBox;
msgBox.setIcon(QMessageBox::Critical);
msgBox.setText("You need to update your PipX modem firmware to V0.5 or later");
msgBox.exec();
disconnectPort(true);
return;
}
m_widget->lineEdit_FirmwareVersion->setText(QString::number(pipx_config_details.major_version) + "." + QString::number(pipx_config_details.minor_version));
m_widget->lineEdit_SerialNumber->setText(QString::number(pipx_config_details.serial_number, 16).toUpper());
if (pipx_config_details.frequency_band == FREQBAND_434MHz)
m_widget->lineEdit_FrequencyBand->setText("434MHz");
else
if (pipx_config_details.frequency_band == FREQBAND_434MHz)
m_widget->lineEdit_FrequencyBand->setText("434MHz");
else
if (pipx_config_details.frequency_band == FREQBAND_868MHz)
m_widget->lineEdit_FrequencyBand->setText("868MHz");
else
if (pipx_config_details.frequency_band == FREQBAND_915MHz)
m_widget->lineEdit_FrequencyBand->setText("915MHz");
else
m_widget->lineEdit_FrequencyBand->setText("UNKNOWN [" + QString::number(pipx_config_details.frequency_band) + "]");
if (pipx_config_details.frequency_band == FREQBAND_915MHz)
m_widget->lineEdit_FrequencyBand->setText("915MHz");
else
m_widget->lineEdit_FrequencyBand->setText("UNKNOWN [" + QString::number(pipx_config_details.frequency_band) + "]");
m_widget->lineEdit_MinFrequency->setText(QString::number((double)pipx_config_details.min_frequency_Hz / 1e6, 'f', 6) + "MHz");
m_widget->lineEdit_MaxFrequency->setText(QString::number((double)pipx_config_details.max_frequency_Hz / 1e6, 'f', 6) + "MHz");
m_widget->lineEdit_MinFrequency->setText(QString::number((double)pipx_config_details.min_frequency_Hz / 1e6, 'f', 6) + "MHz");
m_widget->lineEdit_MaxFrequency->setText(QString::number((double)pipx_config_details.max_frequency_Hz / 1e6, 'f', 6) + "MHz");
m_widget->doubleSpinBox_Frequency->setMinimum((double)pipx_config_details.min_frequency_Hz / 1e6);
m_widget->doubleSpinBox_Frequency->setMaximum((double)pipx_config_details.max_frequency_Hz / 1e6);
m_widget->doubleSpinBox_Frequency->setSingleStep(((double)pipx_config_details.frequency_step_size * 4) / 1e6);
m_widget->doubleSpinBox_Frequency->setMinimum((double)pipx_config_details.min_frequency_Hz / 1e6);
m_widget->doubleSpinBox_Frequency->setMaximum((double)pipx_config_details.max_frequency_Hz / 1e6);
m_widget->doubleSpinBox_Frequency->setSingleStep(((double)pipx_config_details.frequency_step_size * 4) / 1e6);
m_widget->lineEdit_FrequencyStepSize->setText(QString::number(pipx_config_details.frequency_step_size, 'f', 2) + "Hz");
m_widget->lineEdit_FrequencyStepSize->setText(QString::number(pipx_config_details.frequency_step_size, 'f', 2) + "Hz");
m_widget->pushButton_Save->setEnabled(true);
m_widget->pushButton_ScanSpectrum->setEnabled(true);
m_widget->pushButton_Import->setEnabled(true);
m_widget->pushButton_Export->setEnabled(true);
}
break;
m_widget->pushButton_Save->setEnabled(true);
m_widget->pushButton_ScanSpectrum->setEnabled(true);
m_widget->pushButton_Import->setEnabled(true);
m_widget->pushButton_Export->setEnabled(true);
}
break;
case PIPX_PACKET_TYPE_REQ_SETTINGS:
break;
case PIPX_PACKET_TYPE_REQ_SETTINGS:
break;
case PIPX_PACKET_TYPE_SETTINGS:
if (m_stage == PIPX_REQ_SETTINGS && pipx_config_details.serial_number != 0)
{
if (packet_size < (int)sizeof(t_pipx_config_header) + (int)sizeof(t_pipx_config_settings))
break; // packet size is too small - error
case PIPX_PACKET_TYPE_SETTINGS:
if (m_stage == PIPX_REQ_SETTINGS && pipx_config_details.serial_number != 0)
{
if (packet_size < (int)sizeof(t_pipx_config_header) + (int)sizeof(t_pipx_config_settings))
break; // packet size is too small - error
m_stage_retries = 0;
m_stage = PIPX_REQ_STATE;
m_stage_retries = 0;
m_stage = PIPX_REQ_STATE;
memcpy(&pipx_config_settings, data, sizeof(t_pipx_config_settings));
memcpy(&pipx_config_settings, data, sizeof(t_pipx_config_settings));
m_widget->comboBox_Mode->setCurrentIndex(m_widget->comboBox_Mode->findData(pipx_config_settings.mode));
m_widget->lineEdit_PairedSerialNumber->setText(QString::number(pipx_config_settings.destination_id, 16).toUpper());
m_widget->spinBox_FrequencyCalibration->setValue(pipx_config_settings.rf_xtal_cap);
m_widget->doubleSpinBox_Frequency->setValue((double)pipx_config_settings.frequency_Hz / 1e6);
m_widget->comboBox_MaxRFBandwidth->setCurrentIndex(m_widget->comboBox_MaxRFBandwidth->findData(pipx_config_settings.max_rf_bandwidth));
m_widget->comboBox_MaxRFTxPower->setCurrentIndex(m_widget->comboBox_MaxRFTxPower->findData(pipx_config_settings.max_tx_power));
m_widget->comboBox_SerialPortSpeed->setCurrentIndex(m_widget->comboBox_SerialPortSpeed->findData(pipx_config_settings.serial_baudrate));
m_widget->spinBox_RTSTime->setValue(pipx_config_settings.rts_time);
m_widget->comboBox_Mode->setCurrentIndex(m_widget->comboBox_Mode->findData(pipx_config_settings.mode));
m_widget->lineEdit_PairedSerialNumber->setText(QString::number(pipx_config_settings.destination_id, 16).toUpper());
m_widget->spinBox_FrequencyCalibration->setValue(pipx_config_settings.rf_xtal_cap);
m_widget->doubleSpinBox_Frequency->setValue((double)pipx_config_settings.frequency_Hz / 1e6);
m_widget->comboBox_MaxRFBandwidth->setCurrentIndex(m_widget->comboBox_MaxRFBandwidth->findData(pipx_config_settings.max_rf_bandwidth));
m_widget->comboBox_MaxRFTxPower->setCurrentIndex(m_widget->comboBox_MaxRFTxPower->findData(pipx_config_settings.max_tx_power));
m_widget->comboBox_SerialPortSpeed->setCurrentIndex(m_widget->comboBox_SerialPortSpeed->findData(pipx_config_settings.serial_baudrate));
m_widget->spinBox_RTSTime->setValue(pipx_config_settings.rts_time);
QString key = "";
for (int i = 0; i < (int)sizeof(pipx_config_settings.aes_key); i++)
key += QString::number(pipx_config_settings.aes_key[i], 16).rightJustified(2, '0');
m_widget->lineEdit_AESKey->setText(key);
m_widget->checkBox_AESEnable->setChecked(pipx_config_settings.aes_enable);
}
QString key = "";
for (int i = 0; i < (int)sizeof(pipx_config_settings.aes_key); i++)
key += QString::number(pipx_config_settings.aes_key[i], 16).rightJustified(2, '0');
m_widget->lineEdit_AESKey->setText(key);
m_widget->checkBox_AESEnable->setChecked(pipx_config_settings.aes_enable);
}
break;
break;
case PIPX_PACKET_TYPE_REQ_STATE:
break;
case PIPX_PACKET_TYPE_REQ_STATE:
break;
case PIPX_PACKET_TYPE_STATE:
if (m_stage == PIPX_REQ_STATE && pipx_config_details.serial_number != 0)
{
if (packet_size < (int)sizeof(t_pipx_config_header) + (int)sizeof(t_pipx_config_state))
break; // packet size is too small - error
case PIPX_PACKET_TYPE_STATE:
if (m_stage == PIPX_REQ_STATE && pipx_config_details.serial_number != 0)
{
if (packet_size < (int)sizeof(t_pipx_config_header) + (int)sizeof(t_pipx_config_state))
break; // packet size is too small - error
m_stage_retries = 0;
m_stage_retries = 0;
// m_stage = PIPX_REQ_STATE;
memcpy(&pipx_config_state, data, sizeof(t_pipx_config_state));
memcpy(&pipx_config_state, data, sizeof(t_pipx_config_state));
switch (pipx_config_state.link_state)
{
case LINK_DISCONNECTED:
m_widget->lineEdit_LinkState->setText("Disconnected");
break;
case LINK_CONNECTING:
m_widget->lineEdit_LinkState->setText("Connecting");
break;
case LINK_CONNECTED:
m_widget->lineEdit_LinkState->setText("Connected");
break;
default:
m_widget->lineEdit_LinkState->setText("Unknown [" + QString::number(pipx_config_state.link_state) + "]");
break;
}
if (pipx_config_state.rssi < m_widget->widgetRSSI->minimum())
m_widget->widgetRSSI->setValue(m_widget->widgetRSSI->minimum());
else
if (pipx_config_state.rssi < m_widget->widgetRSSI->minimum())
m_widget->widgetRSSI->setValue(m_widget->widgetRSSI->minimum());
else
if (pipx_config_state.rssi > m_widget->widgetRSSI->maximum())
m_widget->widgetRSSI->setValue(m_widget->widgetRSSI->maximum());
else
m_widget->widgetRSSI->setValue(pipx_config_state.rssi);
m_widget->label_RSSI->setText("RSSI " + QString::number(pipx_config_state.rssi) + "dBm");
m_widget->lineEdit_RxAFC->setText(QString::number(pipx_config_state.afc) + "Hz");
m_widget->lineEdit_Retries->setText(QString::number(pipx_config_state.retries));
}
m_widget->label_RSSI->setText("RSSI " + QString::number(pipx_config_state.rssi) + "dBm");
m_widget->lineEdit_RxAFC->setText(QString::number(pipx_config_state.afc) + "Hz");
m_widget->lineEdit_Retries->setText(QString::number(pipx_config_state.retries));
}
break;
break;
case PIPX_PACKET_TYPE_SPECTRUM: // a packet with scanned spectrum data
if (pipx_config_details.serial_number != 0)
case PIPX_PACKET_TYPE_SPECTRUM: // a packet with scanned spectrum data
if (pipx_config_details.serial_number != 0)
{
if (packet_size < (int)sizeof(t_pipx_config_header) + (int)sizeof(t_pipx_config_spectrum))
break; // packet size is too small - error
memcpy(&pipx_config_spectrum, data, sizeof(t_pipx_config_spectrum));
int8_t *spec_data = (int8_t *)(data + sizeof(t_pipx_config_spectrum));
if (pipx_config_spectrum.magnitudes > 0)
{
if (packet_size < (int)sizeof(t_pipx_config_header) + (int)sizeof(t_pipx_config_spectrum))
break; // packet size is too small - error
memcpy(&pipx_config_spectrum, data, sizeof(t_pipx_config_spectrum));
int8_t *spec_data = (int8_t *)(data + sizeof(t_pipx_config_spectrum));
if (pipx_config_spectrum.magnitudes > 0)
{
m_widget->label_19->setText(QString::number(pipx_config_spectrum.start_frequency) + " " + QString::number(pipx_config_spectrum.frequency_step_size) + " " + QString::number(pipx_config_spectrum.magnitudes));
m_widget->label_19->setText(QString::number(pipx_config_spectrum.start_frequency) + " " + QString::number(pipx_config_spectrum.frequency_step_size) + " " + QString::number(pipx_config_spectrum.magnitudes));
/*
QGraphicsScene *spec_scene = m_widget->graphicsView_Spectrum->scene();
if (spec_scene)
{
if (pipx_config_spectrum.start_frequency - pipx_config_details.min_frequency_Hz <= 0)
spec_scene->clear();
QGraphicsScene *spec_scene = m_widget->graphicsView_Spectrum->scene();
if (spec_scene)
{
if (pipx_config_spectrum.start_frequency - pipx_config_details.min_frequency_Hz <= 0)
spec_scene->clear();
int w = 500;
int h = 500;
int w = 500;
int h = 500;
float xscale = (float)w / (pipx_config_details.max_frequency_Hz - pipx_config_details.min_frequency_Hz);
float yscale = h / 128.0f;
float xscale = (float)w / (pipx_config_details.max_frequency_Hz - pipx_config_details.min_frequency_Hz);
float yscale = h / 128.0f;
float xs = xscale * (pipx_config_spectrum.start_frequency - pipx_config_details.min_frequency_Hz);
float xs = xscale * (pipx_config_spectrum.start_frequency - pipx_config_details.min_frequency_Hz);
for (int i = 0; i < pipx_config_spectrum.magnitudes; i++)
{
int x = -(w / 2) + xs + (xscale * i * pipx_config_spectrum.frequency_step_size);
int rssi = (int)spec_data[i] + 128;
int y = yscale * rssi;
spec_scene->addLine(x, -h / 2, x, (-h / 2) - y, QPen(Qt::green, 1, Qt::SolidLine, Qt::SquareCap));
}
}
for (int i = 0; i < pipx_config_spectrum.magnitudes; i++)
{
int x = -(w / 2) + xs + (xscale * i * pipx_config_spectrum.frequency_step_size);
int rssi = (int)spec_data[i] + 128;
int y = yscale * rssi;
spec_scene->addLine(x, -h / 2, x, (-h / 2) - y, QPen(Qt::green, 1, Qt::SolidLine, Qt::SquareCap));
}
}
*/
}
}
}
break;
break;
default:
break;
default:
break;
}
}
@ -1053,45 +1086,45 @@ void PipXtremeGadgetWidget::processStream()
switch (m_stage)
{
case PIPX_IDLE:
QTimer::singleShot(RETRY_TIME, this, SLOT(processStream()));
break;
case PIPX_IDLE:
QTimer::singleShot(RETRY_TIME, this, SLOT(processStream()));
break;
case PIPX_REQ_DETAILS:
if (++m_stage_retries > MAX_RETRIES)
{
disconnectPort(true, false);
break;
}
sendRequestDetails(0);
QTimer::singleShot(RETRY_TIME, this, SLOT(processStream()));
case PIPX_REQ_DETAILS:
if (++m_stage_retries > MAX_RETRIES)
{
disconnectPort(true, false);
break;
}
sendRequestDetails(0);
QTimer::singleShot(RETRY_TIME, this, SLOT(processStream()));
break;
case PIPX_REQ_SETTINGS:
if (++m_stage_retries > MAX_RETRIES)
{
disconnectPort(true, false);
break;
}
sendRequestSettings(pipx_config_details.serial_number);
QTimer::singleShot(RETRY_TIME, this, SLOT(processStream()));
case PIPX_REQ_SETTINGS:
if (++m_stage_retries > MAX_RETRIES)
{
disconnectPort(true, false);
break;
}
sendRequestSettings(pipx_config_details.serial_number);
QTimer::singleShot(RETRY_TIME, this, SLOT(processStream()));
break;
case PIPX_REQ_STATE:
if (++m_stage_retries > MAX_RETRIES)
{
disconnectPort(true, false);
break;
}
sendRequestState(pipx_config_details.serial_number);
QTimer::singleShot(RETRY_TIME, this, SLOT(processStream()));
case PIPX_REQ_STATE:
if (++m_stage_retries > MAX_RETRIES)
{
disconnectPort(true, false);
break;
}
sendRequestState(pipx_config_details.serial_number);
QTimer::singleShot(RETRY_TIME, this, SLOT(processStream()));
break;
default:
m_stage_retries = 0;
m_stage = PIPX_IDLE;
QTimer::singleShot(RETRY_TIME, this, SLOT(processStream()));
break;
default:
m_stage_retries = 0;
m_stage = PIPX_IDLE;
QTimer::singleShot(RETRY_TIME, this, SLOT(processStream()));
break;
}
}
@ -1175,12 +1208,12 @@ void PipXtremeGadgetWidget::connectPort()
device_str = device_str.trimmed();
}
else
if (device_str.toLower().startsWith("usb: "))
{
type = USB_PORT;
device_str.remove(0, 5);
device_str = device_str.trimmed();
}
if (device_str.toLower().startsWith("usb: "))
{
type = USB_PORT;
device_str.remove(0, 5);
device_str = device_str.trimmed();
}
// type = m_widget->comboBox_Ports->itemData(device_idx).toInt();
@ -1191,83 +1224,83 @@ void PipXtremeGadgetWidget::connectPort()
switch (type)
{
case SERIAL_PORT: // serial port
{
QString str = getSerialPortDevice(device_str);
if (str.isEmpty())
break;
case SERIAL_PORT: // serial port
{
QString str = getSerialPortDevice(device_str);
if (str.isEmpty())
break;
int br_idx = m_widget->comboBox_SerialBaudrate->currentIndex();
if (br_idx < 0)
break;
int br_idx = m_widget->comboBox_SerialBaudrate->currentIndex();
if (br_idx < 0)
break;
int baudrate = m_widget->comboBox_SerialBaudrate->itemData(br_idx).toInt();
int baudrate = m_widget->comboBox_SerialBaudrate->itemData(br_idx).toInt();
BaudRateType bdt = BAUD57600;
switch (baudrate)
{
case 1200: bdt = BAUD1200; break;
case 2400: bdt = BAUD2400; break;
case 4800: bdt = BAUD4800; break;
case 9600: bdt = BAUD9600; break;
case 19200: bdt = BAUD19200; break;
case 38400: bdt = BAUD38400; break;
case 57600: bdt = BAUD57600; break;
case 115200: bdt = BAUD115200; break;
case 128000: bdt = BAUD128000; break;
case 256000: bdt = BAUD256000; break;
#if (defined Q_OS_WIN)
case 230400: bdt = BAUD230400; break;
case 460800: bdt = BAUD460800; break;
case 921600: bdt = BAUD921600; break;
#endif
}
BaudRateType bdt = BAUD57600;
switch (baudrate)
{
case 1200: bdt = BAUD1200; break;
case 2400: bdt = BAUD2400; break;
case 4800: bdt = BAUD4800; break;
case 9600: bdt = BAUD9600; break;
case 19200: bdt = BAUD19200; break;
case 38400: bdt = BAUD38400; break;
case 57600: bdt = BAUD57600; break;
case 115200: bdt = BAUD115200; break;
case 128000: bdt = BAUD128000; break;
case 256000: bdt = BAUD256000; break;
#if (defined Q_OS_WIN)
case 230400: bdt = BAUD230400; break;
case 460800: bdt = BAUD460800; break;
case 921600: bdt = BAUD921600; break;
#endif
}
PortSettings settings;
settings.BaudRate = bdt;
settings.DataBits = DATA_8;
settings.Parity = PAR_NONE;
settings.StopBits = STOP_1;
settings.FlowControl = FLOW_OFF;
settings.Timeout_Millisec = 1000;
PortSettings settings;
settings.BaudRate = bdt;
settings.DataBits = DATA_8;
settings.Parity = PAR_NONE;
settings.StopBits = STOP_1;
settings.FlowControl = FLOW_OFF;
settings.Timeout_Millisec = 1000;
// settings.setQueryMode(QextSerialBase::EventDriven);
// QextSerialPort *serial_dev = new QextSerialPort(str, settings, QextSerialPort::Polling);
// QextSerialPort *serial_dev = new QextSerialPort(str, settings, QextSerialPort::EventDriven);
QextSerialPort *serial_dev = new QextSerialPort(str, settings);
if (!serial_dev)
break;
QextSerialPort *serial_dev = new QextSerialPort(str, settings);
if (!serial_dev)
break;
// if (!serial_dev->open(QIODevice::ReadWrite | QIODevice::Unbuffered))
if (!serial_dev->open(QIODevice::ReadWrite))
{
delete serial_dev;
break;
}
if (!serial_dev->open(QIODevice::ReadWrite))
{
delete serial_dev;
break;
}
m_ioDevice = serial_dev;
break;
}
m_ioDevice = serial_dev;
break;
}
case USB_PORT: // USB port
{
RawHID *usb_dev = new RawHID(device_str);
if (!usb_dev)
break;
case USB_PORT: // USB port
{
RawHID *usb_dev = new RawHID(device_str);
if (!usb_dev)
break;
// if (!usb_dev->open(QIODevice::ReadWrite | QIODevice::Unbuffered))
if (!usb_dev->open(QIODevice::ReadWrite))
{
delete usb_dev;
break;
}
m_ioDevice = usb_dev;
break;
}
default: // unknown port type
if (!usb_dev->open(QIODevice::ReadWrite))
{
delete usb_dev;
break;
}
m_ioDevice = usb_dev;
break;
}
default: // unknown port type
break;
}
if (!m_ioDevice)
@ -1313,12 +1346,12 @@ void PipXtremeGadgetWidget::importSettings()
QFileDialog::Options options;
QString selectedFilter;
filename = QFileDialog::getOpenFileName(this,
tr("Load from PipX settings file"),
filename,
tr("PipX settings (*.ini)"),
&selectedFilter,
options
).trimmed();
tr("Load from PipX settings file"),
filename,
tr("PipX settings (*.ini)"),
&selectedFilter,
options
).trimmed();
if (filename.isEmpty())
return;
@ -1371,25 +1404,25 @@ void PipXtremeGadgetWidget::exportSettings()
QString filename = "pipx_" + QString::number(pipx_config_details.serial_number, 16).rightJustified(8, '0') + ".ini";
filename = QFileDialog::getSaveFileName(this,
tr("Save to PipX settings file"),
filename,
tr("PipX settings (*.ini)")
).trimmed();
tr("Save to PipX settings file"),
filename,
tr("PipX settings (*.ini)")
).trimmed();
if (filename.isEmpty())
return;
/*
if (QFileInfo(filename).exists())
{
QMessageBox msgBox;
msgBox.setText(tr("File already exists."));
msgBox.setInformativeText(tr("Do you want to overwrite the existing file?"));
msgBox.setStandardButtons(QMessageBox::Ok | QMessageBox::Cancel);
msgBox.setDefaultButton(QMessageBox::Ok);
if (msgBox.exec() == QMessageBox::Ok)
QFileInfo(filename).absoluteDir().remove(QFileInfo(filename).fileName());
else
return;
}
if (QFileInfo(filename).exists())
{
QMessageBox msgBox;
msgBox.setText(tr("File already exists."));
msgBox.setInformativeText(tr("Do you want to overwrite the existing file?"));
msgBox.setStandardButtons(QMessageBox::Ok | QMessageBox::Cancel);
msgBox.setDefaultButton(QMessageBox::Ok);
if (msgBox.exec() == QMessageBox::Ok)
QFileInfo(filename).absoluteDir().remove(QFileInfo(filename).fileName());
else
return;
}
*/ QDir dir = QFileInfo(filename).absoluteDir();
if (!dir.exists())
{
@ -1422,10 +1455,10 @@ void PipXtremeGadgetWidget::exportSettings()
void PipXtremeGadgetWidget::error(QString errorString, int errorNumber)
{
QMessageBox msgBox;
msgBox.setIcon(QMessageBox::Critical);
msgBox.setText(errorString + " [" + QString::number(errorNumber) + "]");
msgBox.exec();
QMessageBox msgBox;
msgBox.setIcon(QMessageBox::Critical);
msgBox.setText(errorString + " [" + QString::number(errorNumber) + "]");
msgBox.exec();
}
// ***************************************************************************************

View File

@ -1,12 +1,12 @@
/**
******************************************************************************
*
* @file pipxtremegadgetwidget.h
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
* @addtogroup GCSPlugins GCS Plugins
* @{
* @{
*****************************************************************************/
******************************************************************************
*
* @file pipxtremegadgetwidget.h
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
* @addtogroup GCSPlugins GCS Plugins
* @{
* @{
*****************************************************************************/
/*
* 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
@ -130,22 +130,25 @@ typedef struct
class PipXtremeGadgetWidget : public QWidget
{
Q_OBJECT
Q_OBJECT
public:
PipXtremeGadgetWidget(QWidget *parent = 0);
~PipXtremeGadgetWidget();
public:
PipXtremeGadgetWidget(QWidget *parent = 0);
~PipXtremeGadgetWidget();
public slots:
void onTelemetryStart();
void onTelemetryStop();
void onTelemetryConnect();
void onTelemetryDisconnect();
public slots:
void onTelemetryStart();
void onTelemetryStop();
void onTelemetryConnect();
void onTelemetryDisconnect();
void onComboBoxPorts_currentIndexChanged(int index);
public slots:
void updateStatus(UAVObject *object1);
protected:
void resizeEvent(QResizeEvent *event);
void resizeEvent(QResizeEvent *event);
private:
typedef enum { PIPX_IDLE, PIPX_REQ_DETAILS, PIPX_REQ_SETTINGS, PIPX_REQ_STATE} PipXStage;
@ -160,6 +163,9 @@ private:
PipXStage m_stage;
int m_stage_retries;
// The PipXtreme status UAVObject
UAVDataObject* pipxStatusObj;
// QVector<quint8> buffer;
t_pipx_config_details pipx_config_details;
@ -187,12 +193,12 @@ private:
void disconnectPort(bool enable_telemetry, bool lock_stuff = true);
void connectPort();
private slots:
private slots:
void importSettings();
void exportSettings();
void connectDisconnect();
void error(QString errorString, int errorNumber);
void getPorts();
void getPorts();
void randomiseAESKey();
void scanSpectrum();
void saveToFlash();

View File

@ -74,7 +74,9 @@ HEADERS += $$UAVOBJECT_SYNTHETICS/accessorydesired.h \
$$UAVOBJECT_SYNTHETICS/attitudesettings.h \
$$UAVOBJECT_SYNTHETICS/txpidsettings.h \
$$UAVOBJECT_SYNTHETICS/cameradesired.h \
$$UAVOBJECT_SYNTHETICS/faultsettings.h
$$UAVOBJECT_SYNTHETICS/faultsettings.h \
$$UAVOBJECT_SYNTHETICS/pipxsettings.h \
$$UAVOBJECT_SYNTHETICS/pipxstatus.h
SOURCES += $$UAVOBJECT_SYNTHETICS/accessorydesired.cpp \
$$UAVOBJECT_SYNTHETICS/ahrsstatus.cpp \
@ -128,4 +130,6 @@ SOURCES += $$UAVOBJECT_SYNTHETICS/accessorydesired.cpp \
$$UAVOBJECT_SYNTHETICS/attitudesettings.cpp \
$$UAVOBJECT_SYNTHETICS/txpidsettings.cpp \
$$UAVOBJECT_SYNTHETICS/cameradesired.cpp \
$$UAVOBJECT_SYNTHETICS/faultsettings.cpp
$$UAVOBJECT_SYNTHETICS/faultsettings.cpp \
$$UAVOBJECT_SYNTHETICS/pipxsettings.cpp \
$$UAVOBJECT_SYNTHETICS/pipxstatus.cpp