1
0
mirror of https://bitbucket.org/librepilot/librepilot.git synced 2025-02-20 10:54:14 +01:00

Added PipXStatus and PipXSetting UAVobjects and some initial support for them.

This commit is contained in:
Brian Webb 2012-04-17 17:36:05 -07:00
parent 78c7416bda
commit 62c5036220
10 changed files with 314 additions and 280 deletions

View File

@ -41,6 +41,7 @@ typedef enum {
PACKET_TYPE_DISCONNECT, // to tell the other modem they cannot connect to us
PACKET_TYPE_READY, // tells the other modem we are ready to accept more data
PACKET_TYPE_NOTREADY, // tells the other modem we're not ready to accept more data - we can also send user data in this packet type
PACKET_TYPE_STATUS, // broadcasts status of this modem
PACKET_TYPE_DATARATE, // for changing the RF data rate
PACKET_TYPE_PING, // used to check link is still up
PACKET_TYPE_ADJUST_TX_PWR, // used to ask the other modem to adjust it's tx power
@ -52,12 +53,14 @@ typedef enum {
} PHPacketType;
typedef struct {
uint32_t source_id;
uint32_t destination_id;
uint32_t source_id;
uint8_t type;
uint8_t data_size;
uint8_t tx_seq;
uint8_t rx_seq;
uint8_t data_size;
int8_t rssi;
int8_t afc;
} PHPacketHeader;
#define PH_MAX_DATA (PIOS_PH_MAX_PACKET - sizeof(PHPacketHeader) - RS_ECC_NPARITY)
@ -81,6 +84,7 @@ typedef struct {
typedef int32_t (*PHOutputStream)(PHPacketHandle packet);
typedef void (*PHDataHandler)(uint8_t *data, uint8_t len);
typedef void (*PHStatusHandler)(PHPacketHandle s);
typedef void (*PHPPMHandler)(uint16_t *channels);
typedef uint32_t PHInstHandle;
@ -89,13 +93,15 @@ typedef uint32_t PHInstHandle;
PHInstHandle PHInitialize(PacketHandlerConfig *cfg);
void PHRegisterOutputStream(PHInstHandle h, PHOutputStream f);
void PHRegisterDataHandler(PHInstHandle h, PHDataHandler f);
void PHRegisterStatusHandler(PHInstHandle h, PHStatusHandler f);
void PHRegisterPPMHandler(PHInstHandle h, PHPPMHandler f);
uint32_t PHConnect(PHInstHandle h, uint32_t dest_id);
PHPacketHandle PHGetRXPacket(PHInstHandle h);
PHPacketHandle PHGetTXPacket(PHInstHandle h);
void PHReleaseTXPacket(PHInstHandle h, PHPacketHandle p);
uint8_t PHTransmitPacket(PHInstHandle h, PHPacketHandle p);
uint8_t PHReceivePacket(PHInstHandle h, PHPacketHandle p);
uint8_t PHBroadcastStatus(PHInstHandle h, uint32_t id, int8_t rssi);
uint8_t PHReceivePacket(PHInstHandle h, PHPacketHandle p, uint16_t len);
#endif // __PACKET_HANDLER_H__

View File

@ -46,6 +46,7 @@ typedef struct {
xSemaphoreHandle lock;
PHOutputStream output_stream;
PHDataHandler data_handler;
PHStatusHandler status_handler;
PHPPMHandler ppm_handler;
} PHPacketData, *PHPacketDataHandle;
@ -113,6 +114,18 @@ void PHRegisterDataHandler(PHInstHandle h, PHDataHandler f)
data->data_handler = f;
}
/**
* Register a PPM packet handler
* \param[in] h The packet handler instance data pointer.
* \param[in] f The PPM handler function
*/
void PHRegisterStatusHandler(PHInstHandle h, PHStatusHandler f)
{
PHPacketDataHandle data = (PHPacketDataHandle)h;
data->status_handler = f;
}
/**
* Register a PPM packet handler
* \param[in] h The packet handler instance data pointer.
@ -232,23 +245,47 @@ uint8_t PHTransmitPacket(PHInstHandle h, PHPacketHandle p)
* Process a packet that has been received.
* \param[in] h The packet handler instance data pointer.
* \param[in] p A pointer to the packet buffer.
* \param[in] received_len The length of data received.
* \return 1 Success
* \return 0 Failure
*/
uint8_t PHReceivePacket(PHInstHandle h, PHPacketHandle p)
uint8_t PHReceivePacket(PHInstHandle h, PHPacketHandle p, uint16_t received_len)
{
PHPacketDataHandle data = (PHPacketDataHandle)h;
// Attempt to correct any errors in the packet.
// Verify the packet length.
// Note: The last two bytes should be the RSSI and AFC.
uint16_t len = PHPacketSizeECC(p);
if (received_len != (len + 2))
{
DEBUG_PRINTF(1, "Packet length error\n\r");
return 0;
}
// Attempt to correct any errors in the packet.
decode_data((unsigned char*)p, len);
// Check that there were no unfixed errors.
uint8_t rx_error = check_syndrome() != 0;
bool rx_error = check_syndrome() != 0;
if(rx_error)
DEBUG_PRINTF(1, "Error in message\n\r");
DEBUG_PRINTF(1, "Error in packet\n\r");
// Add the RSSI and AFC to the packet.
p->header.rssi = *(((int8_t*)p) + len);
p->header.afc = *(((int8_t*)p) + len + 1);
switch (p->header.type) {
case PACKET_TYPE_STATUS:
if (!rx_error)
// Pass on the channels to the PPM handler.
if(data->status_handler)
data->status_handler(p);
break;
case PACKET_TYPE_ACKED_DATA:
// Send the ACK / NACK
@ -325,6 +362,29 @@ uint8_t PHReceivePacket(PHInstHandle h, PHPacketHandle p)
return 1;
}
/**
* Broadcast a status packet.
* \param[in] data The packet handler instance data pointer.
* \param[in] p A pointer to the packet buffer.
* \return 1 Success
* \return 0 Failure
*/
uint8_t PHBroadcastStatus(PHInstHandle h, uint32_t id, int8_t rssi)
{
PHPacketDataHandle data = (PHPacketDataHandle)h;
// Create the status message
PHPacketHeader header;
header.destination_id = 0xffffffff;
header.source_id = id;
header.rssi = rssi;
header.type = PACKET_TYPE_STATUS;
header.data_size = 0;
// Send the packet.
return PHLTransmitPacket(data, (PHPacketHandle)&header);
}
/**
* Transmit a packet from the transmit packet buffer window.
* \param[in] data The packet handler instance data pointer.

View File

@ -42,7 +42,7 @@
#include <stdbool.h>
//#undef PIOS_INCLUDE_USB
#undef PIOS_INCLUDE_USB
// ****************
// Private functions
@ -50,12 +50,12 @@
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 StatusHandler(PHPacketHandle p);
static void PPMHandler(uint16_t *channels);
static void updateSettings();
@ -65,16 +65,25 @@ static void updateSettings();
#define STACK_SIZE_BYTES 300
#define TASK_PRIORITY (tskIDLE_PRIORITY + 1)
#define BRIDGE_BUF_LEN 128
#define BRIDGE_BUF_LEN 512
#define MAX_RETRIES 2
#define REQ_TIMEOUT_MS 10
#define STATS_UPDATE_PERIOD_MS 250
#define STATS_UPDATE_PERIOD_MS 500
#define RADIOSTATS_UPDATE_PERIOD_MS 500
#define MAX_LOST_CONTACT_TIME 10
// ****************
// Private types
typedef struct {
uint32_t pairID;
int8_t rssi;
uint8_t lastContact;
} PairStats;
typedef struct {
// The task handles.
xTaskHandle radio2ComBridgeTaskHandle;
@ -90,7 +99,8 @@ typedef struct {
uint32_t radio_port;
// The UAVTalk connection on the com side.
UAVTalkConnection uavTalkCon;
UAVTalkConnection inUAVTalkCon;
UAVTalkConnection outUAVTalkCon;
// Error statistics.
uint32_t comTxErrors;
@ -100,6 +110,9 @@ typedef struct {
uint32_t radioTxRetries;
uint32_t radioRxErrors;
// The destination ID
uint32_t destination_id;
// The packet timeout.
portTickType send_timeout;
uint16_t min_packet_size;
@ -113,6 +126,9 @@ typedef struct {
int16_t uavtalk_packet_len;
int16_t uavtalk_packet_index;
// Track other radios that are in range.
PairStats pairStats[PIPXSTATUS_PAIRIDS_NUMELEM];
} RadioComBridgeData;
// ****************
@ -167,13 +183,17 @@ static int32_t RadioComBridgeInitialize(void)
data->radio_port = PIOS_COM_BRIDGE_RADIO;
// Allocate the com buffers.
data->radio2com_buf = pvPortMalloc(BRIDGE_BUF_LEN);
data->radio2com_buf = pvPortMalloc(PIOS_PH_MAX_PACKET);
PIOS_Assert(data->radio2com_buf);
data->com2radio_buf = pvPortMalloc(BRIDGE_BUF_LEN);
PIOS_Assert(data->com2radio_buf);
// Initialise UAVTalk
data->uavTalkCon = UAVTalkInitialize(&transmitData);
data->inUAVTalkCon = UAVTalkInitialize(0);
data->outUAVTalkCon = UAVTalkInitialize(&transmitData);
// Initialize the destination ID
data->destination_id = 0xffffffff;
// Initialize the statistics.
data->radioTxErrors = 0;
@ -186,6 +206,7 @@ static int32_t RadioComBridgeInitialize(void)
// Register the callbacks with the packet handler
PHRegisterOutputStream(pios_packet_handler, transmitPacket);
PHRegisterDataHandler(pios_packet_handler, receiveData);
PHRegisterStatusHandler(pios_packet_handler, StatusHandler);
PHRegisterPPMHandler(pios_packet_handler, PPMHandler);
// Initialize the packet send timeout
@ -194,8 +215,16 @@ static int32_t RadioComBridgeInitialize(void)
// Initialize the rado->com UAVTalk message tracker.
data->uavtalk_idle = true;
data->uavtalk_packet_len = -1;
data->uavtalk_packet_index = -1;
data->uavtalk_packet_len = 0;
data->uavtalk_packet_index = -1; // Looking for SYNC
// Initialize the detected device statistics.
for (uint8_t i = 0; i < PIPXSTATUS_PAIRIDS_NUMELEM; ++i)
{
data->pairStats[i].pairID = 0;
data->pairStats[i].rssi = -127;
data->pairStats[i].lastContact = 0;
}
updateSettings();
@ -218,9 +247,9 @@ static void radio2ComBridgeTask(void *parameters)
#endif /* PIOS_INCLUDE_WDG */
// Receive data from the radio port
rx_bytes = PIOS_COM_ReceiveBuffer(data->radio_port, data->radio2com_buf, BRIDGE_BUF_LEN, 200);
rx_bytes = PIOS_COM_ReceiveBuffer(data->radio_port, data->radio2com_buf, PIOS_PH_MAX_PACKET, 200);
if (rx_bytes > 0)
PHReceivePacket(pios_packet_handler, (PHPacketHandle)data->radio2com_buf);
PHReceivePacket(pios_packet_handler, (PHPacketHandle)data->radio2com_buf, rx_bytes);
}
}
@ -253,11 +282,11 @@ static void com2RadioBridgeTask(void * parameters)
// Receive data from the com port
uint32_t cur_rx_bytes = PIOS_COM_ReceiveBuffer(inputPort, data->com2radio_buf +
rx_bytes, BRIDGE_BUF_LEN - rx_bytes, timeout);
rx_bytes, BRIDGE_BUF_LEN - rx_bytes, timeout);
// Pass the new data through UAVTalk
for (uint8_t i = 0; i < cur_rx_bytes; i++)
UAVTalkProcessInputStream(data->uavTalkCon, *(data->com2radio_buf + i + rx_bytes));
UAVTalkProcessInputStream(data->inUAVTalkCon, *(data->com2radio_buf + i + rx_bytes));
// Do we have an data to send?
rx_bytes += cur_rx_bytes;
@ -292,6 +321,8 @@ static void com2RadioBridgeTask(void * parameters)
// Initialize the packet.
//p->header.type = PACKET_TYPE_ACKED_DATA;
p->header.destination_id = data->destination_id;
p->header.source_id = PIOS_RFM22B_DeviceID(pios_rfm22b_id);
p->header.type = PACKET_TYPE_DATA;
p->header.data_size = rx_bytes;
@ -316,39 +347,43 @@ static void com2RadioBridgeTask(void * parameters)
static void radioStatusTask(void *parameters)
{
while (1) {
PipXStatusData pipxStatus;
#ifdef PIOS_INCLUDE_WDG
// Update the watchdog timer.
PIOS_WDG_UpdateFlag(PIOS_WDG_RADIOCOM);
#endif /* PIOS_INCLUDE_WDG */
// Get object data
PipXStatusGet(&pipxStatus);
// Update the status
updatePipXStatus();
pipxStatus.DeviceID = PIOS_RFM22B_DeviceID(pios_rfm22b_id);
pipxStatus.RSSI = PIOS_RFM22B_RSSI(pios_rfm22b_id);
// Update the potential pairing contacts
for (uint8_t i = 0; i < PIPXSTATUS_PAIRIDS_NUMELEM; ++i)
{
pipxStatus.PairIDs[i] = data->pairStats[i].pairID;
pipxStatus.PairSignalStrengths[i] = data->pairStats[i].rssi;
}
// Update the object
PipXStatusSet(&pipxStatus);
// Schedule the status for transmssion
data->send_pipxstatus = true;
// Broadcast the status.
{
static uint16_t cntr = 0;
if(cntr++ == RADIOSTATS_UPDATE_PERIOD_MS / STATS_UPDATE_PERIOD_MS)
{
PHBroadcastStatus(pios_packet_handler, pipxStatus.DeviceID, pipxStatus.RSSI);
cntr = 0;
}
}
// 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.
* \param[in] buf Data buffer to send
@ -364,7 +399,7 @@ static int32_t transmitData(uint8_t *buf, int32_t length)
if (PIOS_USB_CheckAvailable(0) && PIOS_COM_TELEM_USB)
outputPort = PIOS_COM_TELEM_USB;
#endif /* PIOS_INCLUDE_USB */
return PIOS_COM_SendBuffer(outputPort, buf, length);
return PIOS_COM_SendBufferNonBlocking(outputPort, buf, length);
}
/**
@ -376,7 +411,7 @@ static int32_t transmitData(uint8_t *buf, int32_t length)
*/
static int32_t transmitPacket(PHPacketHandle p)
{
return PIOS_COM_SendBuffer(data->radio_port, (uint8_t*)p, PH_PACKET_SIZE(p));
return PIOS_COM_SendBufferNonBlocking(data->radio_port, (uint8_t*)p, PH_PACKET_SIZE(p));
}
/**
@ -399,59 +434,43 @@ static void receiveData(uint8_t *buf, uint8_t len)
if (data->send_pipxstatus && data->uavtalk_idle)
SendPipXStatus();
// Parse the data for UAVTalk packets.
uint8_t sent_bytes = 0;
for (uint8_t i = 0; i < len; ++i)
{
uint8_t val = buf[i];
// Looking for sync value
if (data->uavtalk_packet_index == -1)
UAVTalkRxState state = UAVTalkProcessInputStream(data->outUAVTalkCon, buf[i]);
/* if(state == UAVTALK_STATE_ERROR) */
/* DEBUG_PRINTF(2, "OUT Error\n\r"); */
if((state == UAVTALK_STATE_COMPLETE) || (state == UAVTALK_STATE_SYNC))
{
if (val == UAVTALK_SYNC_VAL)
data->uavtalk_packet_index = 1;
}
else
{
if (data->uavtalk_packet_index == 2)
// Length LSB
data->uavtalk_packet_len = val;
else if (data->uavtalk_packet_index == 3)
{
// Length MSB
data->uavtalk_packet_len |= val << 8;
// Is the length valid.
if ((data->uavtalk_packet_len < UAVTALK_MIN_HEADER_LENGTH) ||
(data->uavtalk_packet_len > UAVTALK_MAX_HEADER_LENGTH + UAVTALK_MAX_PAYLOAD_LENGTH))
data->uavtalk_packet_index = -2;
}
else if (data->uavtalk_packet_index == data->uavtalk_packet_len)
{
// Packet received.
data->uavtalk_packet_index = -2;
// Send the buffer up to this point
uint8_t send_bytes = i - sent_bytes;
if (PIOS_COM_SendBufferNonBlocking(outputPort, buf + sent_bytes, send_bytes) != send_bytes)
// Error on transmit
data->comTxErrors++;
sent_bytes = i;
// Send the buffer up to this point
uint8_t send_bytes = len - sent_bytes;
if (PIOS_COM_SendBuffer(outputPort, buf + sent_bytes, send_bytes) != send_bytes)
// Error on transmit
data->comTxErrors++;
sent_bytes = i;
// The connection is now idle.
data->uavtalk_idle = true;
// Send any UAVTalk messages that need to be sent.
if (data->send_gcsreceiver)
SendGCSReceiver();
if (data->send_pipxstatus)
SendPipXStatus();
}
++(data->uavtalk_packet_index);
// 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();
}
}
// Send the received data to the com port
uint8_t send_bytes = len - sent_bytes;
if (PIOS_COM_SendBuffer(outputPort, buf + sent_bytes, send_bytes) != send_bytes)
// Error on transmit
data->comTxErrors++;
if (send_bytes > 0)
{
if (PIOS_COM_SendBufferNonBlocking(outputPort, buf + sent_bytes, send_bytes) != send_bytes)
// Error on transmit
data->comTxErrors++;
// The connection is not idle.
data->uavtalk_idle = false;
}
}
/**
@ -464,7 +483,7 @@ static void SendGCSReceiver(void)
uint32_t retries = 0;
int32_t success = -1;
while (retries < MAX_RETRIES && success == -1) {
success = UAVTalkSendObject(data->uavTalkCon, GCSReceiverHandle(), 0, 0, REQ_TIMEOUT_MS);
success = UAVTalkSendObject(data->outUAVTalkCon, GCSReceiverHandle(), 0, 0, REQ_TIMEOUT_MS);
++retries;
}
if(success >= 0)
@ -478,8 +497,61 @@ static void SendGCSReceiver(void)
static void SendPipXStatus(void)
{
// Transmit the PipXStatus
UAVTalkSendObject(data->uavTalkCon, PipXStatusHandle(), 0, 0, REQ_TIMEOUT_MS);
UAVTalkSendObject(data->outUAVTalkCon, PipXStatusHandle(), 0, 0, REQ_TIMEOUT_MS);
data->send_pipxstatus = false;
// Increment the last contact for each device
for (uint8_t i = 0; i < PIPXSTATUS_PAIRIDS_NUMELEM; ++i)
++data->pairStats[i].lastContact;
}
/**
* Receive a status packet
* \param[in] status The status structure
*/
static void StatusHandler(PHPacketHandle status)
{
uint32_t id = status->header.source_id;
// Have we seen this device recently?
uint8_t id_idx = 0;
for ( ; id_idx < PIPXSTATUS_PAIRIDS_NUMELEM; ++id_idx)
if(data->pairStats[id_idx].pairID == id)
break;
// If we have seen it, update the RSSI and reset the last contact couter
if(id_idx < PIPXSTATUS_PAIRIDS_NUMELEM)
{
data->pairStats[id_idx].rssi = status->header.rssi;
data->pairStats[id_idx].lastContact = 0;
return;
}
// Remove any contacts that we haven't seen for a while.
for (id_idx = 0; id_idx < PIPXSTATUS_PAIRIDS_NUMELEM; ++id_idx)
{
if(data->pairStats[id_idx].lastContact > MAX_LOST_CONTACT_TIME)
{
data->pairStats[id_idx].pairID = 0;
data->pairStats[id_idx].rssi = -127;
data->pairStats[id_idx].lastContact = 0;
}
}
// If we haven't seen it, find a slot to put it in.
uint8_t min_idx = 0;
int8_t min_rssi = data->pairStats[0].rssi;
for (id_idx = 1; id_idx < PIPXSTATUS_PAIRIDS_NUMELEM; ++id_idx)
{
if(data->pairStats[id_idx].rssi < min_rssi)
{
min_rssi = data->pairStats[id_idx].rssi;
min_idx = id_idx;
}
}
data->pairStats[min_idx].pairID = id;
data->pairStats[min_idx].rssi = status->header.rssi;
data->pairStats[min_idx].lastContact = 0;
}
/**

View File

@ -341,7 +341,7 @@ static uint32_t debug_val = 0;
volatile uint8_t osc_load_cap; // xtal frequency calibration value
volatile uint8_t rssi; // the current RSSI (register value)
volatile int16_t rssi_dBm; // dBm value
volatile int8_t rssi_dBm; // dBm value
// the transmit power to use for data transmissions
uint8_t tx_power;
@ -362,16 +362,15 @@ volatile uint16_t tx_data_wr;
// the current receive buffer in use (double buffer)
volatile uint8_t rx_buffer_current;
// the receive buffer .. received packet data is saved here
volatile uint8_t rx_buffer[256] __attribute__ ((aligned(4)));
volatile uint8_t rx_buffer[258] __attribute__ ((aligned(4)));
// the receive buffer write index
volatile uint16_t rx_buffer_wr;
// the received packet
volatile uint16_t rx_packet_wr; // the receive packet write index
volatile int16_t rx_packet_start_rssi_dBm; //
volatile int32_t rx_packet_start_afc_Hz; //
volatile int16_t rx_packet_rssi_dBm; // the received packet signal strength
volatile int32_t rx_packet_afc_Hz; // the receive packet frequency offset
volatile int8_t rx_packet_start_rssi_dBm; //
volatile int8_t rx_packet_start_afc_Hz; //
volatile int8_t rx_packet_rssi_dBm; // the received packet signal strength
volatile int8_t rx_packet_afc_Hz; // the receive packet frequency offset
int lookup_index;
int ss_lookup_index;
@ -459,7 +458,7 @@ int32_t PIOS_RFM22B_Init(uint32_t *rfm22b_id, const struct pios_rfm22b_cfg *cfg)
DEBUG_PRINTF(2, "RF device ID: %x\n\r", rfm22b_dev->deviceID);
// Initialize the radio device.
int initval = rfm22_init_normal(cfg->minFrequencyHz, cfg->maxFrequencyHz, 50000);
int initval = rfm22_init_normal(rfm22b_dev->deviceID, cfg->minFrequencyHz, cfg->maxFrequencyHz, 50000);
if (initval < 0)
{
@ -512,9 +511,9 @@ uint32_t PIOS_RFM22B_DeviceID(uint32_t rfm22b_id)
return rfm22b_dev->deviceID;
}
int16_t PIOS_RFM22B_RSSI(uint32_t rfb22b_id)
int8_t PIOS_RFM22B_RSSI(uint32_t rfb22b_id)
{
return rssi_dBm;
return rfm22_receivedRSSI();
}
static void PIOS_RFM22B_RxStart(uint32_t rfm22b_id, uint16_t rx_bytes_avail)
@ -1142,6 +1141,13 @@ uint8_t rfm22_txStart()
RX_LED_OFF;
// Set the destination address in the transmit header.
// The destination address is the first 4 bytes of the message.
rfm22_write(RFM22_transmit_header0, tx_buffer[0]);
rfm22_write(RFM22_transmit_header1, tx_buffer[1]);
rfm22_write(RFM22_transmit_header2, tx_buffer[2]);
rfm22_write(RFM22_transmit_header3, tx_buffer[3]);
// FIFO mode, GFSK modulation
uint8_t fd_bit = rfm22_read(RFM22_modulation_mode_control2) & RFM22_mmc2_fd;
rfm22_write(RFM22_modulation_mode_control2, fd_bit | RFM22_mmc2_dtmod_fifo |
@ -1483,12 +1489,15 @@ void rfm22_processRxInt(void)
// we have a valid received packet
rfm22_setDebug("VALID_R_PACKET");
if (rx_packet_wr == 0)
if (rx_buffer_wr > 0)
{
// remember the rssi for this packet
rx_packet_rssi_dBm = rx_packet_start_rssi_dBm;
// remember the afc offset for this packet
rx_packet_afc_Hz = rx_packet_start_afc_Hz;
// Add the rssi and afc to the end of the packet.
rx_buffer[rx_buffer_wr++] = rx_packet_start_rssi_dBm;
rx_buffer[rx_buffer_wr++] = rx_packet_start_afc_Hz;
// Pass this packet on
bool need_yield = false;
if (rfm22b_dev_g->rx_in_cb)
@ -1604,7 +1613,7 @@ void rfm22_processInt(void)
// read rx signal strength .. 45 = -100dBm, 205 = -20dBm
rssi = rfm22_read(RFM22_rssi);
// convert to dBm
rssi_dBm = ((int16_t)rssi / 2) - 122;
rssi_dBm = (int8_t)(rssi >> 1) - 122;
// calibrate the RSSI value (rf bandwidth appears to affect it)
// if (rf_bandwidth_used > 0)
@ -1668,21 +1677,21 @@ void rfm22_processInt(void)
// ************************************
int16_t rfm22_getRSSI(void)
int8_t rfm22_getRSSI(void)
{
exec_using_spi = TRUE;
rssi = rfm22_read(RFM22_rssi); // read rx signal strength .. 45 = -100dBm, 205 = -20dBm
rssi_dBm = ((int16_t)rssi / 2) - 122; // convert to dBm
rssi_dBm = (int8_t)(rssi >> 1) - 122; // convert to dBm
exec_using_spi = FALSE;
return rssi_dBm;
}
int16_t rfm22_receivedRSSI(void)
int8_t rfm22_receivedRSSI(void)
{ // return the packets signal strength
if (!initialized)
return -200;
return -127;
else
return rx_packet_rssi_dBm;
}
@ -1722,7 +1731,6 @@ void rfm22_setTxNormal(void)
rfm22_setRxMode(RX_WAIT_PREAMBLE_MODE, false);
tx_data_rd = tx_data_wr = 0;
rx_packet_wr = 0;
rx_packet_start_rssi_dBm = 0;
rx_packet_start_afc_Hz = 0;
rx_packet_rssi_dBm = 0;
@ -1836,151 +1844,6 @@ void rfm22_1ms_tick(void)
}
}
// *****************************************************************************
// call this as often as possible - not from an interrupt
void rfm22_process(void)
{
#if !defined(RFM22_EXT_INT_USE)
if (rf_mode != RX_SCAN_SPECTRUM)
rfm22_processInt(); // manually poll the interrupt line routine
#endif
{
static int cntr = 0;
if (cntr >= 5000) {
DEBUG_PRINTF(2, "Process\n\r");
cntr = 0;
} else
++cntr;
}
if (power_on_reset) {
// we need to re-initialize the RF module - it told us it's reset itself
if (rf_mode != RX_SCAN_SPECTRUM) {
// normal data mode
uint32_t current_freq = carrier_frequency_hz; // fetch current rf nominal frequency
rfm22_init_normal(lower_carrier_frequency_limit_Hz, upper_carrier_frequency_limit_Hz, rfm22_freqHopSize());
rfm22_setNominalCarrierFrequency(current_freq); // restore the nominal carrier frequency
} else
// we are scanning the spectrum
rfm22_init_scan_spectrum(lower_carrier_frequency_limit_Hz, upper_carrier_frequency_limit_Hz);
return;
}
switch (rf_mode) {
case RX_SCAN_SPECTRUM: // we are scanning the spectrum
// read device status register
device_status = rfm22_read(RFM22_device_status);
// read ezmac status register
ezmac_status = rfm22_read(RFM22_ezmac_status);
// read interrupt status registers - clears the interrupt line
int_status1 = rfm22_read(RFM22_interrupt_status1);
int_status2 = rfm22_read(RFM22_interrupt_status2);
if (int_status2 & RFM22_is2_ipor) {
// the RF module has gone and done a reset - we need to re-initialize the rf module
initialized = FALSE;
power_on_reset = TRUE;
return;
}
break;
case RX_WAIT_PREAMBLE_MODE:
if (rfm22_int_timer >= timeout_ms)
{
// assume somethings locked up
rfm22_int_time_outs++;
rfm22_setRxMode(RX_WAIT_PREAMBLE_MODE, false); // reset the RF module to rx mode
tx_data_rd = tx_data_wr = 0; // wipe TX buffer
break;
}
// go to transmit mode if we have data to send and the channel is clear to transmit on
if (tx_data_rd == 0 && tx_data_wr > 0 && rfm22_channelIsClear()) {
rfm22_setTxMode(TX_DATA_MODE); // transmit packet NOW
break;
}
break;
case RX_WAIT_SYNC_MODE:
if (rfm22_int_timer >= timeout_sync_ms)
{
// assume somethings locked up
rfm22_int_time_outs++;
rfm22_setRxMode(RX_WAIT_PREAMBLE_MODE, false); // reset the RF module to rx mode
tx_data_rd = tx_data_wr = 0; // wipe TX buffer
break;
}
// go to transmit mode if we have data to send and the channel is clear to transmit on
if (tx_data_rd == 0 && tx_data_wr > 0 && rfm22_channelIsClear()) {
// transmit packet NOW
rfm22_setTxMode(TX_DATA_MODE);
break;
}
break;
case RX_DATA_MODE:
case TX_DATA_MODE:
if (rfm22_int_timer >= timeout_data_ms)
{
// assume somethings locked up
rfm22_int_time_outs++;
rfm22_setRxMode(RX_WAIT_PREAMBLE_MODE, false); // reset the RF module to rx mode
tx_data_rd = tx_data_wr = 0; // wipe TX buffer
break;
}
break;
case TX_STREAM_MODE:
// todo:
break;
case TX_CARRIER_MODE:
case TX_PN_MODE:
// if (rfm22_int_timer >= TX_TEST_MODE_TIMELIMIT_MS)
// {
// rfm22_setRxMode(RX_WAIT_PREAMBLE_MODE, false); // back to rx mode
// tx_data_rd = tx_data_wr = 0; // wipe TX buffer
// break;
// }
break;
default:
// unknown mode - this should never happen, maybe we should do a complete CPU reset here?
rfm22_setRxMode(RX_WAIT_PREAMBLE_MODE, false); // to rx mode
tx_data_rd = tx_data_wr = 0; // wipe TX buffer
break;
}
#if defined(RFM22_INT_TIMEOUT_DEBUG)
if (prev_rfm22_int_time_outs != rfm22_int_time_outs) {
prev_rfm22_int_time_outs = rfm22_int_time_outs;
DEBUG_PRINTF(2, "rf int timeouts %d\n\r", rfm22_int_time_outs);
}
#endif
}
// ************************************
// reset the RF module
@ -2052,12 +1915,11 @@ int rfm22_resetModule(uint8_t mode, uint32_t min_frequency_hz, uint32_t max_freq
device_status = int_status1 = int_status2 = ezmac_status = 0;
rssi = 0;
rssi_dBm = -200;
rssi_dBm = -127;
rx_buffer_current = 0;
rx_buffer_wr = 0;
rx_packet_wr = 0;
rx_packet_rssi_dBm = -200;
rx_packet_rssi_dBm = -127;
rx_packet_afc_Hz = 0;
tx_data_rd = tx_data_wr = 0;
@ -2360,7 +2222,7 @@ int rfm22_init_rx_stream(uint32_t min_frequency_hz, uint32_t max_frequency_hz)
// ************************************
// Initialise this hardware layer module and the rf module
int rfm22_init_normal(uint32_t min_frequency_hz, uint32_t max_frequency_hz, uint32_t freq_hop_step_size)
int rfm22_init_normal(uint32_t id, uint32_t min_frequency_hz, uint32_t max_frequency_hz, uint32_t freq_hop_step_size)
{
int res = rfm22_resetModule(RX_WAIT_PREAMBLE_MODE, min_frequency_hz, max_frequency_hz);
if (res < 0)
@ -2431,15 +2293,10 @@ int rfm22_init_normal(uint32_t min_frequency_hz, uint32_t max_frequency_hz, uint
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);
rfm22_write(RFM22_check_header0, id & 0xff);
rfm22_write(RFM22_check_header1, (id >> 8) & 0xff);
rfm22_write(RFM22_check_header2, (id >> 16) & 0xff);
rfm22_write(RFM22_check_header3, (id >> 24) & 0xff);
// 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 |
@ -2453,12 +2310,6 @@ int rfm22_init_normal(uint32_t min_frequency_hz, uint32_t max_frequency_hz, uint
rfm22_write(RFM22_sync_word1, SYNC_BYTE_3);
rfm22_write(RFM22_sync_word0, SYNC_BYTE_4);
// no bits to be checked
rfm22_write(RFM22_header_enable3, 0x00);
rfm22_write(RFM22_header_enable2, 0x00);
rfm22_write(RFM22_header_enable1, 0x00);
rfm22_write(RFM22_header_enable0, 0x00);
rfm22_write(RFM22_agc_override1, RFM22_agc_ovr1_agcen);
// set frequency hopping channel step size (multiples of 10kHz)

View File

@ -48,7 +48,7 @@ struct pios_rfm22b_cfg {
/* 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);
extern int8_t PIOS_RFM22B_RSSI(uint32_t rfb22b_id);
#endif /* PIOS_RFM22B_H */

