1
0
mirror of https://bitbucket.org/librepilot/librepilot.git synced 2025-01-19 04:52:12 +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 { typedef struct {
uint8_t txWinSize; uint8_t txWinSize;
uint16_t maxConnections; uint16_t maxConnections;
uint32_t id;
} PacketHandlerConfig; } PacketHandlerConfig;
typedef int32_t (*PHOutputStream)(PHPacketHandle packet); typedef int32_t (*PHOutputStream)(PHPacketHandle packet);

View File

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

View File

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

View File

@ -34,7 +34,10 @@
#include <radiocombridge.h> #include <radiocombridge.h>
#include <packet_handler.h> #include <packet_handler.h>
#include <gcsreceiver.h> #include <gcsreceiver.h>
#include <pipxstatus.h>
#include <pipxsettings.h>
#include <uavtalk_priv.h> #include <uavtalk_priv.h>
#include <pios_rfm22b.h>
#include <ecc.h> #include <ecc.h>
#include <stdbool.h> #include <stdbool.h>
@ -46,10 +49,13 @@
static void radio2ComBridgeTask(void *parameters); static void radio2ComBridgeTask(void *parameters);
static void com2RadioBridgeTask(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 transmitData(uint8_t * data, int32_t length);
static int32_t transmitPacket(PHPacketHandle packet); static int32_t transmitPacket(PHPacketHandle packet);
static void receiveData(uint8_t *buf, uint8_t len); static void receiveData(uint8_t *buf, uint8_t len);
static void SendGCSReceiver(void); static void SendGCSReceiver(void);
static void SendPipXStatus(void);
static void PPMHandler(uint16_t *channels); static void PPMHandler(uint16_t *channels);
static void updateSettings(); static void updateSettings();
@ -64,6 +70,8 @@ static void updateSettings();
#define MAX_RETRIES 2 #define MAX_RETRIES 2
#define REQ_TIMEOUT_MS 10 #define REQ_TIMEOUT_MS 10
#define STATS_UPDATE_PERIOD_MS 250
// **************** // ****************
// Private types // Private types
@ -71,6 +79,7 @@ typedef struct {
// The task handles. // The task handles.
xTaskHandle radio2ComBridgeTaskHandle; xTaskHandle radio2ComBridgeTaskHandle;
xTaskHandle com2RadioBridgeTaskHandle; xTaskHandle com2RadioBridgeTaskHandle;
xTaskHandle radioStatusTaskHandle;
// The com buffers. // The com buffers.
uint8_t *radio2com_buf; uint8_t *radio2com_buf;
@ -84,15 +93,20 @@ typedef struct {
UAVTalkConnection uavTalkCon; UAVTalkConnection uavTalkCon;
// Error statistics. // Error statistics.
uint32_t com_tx_errors; uint32_t comTxErrors;
uint32_t radio_tx_errors; uint32_t comTxRetries;
uint32_t comRxErrors;
uint32_t radioTxErrors;
uint32_t radioTxRetries;
uint32_t radioRxErrors;
// The packet timeout. // The packet timeout.
portTickType send_timeout; portTickType send_timeout;
uint16_t min_packet_size; 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_gcsreceiver;
bool send_pipxstatus;
// Tracks the UAVTalk messages transmitted from radio to com. // Tracks the UAVTalk messages transmitted from radio to com.
bool uavtalk_idle; bool uavtalk_idle;
@ -117,6 +131,7 @@ static int32_t RadioComBridgeStart(void)
// Start the tasks // Start the tasks
xTaskCreate(radio2ComBridgeTask, (signed char *)"Radio2ComBridge", STACK_SIZE_BYTES/2, NULL, TASK_PRIORITY, &(data->radio2ComBridgeTaskHandle)); 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(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 #ifdef PIOS_INCLUDE_WDG
PIOS_WDG_RegisterFlag(PIOS_WDG_RADIOCOM); PIOS_WDG_RegisterFlag(PIOS_WDG_RADIOCOM);
PIOS_WDG_RegisterFlag(PIOS_WDG_COMRADIO); PIOS_WDG_RegisterFlag(PIOS_WDG_COMRADIO);
@ -140,9 +155,12 @@ static int32_t RadioComBridgeInitialize(void)
if (!data) if (!data)
return -1; return -1;
// Initialize the GCSReceiver object. // Initialize the UAVObjects that we use
GCSReceiverInitialize(); GCSReceiverInitialize();
PipXStatusInitialize();
PipXSettingsInitialize();
data->send_gcsreceiver = false; data->send_gcsreceiver = false;
data->send_pipxstatus = false;
// TODO: Get from settings object // TODO: Get from settings object
data->com_port = PIOS_COM_BRIDGE_COM; data->com_port = PIOS_COM_BRIDGE_COM;
@ -158,8 +176,12 @@ static int32_t RadioComBridgeInitialize(void)
data->uavTalkCon = UAVTalkInitialize(&transmitData); data->uavTalkCon = UAVTalkInitialize(&transmitData);
// Initialize the statistics. // Initialize the statistics.
data->com_tx_errors = 0; data->radioTxErrors = 0;
data->radio_tx_errors = 0; data->radioTxRetries = 0;
data->radioRxErrors = 0;
data->comTxErrors = 0;
data->comTxRetries = 0;
data->comRxErrors = 0;
// Register the callbacks with the packet handler // Register the callbacks with the packet handler
PHRegisterOutputStream(pios_packet_handler, transmitPacket); 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. * 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. // Send a local UAVTalk message if one is waiting to be sent.
if (data->send_gcsreceiver && data->uavtalk_idle) if (data->send_gcsreceiver && data->uavtalk_idle)
SendGCSReceiver(); SendGCSReceiver();
if (data->send_pipxstatus && data->uavtalk_idle)
SendPipXStatus();
// Parse the data for UAVTalk packets. // Parse the data for UAVTalk packets.
uint8_t sent_bytes = 0; 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; uint8_t send_bytes = len - sent_bytes;
if (PIOS_COM_SendBuffer(outputPort, buf + sent_bytes, send_bytes) != send_bytes) if (PIOS_COM_SendBuffer(outputPort, buf + sent_bytes, send_bytes) != send_bytes)
// Error on transmit // Error on transmit
data->com_tx_errors++; data->comTxErrors++;
sent_bytes = i; sent_bytes = i;
// Send any UAVTalk messages that need to be sent. // Send any UAVTalk messages that need to be sent.
if (data->send_gcsreceiver) if (data->send_gcsreceiver)
SendGCSReceiver(); SendGCSReceiver();
if (data->send_pipxstatus)
SendPipXStatus();
} }
++(data->uavtalk_packet_index); ++(data->uavtalk_packet_index);
} }
@ -387,7 +451,7 @@ static void receiveData(uint8_t *buf, uint8_t len)
uint8_t send_bytes = len - sent_bytes; uint8_t send_bytes = len - sent_bytes;
if (PIOS_COM_SendBuffer(outputPort, buf + sent_bytes, send_bytes) != send_bytes) if (PIOS_COM_SendBuffer(outputPort, buf + sent_bytes, send_bytes) != send_bytes)
// Error on transmit // Error on transmit
data->com_tx_errors++; data->comTxErrors++;
} }
/** /**
@ -407,6 +471,17 @@ static void SendGCSReceiver(void)
data->send_gcsreceiver = false; 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 * Receive a ppm packet
* \param[in] channels The ppm channels * \param[in] channels The ppm channels

View File

@ -261,9 +261,9 @@ extern uint32_t pios_com_rfm22b_id;
// RFM22 // RFM22
//------------------------- //-------------------------
extern uint32_t pios_rfm22b_id;
#define RFM22_EXT_INT_USE #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) #if defined(RFM22_EXT_INT_USE)
#define PIOS_RFM22_EXTI_GPIO_PORT GPIOA #define PIOS_RFM22_EXTI_GPIO_PORT GPIOA

View File

@ -149,14 +149,13 @@ struct pios_rfm22b_dev {
enum pios_rfm22b_dev_magic magic; enum pios_rfm22b_dev_magic magic;
const struct pios_rfm22b_cfg *cfg; const struct pios_rfm22b_cfg *cfg;
uint32_t countdownTimer; uint32_t deviceID;
// The COM callback functions.
pios_com_callback rx_in_cb; pios_com_callback rx_in_cb;
uint32_t rx_in_context; uint32_t rx_in_context;
pios_com_callback tx_out_cb; pios_com_callback tx_out_cb;
uint32_t tx_out_context; uint32_t tx_out_context;
PHPacketHandle cur_tx_packet;
}; };
uint32_t random32 = 0x459ab8d8; 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 // Bind the configuration to the device instance
rfm22b_dev->cfg = cfg; rfm22b_dev->cfg = cfg;
rfm22b_dev->cur_tx_packet = 0;
*rfm22b_id = (uint32_t)rfm22b_dev; *rfm22b_id = (uint32_t)rfm22b_dev;
// Initialize the TX pre-buffer pointer.
tx_pre_buffer_size = 0; 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. // Initialize the radio device.
DEBUG_PRINTF(2, "Init Radio\n\r");
int initval = rfm22_init_normal(cfg->minFrequencyHz, cfg->maxFrequencyHz, 50000); int initval = rfm22_init_normal(cfg->minFrequencyHz, cfg->maxFrequencyHz, 50000);
if (initval < 0) 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); rfm22_setTxPower(cfg->maxTxPower);
DEBUG_PRINTF(2, "\n\r"); 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 datarate: %dbps\n\r", rfm22_getDatarate());
DEBUG_PRINTF(2, "RF frequency: %dHz\n\r", rfm22_getNominalCarrierFrequency()); DEBUG_PRINTF(2, "RF frequency: %dHz\n\r", rfm22_getNominalCarrierFrequency());
DEBUG_PRINTF(2, "RF TX power: %d\n\r", rfm22_getTxPower()); 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); 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) 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; 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 // x-nibbles rx preamble detection
rfm22_write(RFM22_preamble_detection_ctrl1, RX_PREAMBLE_NIBBLES << 3); rfm22_write(RFM22_preamble_detection_ctrl1, RX_PREAMBLE_NIBBLES << 3);
#ifdef PIOS_RFM22_NO_HEADER
// header control - we are not using the header // header control - we are not using the header
rfm22_write(RFM22_header_control1, RFM22_header_cntl1_bcen_none | RFM22_header_cntl1_hdch_none); 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. // 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_write(RFM22_header_control2, RFM22_header_cntl2_hdlen_none |
RFM22_header_cntl2_synclen_3210 | ((TX_PREAMBLE_NIBBLES >> 8) & 0x01)); 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 // sync word
rfm22_write(RFM22_sync_word3, SYNC_BYTE_1); rfm22_write(RFM22_sync_word3, SYNC_BYTE_1);

View File

@ -32,7 +32,23 @@
#define PIOS_RFM22B_H #define PIOS_RFM22B_H
/* Global Types */ /* 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 */ /* 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 */ #endif /* PIOS_RFM22B_H */