View File

@ -609,9 +609,9 @@ uint32_t rfm22_getDatarate(void);
void rfm22_setRxMode(uint8_t mode, bool multi_packet_mode);
int16_t rfm22_getRSSI(void);
int8_t rfm22_getRSSI(void);
int16_t rfm22_receivedRSSI(void);
int8_t rfm22_receivedRSSI(void);
int32_t rfm22_receivedAFCHz(void);
uint16_t rfm22_receivedLength(void);
uint8_t * rfm22_receivedPointer(void);
@ -639,7 +639,6 @@ bool rfm22_channelIsClear(void);
bool rfm22_txReady(void);
void rfm22_1ms_tick(void);
void rfm22_process(void);
void rfm22_TxDataByte_SetCallback(t_rfm22_TxDataByteCallback new_function);
void rfm22_RxData_SetCallback(t_rfm22_RxDataCallback new_function);
@ -647,7 +646,7 @@ void rfm22_RxData_SetCallback(t_rfm22_RxDataCallback new_function);
int rfm22_init_scan_spectrum(uint32_t min_frequency_hz, uint32_t max_frequency_hz);
int rfm22_init_tx_stream(uint32_t min_frequency_hz, uint32_t max_frequency_hz);
int rfm22_init_rx_stream(uint32_t min_frequency_hz, uint32_t max_frequency_hz);
int rfm22_init_normal(uint32_t min_frequency_hz, uint32_t max_frequency_hz, uint32_t freq_hop_step_size);
int rfm22_init_normal(uint32_t id, uint32_t min_frequency_hz, uint32_t max_frequency_hz, uint32_t freq_hop_step_size);
#endif /* PIOS_RFM22B_PRIV_H */

View File

@ -38,7 +38,7 @@
#define PIOS_COM_FLEXI_RX_BUF_LEN 192
#define PIOS_COM_FLEXI_TX_BUF_LEN 192
#define PIOS_COM_TELEM_USB_RX_BUF_LEN 192
#define PIOS_COM_TELEM_USB_RX_BUF_LEN 512
#define PIOS_COM_TELEM_USB_TX_BUF_LEN 192
#define PIOS_COM_VCP_USB_RX_BUF_LEN 192

View File

@ -483,10 +483,10 @@ 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_7, // +20dBm .. 100mW
.sendTimeout = 15, /* ms */
.minPacketSize = 50,
.maxTxPower = RFM22_tx_pwr_txpow_0, // +1dBm ... 1.25mW
//.maxTxPower = RFM22_tx_pwr_txpow_7, // +20dBm .. 100mW
.sendTimeout = 25, /* ms */
.minPacketSize = 100,
.txWinSize = 4,
.maxConnections = 1,
};

View File

@ -0,0 +1,20 @@
<xml>
<object name="PipXSettings" singleinstance="true" settings="true">
<description>PipXtreme configurations options.</description>
<field name="PairID" units="" type="uint32" elements="1" defaultvalue="0"/>
<field name="TelemetrySpeed" units="bps" type="enum" elements="1" options="2400,4800,9600,19200,38400,57600,115200" defaultvalue="57600"/>
<field name="FlexiConfig" units="function" type="enum" elements="1" options="Disabled,Serial,PPM,RSSI" defaultvalue="Disabled"/>
<field name="FlexiSpeed" units="bps" type="enum" elements="1" options="2400,4800,9600,19200,38400,57600,115200" defaultvalue="57600"/>
<field name="RFSpeed" units="bps" type="enum" elements="1" options="2400,4800,9600,19200,38400,57600,115200" defaultvalue="57600"/>
<field name="MaxRFPower" units="mW" type="enum" elements="1" options="1.25,1.6,3.16,6.3,12.6,25,50,100" defaultvalue="1.25"/>
<field name="SendTimeout" units="ms" type="uint16" elements="1" defaultvalue="50"/>
<field name="MinPacketSize" units="bytes" type="uint8" elements="1" defaultvalue="50"/>
<field name="FrequencyCalibration" units="" type="uint8" elements="1" defaultvalue="127"/>
<field name="Frequency" units="" type="uint32" elements="1" defaultvalue="434000000"/>
<access gcs="readwrite" flight="readonly"/>
<telemetrygcs acked="true" updatemode="onchange" period="0"/>
<telemetryflight acked="false" updatemode="manual" period="0"/>
<logging updatemode="never" period="0"/>
</object>
</xml>