View File

@ -37,21 +37,6 @@
extern const struct pios_com_driver pios_rfm22b_com_driver; 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 #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_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_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_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_none 0x00 // No Received Header check
#define RFM22_header_cntl1_hdch_0 0x01 // Received Header check for byte 0. #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_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_control2 0x33 // R/W
#define RFM22_header_cntl2_prealen 0x01 // MSB of Preamble Length. See register Preamble Length. #define RFM22_header_cntl2_prealen 0x01 // MSB of Preamble Length. See register Preamble Length.

View File

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

View File

@ -52,6 +52,7 @@ uint32_t pios_com_vcp_usb_id;
uint32_t pios_com_usart1_id; uint32_t pios_com_usart1_id;
uint32_t pios_com_usart3_id; uint32_t pios_com_usart3_id;
uint32_t pios_com_rfm22b_id; uint32_t pios_com_rfm22b_id;
uint32_t pios_rfm22b_id;
/** /**
* PIOS_Board_Init() * PIOS_Board_Init()
@ -99,18 +100,6 @@ void PIOS_Board_Init(void) {
#endif /* PIOS_INCLUDE_TIM */ #endif /* PIOS_INCLUDE_TIM */
#if defined(PIOS_INCLUDE_PACKET_HANDLER) #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); pios_packet_handler = PHInitialize(&pios_ph_cfg);
#endif /* PIOS_INCLUDE_PACKET_HANDLER */ #endif /* PIOS_INCLUDE_PACKET_HANDLER */
@ -220,7 +209,6 @@ void PIOS_Board_Init(void) {
#if defined(PIOS_INCLUDE_RFM22B) #if defined(PIOS_INCLUDE_RFM22B)
/* Initalize the RFM22B radio COM device. */ /* Initalize the RFM22B radio COM device. */
{ {
uint32_t pios_rfm22b_id;
if (PIOS_RFM22B_Init(&pios_rfm22b_id, &pios_rfm22b_cfg)) { if (PIOS_RFM22B_Init(&pios_rfm22b_id, &pios_rfm22b_cfg)) {
PIOS_Assert(0); PIOS_Assert(0);
} }

View File

@ -483,7 +483,8 @@ const struct pios_rfm22b_cfg pios_rfm22b_cfg = {
.maxFrequencyHz = 434000000 + 2000000, .maxFrequencyHz = 434000000 + 2000000,
.RFXtalCap = 0x7f, .RFXtalCap = 0x7f,
.maxRFBandwidth = 128000, .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 */ .sendTimeout = 15, /* ms */
.minPacketSize = 50, .minPacketSize = 50,
.txWinSize = 4, .txWinSize = 4,

View File

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

View File

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

View File

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