View File

@ -0,0 +1,26 @@
<xml>
<object name="PipXStatus" singleinstance="true" settings="false">
<description>PipXtreme device status.</description>
<field name="Description" units="" type="uint8" elements="40"/>
<field name="CPUSerial" units="" type="uint8" elements="12" />
<field name="BoardRevision" units="" type="uint16" elements="1"/>
<field name="BoardType" units="" type="uint8" elements="1"/>
<field name="MinFrequency" units="Hz" type="uint32" elements="1" defaultvalue="0"/>
<field name="MaxFrequency" units="Hz" type="uint32" elements="1" defaultvalue="0"/>
<field name="FrequencyBand" units="" type="uint8" elements="1" defaultvalue="0"/>
<field name="FrequencyStepSize" units="" type="float" elements="1" defaultvalue="0"/>
<field name="DeviceID" units="" type="uint32" elements="1" defaultvalue="0"/>
<field name="AFC" units="" type="int32" elements="1" defaultvalue="0"/>
<field name="Retries" units="" type="uint16" elements="1" defaultvalue="0"/>
<field name="Errors" units="" type="uint16" elements="1" defaultvalue="0"/>
<field name="RSSI" units="dBm" type="int8" elements="1" defaultvalue="0"/>
<field name="LinkState" units="function" type="enum" elements="1" options="Disconnected,Connecting,Connected" defaultvalue="Disconnected"/>
<field name="PairIDs" units="" type="uint32" elements="4" defaultvalue="0"/>
<field name="PairSignalStrengths" units="dBm" type="int8" elements="4" defaultvalue="-127"/>
<access gcs="readonly" flight="readwrite"/>
<telemetrygcs acked="false" updatemode="manual" period="0"/>
<telemetryflight acked="false" updatemode="manual" period="0"/>
<logging updatemode="periodic" period="1000"/>
</object>
</xml>