mirror of
https://bitbucket.org/librepilot/librepilot.git
synced 2025-01-18 03:52:11 +01:00
RFM22B: All packets are now ACKed, and added a formal connection request / accept that will be used or auto-configuring the remote modem.
This commit is contained in:
parent
98026966f7
commit
fa5f7a8fdd
@ -42,8 +42,6 @@ typedef enum {
|
||||
PACKET_TYPE_NONE = 0,
|
||||
PACKET_TYPE_STATUS, // broadcasts status of this modem
|
||||
PACKET_TYPE_CON_REQUEST, // request a connection to another modem
|
||||
PACKET_TYPE_CON_ACCEPT, // accecpt a connection to another modem
|
||||
PACKET_TYPE_CON_DECLINE, // decline a connection to another modem
|
||||
PACKET_TYPE_DATA, // data packet (packet contains user data)
|
||||
PACKET_TYPE_PPM, // PPM relay values
|
||||
PACKET_TYPE_ACK,
|
||||
@ -59,12 +57,19 @@ typedef struct {
|
||||
} PHPacketHeader;
|
||||
|
||||
#define PH_MAX_DATA (PIOS_PH_MAX_PACKET - sizeof(PHPacketHeader) - RS_ECC_NPARITY)
|
||||
#define PH_PACKET_SIZE(p) (p->data + p->header.data_size - (uint8_t*)p + RS_ECC_NPARITY)
|
||||
#define PH_PACKET_SIZE(p) ((p)->data + (p)->header.data_size - (uint8_t*)(p) + RS_ECC_NPARITY)
|
||||
typedef struct {
|
||||
PHPacketHeader header;
|
||||
uint8_t data[PH_MAX_DATA + RS_ECC_NPARITY];
|
||||
} PHPacket, *PHPacketHandle;
|
||||
|
||||
typedef struct {
|
||||
PHPacketHeader header;
|
||||
uint16_t seq_num;
|
||||
bool ready_to_send;
|
||||
uint8_t ecc[RS_ECC_NPARITY];
|
||||
} PHAckNackPacket, *PHAckNackPacketHandle;
|
||||
|
||||
#define PH_PPM_DATA_SIZE(p) ((uint8_t*)((p)->ecc) - (uint8_t*)(((PHPacketHandle)(p))->data))
|
||||
typedef struct {
|
||||
PHPacketHeader header;
|
||||
@ -83,11 +88,11 @@ typedef struct {
|
||||
#define PH_CONNECTION_DATA_SIZE(p) ((uint8_t*)((p)->ecc) - (uint8_t*)(((PHPacketHandle)(p))->data))
|
||||
typedef struct {
|
||||
PHPacketHeader header;
|
||||
uint32_t datarate;
|
||||
uint32_t frequencyHz;
|
||||
uint32_t minFrequencyHz;
|
||||
uint32_t maxFrequencyHz;
|
||||
uint8_t maxTxPower;
|
||||
uint8_t datarate;
|
||||
uint32_t frequency_hz;
|
||||
uint32_t min_frequency;
|
||||
uint32_t max_frequency;
|
||||
uint8_t max_tx_power;
|
||||
uint8_t ecc[RS_ECC_NPARITY];
|
||||
} PHConnectionPacket, *PHConnectionPacketHandle;
|
||||
|
||||
|
@ -192,16 +192,11 @@ static void systemTask(void *parameters)
|
||||
prev_tx_count = tx_count;
|
||||
prev_rx_count = rx_count;
|
||||
}
|
||||
if (radio_stats.connected)
|
||||
{
|
||||
oplinkStatus.LinkState = OPLINKSTATUS_LINKSTATE_CONNECTED;
|
||||
oplinkStatus.LinkState = radio_stats.link_state;
|
||||
if (radio_stats.link_state == OPLINKSTATUS_LINKSTATE_CONNECTED)
|
||||
LINK_LED_ON;
|
||||
}
|
||||
else
|
||||
{
|
||||
oplinkStatus.LinkState = OPLINKSTATUS_LINKSTATE_DISCONNECTED;
|
||||
LINK_LED_OFF;
|
||||
}
|
||||
|
||||
// Update the object
|
||||
OPLinkStatusSet(&oplinkStatus);
|
||||
|
@ -306,7 +306,7 @@ static int32_t UAVTalkSendHandler(uint8_t *buf, int32_t length)
|
||||
uint32_t outputPort = PIOS_COM_TELEMETRY;
|
||||
#if defined(PIOS_INCLUDE_USB)
|
||||
// Determine output port (USB takes priority over telemetry port)
|
||||
if (PIOS_USB_CheckAvailable(0) && PIOS_COM_TELEM_USB)
|
||||
if (PIOS_COM_TELEM_USB && PIOS_COM_Available(PIOS_COM_TELEM_USB))
|
||||
outputPort = PIOS_COM_TELEM_USB;
|
||||
#endif /* PIOS_INCLUDE_USB */
|
||||
if(outputPort)
|
||||
@ -325,10 +325,12 @@ static int32_t UAVTalkSendHandler(uint8_t *buf, int32_t length)
|
||||
static int32_t RadioSendHandler(uint8_t *buf, int32_t length)
|
||||
{
|
||||
uint32_t outputPort = PIOS_COM_RADIO;
|
||||
if(outputPort)
|
||||
// Don't send any data unless the radio port is available.
|
||||
if(outputPort && PIOS_COM_Available(outputPort))
|
||||
return PIOS_COM_SendBuffer(outputPort, buf, length);
|
||||
else
|
||||
return -1;
|
||||
// For some reason, if this function returns failure, it prevents saving settings.
|
||||
return length;
|
||||
}
|
||||
|
||||
static void ProcessInputStream(UAVTalkConnection connectionHandle, uint8_t rxbyte)
|
||||
|
@ -71,6 +71,9 @@
|
||||
// The maximum amount of time without activity before initiating a reset.
|
||||
#define PIOS_RFM22B_SUPERVISOR_TIMEOUT 100 // ms
|
||||
|
||||
// The time between connection attempts when not connected
|
||||
#define CONNECT_ATTEMPT_PERIOD_MS 250 // ms
|
||||
|
||||
// The time between updates for sending stats the radio link.
|
||||
#define RADIOSTATS_UPDATE_PERIOD_MS 250
|
||||
|
||||
@ -159,7 +162,6 @@ static const uint8_t OUT_FF[64] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
|
||||
|
||||
/* Local function forwared declarations */
|
||||
static void PIOS_RFM22B_Task(void *parameters);
|
||||
static void PIOS_RFM22B_InjectEvent(struct pios_rfm22b_dev *rfm22b_dev, enum pios_rfm22b_event event, bool inISR);
|
||||
static bool rfm22_readStatus(struct pios_rfm22b_dev *rfm22b_dev);
|
||||
static enum pios_rfm22b_event rfm22_init(struct pios_rfm22b_dev *rfm22b_dev);
|
||||
static enum pios_rfm22b_event rfm22_setRxMode(struct pios_rfm22b_dev *rfm22b_dev);
|
||||
@ -167,10 +169,14 @@ static enum pios_rfm22b_event rfm22_detectPreamble(struct pios_rfm22b_dev *rfm22
|
||||
static enum pios_rfm22b_event rfm22_detectSync(struct pios_rfm22b_dev *rfm22b_dev);
|
||||
static enum pios_rfm22b_event rfm22_rxData(struct pios_rfm22b_dev *rfm22b_dev);
|
||||
static enum pios_rfm22b_event rfm22_receiveStatus(struct pios_rfm22b_dev *rfm22b_dev);
|
||||
static enum pios_rfm22b_event rfm22_receiveAck(struct pios_rfm22b_dev *rfm22b_dev);
|
||||
static enum pios_rfm22b_event rfm22_receiveNack(struct pios_rfm22b_dev *rfm22b_dev);
|
||||
static enum pios_rfm22b_event rfm22_sendAck(struct pios_rfm22b_dev *rfm22b_dev);
|
||||
static enum pios_rfm22b_event rfm22_sendNack(struct pios_rfm22b_dev *rfm22b_dev);
|
||||
static enum pios_rfm22b_event rfm22_requestConnection(struct pios_rfm22b_dev *rfm22b_dev);
|
||||
static enum pios_rfm22b_event rfm22_initConnection(struct pios_rfm22b_dev *rfm22b_dev);
|
||||
static enum pios_rfm22b_event rfm22_acceptConnection(struct pios_rfm22b_dev *rfm22b_dev);
|
||||
static enum pios_rfm22b_event rfm22_connectionAccepted(struct pios_rfm22b_dev *rfm22b_dev);
|
||||
static enum pios_rfm22b_event rfm22_connectionDeclined(struct pios_rfm22b_dev *rfm22b_dev);
|
||||
static enum pios_rfm22b_event rfm22_txStart(struct pios_rfm22b_dev *rfm22b_dev);
|
||||
static enum pios_rfm22b_event rfm22_txData(struct pios_rfm22b_dev *rfm22b_dev);
|
||||
static enum pios_rfm22b_event rfm22_process_state_transition(struct pios_rfm22b_dev *rfm22b_dev, enum pios_rfm22b_event event);
|
||||
@ -196,6 +202,8 @@ static uint8_t rfm22_read_noclaim(uint8_t addr);
|
||||
|
||||
/* Te state transition table */
|
||||
const static struct pios_rfm22b_transition rfm22b_transitions[RFM22B_STATE_NUM_STATES] = {
|
||||
|
||||
// Initialization thread
|
||||
[RFM22B_STATE_UNINITIALIZED] = {
|
||||
.entry_fn = 0,
|
||||
.next_state = {
|
||||
@ -206,27 +214,40 @@ const static struct pios_rfm22b_transition rfm22b_transitions[RFM22B_STATE_NUM_S
|
||||
[RFM22B_STATE_INITIALIZING] = {
|
||||
.entry_fn = rfm22_init,
|
||||
.next_state = {
|
||||
//[RFM22B_EVENT_INITIALIZED] = RFM22B_STATE_REQUESTING_CONNECTION,
|
||||
[RFM22B_EVENT_INITIALIZED] = RFM22B_STATE_TX_START,
|
||||
[RFM22B_EVENT_INITIALIZED] = RFM22B_STATE_INITIATING_CONNECTION,
|
||||
[RFM22B_EVENT_INITIALIZE] = RFM22B_STATE_INITIALIZING,
|
||||
[RFM22B_EVENT_ERROR] = RFM22B_STATE_ERROR,
|
||||
[RFM22B_EVENT_FATAL_ERROR] = RFM22B_STATE_FATAL_ERROR,
|
||||
},
|
||||
},
|
||||
[RFM22B_STATE_INITIATING_CONNECTION] = {
|
||||
.entry_fn = rfm22_initConnection,
|
||||
.next_state = {
|
||||
[RFM22B_EVENT_REQUEST_CONNECTION] = RFM22B_STATE_REQUESTING_CONNECTION,
|
||||
[RFM22B_EVENT_WAIT_FOR_CONNECTION] = RFM22B_STATE_RX_MODE,
|
||||
[RFM22B_EVENT_TIMEOUT] = RFM22B_STATE_TIMEOUT,
|
||||
[RFM22B_EVENT_ERROR] = RFM22B_STATE_ERROR,
|
||||
[RFM22B_EVENT_INITIALIZE] = RFM22B_STATE_INITIALIZING,
|
||||
[RFM22B_EVENT_FATAL_ERROR] = RFM22B_STATE_FATAL_ERROR,
|
||||
},
|
||||
},
|
||||
[RFM22B_STATE_REQUESTING_CONNECTION] = {
|
||||
.entry_fn = rfm22_requestConnection,
|
||||
.next_state = {
|
||||
[RFM22B_EVENT_REQUESTED_CONNECTION] = RFM22B_STATE_TX_START,
|
||||
[RFM22B_EVENT_START_TRANSFER] = RFM22B_STATE_TX_START,
|
||||
[RFM22B_EVENT_TIMEOUT] = RFM22B_STATE_TIMEOUT,
|
||||
[RFM22B_EVENT_ERROR] = RFM22B_STATE_ERROR,
|
||||
[RFM22B_EVENT_INITIALIZE] = RFM22B_STATE_INITIALIZING,
|
||||
[RFM22B_EVENT_FATAL_ERROR] = RFM22B_STATE_FATAL_ERROR,
|
||||
},
|
||||
},
|
||||
[RFM22B_STATE_ACCEPTING_CONNECTION] = {
|
||||
.entry_fn = rfm22_acceptConnection,
|
||||
.next_state = {
|
||||
[RFM22B_EVENT_RX_COMPLETE] = RFM22B_STATE_TX_START,
|
||||
[RFM22B_EVENT_CONNECTION_ACCEPTED] = RFM22B_STATE_SENDING_ACK,
|
||||
[RFM22B_EVENT_TIMEOUT] = RFM22B_STATE_TIMEOUT,
|
||||
[RFM22B_EVENT_ERROR] = RFM22B_STATE_ERROR,
|
||||
[RFM22B_EVENT_INITIALIZE] = RFM22B_STATE_INITIALIZING,
|
||||
[RFM22B_EVENT_FATAL_ERROR] = RFM22B_STATE_FATAL_ERROR,
|
||||
},
|
||||
},
|
||||
@ -236,38 +257,35 @@ const static struct pios_rfm22b_transition rfm22b_transitions[RFM22B_STATE_NUM_S
|
||||
[RFM22B_EVENT_RX_COMPLETE] = RFM22B_STATE_TX_START,
|
||||
[RFM22B_EVENT_TIMEOUT] = RFM22B_STATE_TIMEOUT,
|
||||
[RFM22B_EVENT_ERROR] = RFM22B_STATE_ERROR,
|
||||
[RFM22B_EVENT_INITIALIZE] = RFM22B_STATE_INITIALIZING,
|
||||
[RFM22B_EVENT_FATAL_ERROR] = RFM22B_STATE_FATAL_ERROR,
|
||||
},
|
||||
},
|
||||
[RFM22B_STATE_CONNECTION_DECLINED] = {
|
||||
.entry_fn = rfm22_connectionDeclined,
|
||||
.next_state = {
|
||||
[RFM22B_EVENT_RX_COMPLETE] = RFM22B_STATE_TX_START,
|
||||
[RFM22B_EVENT_TIMEOUT] = RFM22B_STATE_TIMEOUT,
|
||||
[RFM22B_EVENT_ERROR] = RFM22B_STATE_ERROR,
|
||||
[RFM22B_EVENT_FATAL_ERROR] = RFM22B_STATE_FATAL_ERROR,
|
||||
},
|
||||
},
|
||||
|
||||
[RFM22B_STATE_RX_MODE] = {
|
||||
.entry_fn = rfm22_setRxMode,
|
||||
.next_state = {
|
||||
[RFM22B_EVENT_INT_RECEIVED] = RFM22B_STATE_WAIT_PREAMBLE,
|
||||
[RFM22B_EVENT_SEND_PACKET] = RFM22B_STATE_TX_START,
|
||||
[RFM22B_EVENT_TX_START] = RFM22B_STATE_TX_START,
|
||||
[RFM22B_EVENT_START_TRANSFER] = RFM22B_STATE_TX_START,
|
||||
[RFM22B_EVENT_PACKET_NACKED] = RFM22B_STATE_RECEIVING_NACK,
|
||||
[RFM22B_EVENT_TIMEOUT] = RFM22B_STATE_TIMEOUT,
|
||||
[RFM22B_EVENT_ERROR] = RFM22B_STATE_ERROR,
|
||||
[RFM22B_EVENT_INITIALIZE] = RFM22B_STATE_INITIALIZING,
|
||||
[RFM22B_EVENT_FATAL_ERROR] = RFM22B_STATE_FATAL_ERROR,
|
||||
},
|
||||
},
|
||||
[RFM22B_STATE_WAIT_PREAMBLE] = {
|
||||
.entry_fn = rfm22_detectPreamble,
|
||||
.next_state = {
|
||||
[RFM22B_EVENT_INT_RECEIVED] = RFM22B_STATE_WAIT_PREAMBLE,
|
||||
[RFM22B_EVENT_PREAMBLE_DETECTED] = RFM22B_STATE_WAIT_SYNC,
|
||||
[RFM22B_EVENT_INT_RECEIVED] = RFM22B_STATE_WAIT_PREAMBLE,
|
||||
[RFM22B_EVENT_SEND_PACKET] = RFM22B_STATE_TX_START,
|
||||
[RFM22B_EVENT_TX_START] = RFM22B_STATE_TX_START,
|
||||
[RFM22B_EVENT_START_TRANSFER] = RFM22B_STATE_TX_START,
|
||||
[RFM22B_EVENT_PACKET_NACKED] = RFM22B_STATE_RECEIVING_NACK,
|
||||
[RFM22B_EVENT_TIMEOUT] = RFM22B_STATE_TIMEOUT,
|
||||
[RFM22B_EVENT_ERROR] = RFM22B_STATE_ERROR,
|
||||
[RFM22B_EVENT_INITIALIZE] = RFM22B_STATE_INITIALIZING,
|
||||
[RFM22B_EVENT_FATAL_ERROR] = RFM22B_STATE_FATAL_ERROR,
|
||||
},
|
||||
},
|
||||
@ -276,9 +294,9 @@ const static struct pios_rfm22b_transition rfm22b_transitions[RFM22B_STATE_NUM_S
|
||||
.next_state = {
|
||||
[RFM22B_EVENT_INT_RECEIVED] = RFM22B_STATE_WAIT_SYNC,
|
||||
[RFM22B_EVENT_SYNC_DETECTED] = RFM22B_STATE_RX_DATA,
|
||||
[RFM22B_EVENT_TX_START] = RFM22B_STATE_TX_START,
|
||||
[RFM22B_EVENT_TIMEOUT] = RFM22B_STATE_TIMEOUT,
|
||||
[RFM22B_EVENT_ERROR] = RFM22B_STATE_ERROR,
|
||||
[RFM22B_EVENT_INITIALIZE] = RFM22B_STATE_INITIALIZING,
|
||||
[RFM22B_EVENT_FATAL_ERROR] = RFM22B_STATE_FATAL_ERROR,
|
||||
},
|
||||
},
|
||||
@ -286,22 +304,46 @@ const static struct pios_rfm22b_transition rfm22b_transitions[RFM22B_STATE_NUM_S
|
||||
.entry_fn = rfm22_rxData,
|
||||
.next_state = {
|
||||
[RFM22B_EVENT_INT_RECEIVED] = RFM22B_STATE_RX_DATA,
|
||||
[RFM22B_EVENT_RX_COMPLETE] = RFM22B_STATE_TX_START,
|
||||
[RFM22B_EVENT_RX_COMPLETE] = RFM22B_STATE_SENDING_ACK,
|
||||
[RFM22B_EVENT_STATUS_RECEIVED] = RFM22B_STATE_RECEIVING_STATUS,
|
||||
[RFM22B_EVENT_CONNECTION_REQUEST] = RFM22B_STATE_ACCEPTING_CONNECTION,
|
||||
[RFM22B_EVENT_CONNECTION_ACCEPT] = RFM22B_STATE_CONNECTION_ACCEPTED,
|
||||
[RFM22B_EVENT_CONNECTION_DECLINED] = RFM22B_STATE_CONNECTION_DECLINED,
|
||||
[RFM22B_EVENT_CONNECTION_REQUESTED] = RFM22B_STATE_ACCEPTING_CONNECTION,
|
||||
[RFM22B_EVENT_PACKET_ACKED] = RFM22B_STATE_RECEIVING_ACK,
|
||||
[RFM22B_EVENT_PACKET_NACKED] = RFM22B_STATE_RECEIVING_NACK,
|
||||
[RFM22B_EVENT_TIMEOUT] = RFM22B_STATE_TIMEOUT,
|
||||
[RFM22B_EVENT_ERROR] = RFM22B_STATE_ERROR,
|
||||
[RFM22B_EVENT_INITIALIZE] = RFM22B_STATE_INITIALIZING,
|
||||
[RFM22B_EVENT_FATAL_ERROR] = RFM22B_STATE_FATAL_ERROR,
|
||||
},
|
||||
},
|
||||
[RFM22B_STATE_RECEIVING_ACK] = {
|
||||
.entry_fn = rfm22_receiveAck,
|
||||
.next_state = {
|
||||
[RFM22B_EVENT_CONNECTION_ACCEPTED] = RFM22B_STATE_CONNECTION_ACCEPTED,
|
||||
[RFM22B_EVENT_TX_START] = RFM22B_STATE_TX_START,
|
||||
[RFM22B_EVENT_RX_MODE] = RFM22B_STATE_RX_MODE,
|
||||
[RFM22B_EVENT_TIMEOUT] = RFM22B_STATE_TIMEOUT,
|
||||
[RFM22B_EVENT_ERROR] = RFM22B_STATE_ERROR,
|
||||
[RFM22B_EVENT_INITIALIZE] = RFM22B_STATE_INITIALIZING,
|
||||
[RFM22B_EVENT_FATAL_ERROR] = RFM22B_STATE_FATAL_ERROR,
|
||||
},
|
||||
},
|
||||
[RFM22B_STATE_RECEIVING_NACK] = {
|
||||
.entry_fn = rfm22_receiveNack,
|
||||
.next_state = {
|
||||
[RFM22B_EVENT_START_TRANSFER] = RFM22B_STATE_TX_START,
|
||||
[RFM22B_EVENT_TIMEOUT] = RFM22B_STATE_TIMEOUT,
|
||||
[RFM22B_EVENT_ERROR] = RFM22B_STATE_ERROR,
|
||||
[RFM22B_EVENT_INITIALIZE] = RFM22B_STATE_INITIALIZING,
|
||||
[RFM22B_EVENT_FATAL_ERROR] = RFM22B_STATE_FATAL_ERROR,
|
||||
},
|
||||
},
|
||||
[RFM22B_STATE_RECEIVING_STATUS] = {
|
||||
.entry_fn = rfm22_receiveStatus,
|
||||
.next_state = {
|
||||
[RFM22B_EVENT_RX_COMPLETE] = RFM22B_STATE_TX_START,
|
||||
[RFM22B_EVENT_RX_COMPLETE] = RFM22B_STATE_SENDING_ACK,
|
||||
[RFM22B_EVENT_TIMEOUT] = RFM22B_STATE_TIMEOUT,
|
||||
[RFM22B_EVENT_ERROR] = RFM22B_STATE_ERROR,
|
||||
[RFM22B_EVENT_INITIALIZE] = RFM22B_STATE_INITIALIZING,
|
||||
[RFM22B_EVENT_FATAL_ERROR] = RFM22B_STATE_FATAL_ERROR,
|
||||
},
|
||||
},
|
||||
@ -312,6 +354,7 @@ const static struct pios_rfm22b_transition rfm22b_transitions[RFM22B_STATE_NUM_S
|
||||
[RFM22B_EVENT_RX_MODE] = RFM22B_STATE_RX_MODE,
|
||||
[RFM22B_EVENT_TIMEOUT] = RFM22B_STATE_TIMEOUT,
|
||||
[RFM22B_EVENT_ERROR] = RFM22B_STATE_ERROR,
|
||||
[RFM22B_EVENT_INITIALIZE] = RFM22B_STATE_INITIALIZING,
|
||||
[RFM22B_EVENT_FATAL_ERROR] = RFM22B_STATE_FATAL_ERROR,
|
||||
},
|
||||
},
|
||||
@ -319,18 +362,41 @@ const static struct pios_rfm22b_transition rfm22b_transitions[RFM22B_STATE_NUM_S
|
||||
.entry_fn = rfm22_txData,
|
||||
.next_state = {
|
||||
[RFM22B_EVENT_INT_RECEIVED] = RFM22B_STATE_TX_DATA,
|
||||
[RFM22B_EVENT_TX_COMPLETE] = RFM22B_STATE_RX_MODE,
|
||||
[RFM22B_EVENT_TX_START] = RFM22B_STATE_TX_START,
|
||||
[RFM22B_EVENT_RX_MODE] = RFM22B_STATE_RX_MODE,
|
||||
[RFM22B_EVENT_TIMEOUT] = RFM22B_STATE_TIMEOUT,
|
||||
[RFM22B_EVENT_ERROR] = RFM22B_STATE_ERROR,
|
||||
[RFM22B_EVENT_INITIALIZE] = RFM22B_STATE_INITIALIZING,
|
||||
[RFM22B_EVENT_FATAL_ERROR] = RFM22B_STATE_FATAL_ERROR,
|
||||
},
|
||||
},
|
||||
[RFM22B_STATE_SENDING_ACK] = {
|
||||
.entry_fn = rfm22_sendAck,
|
||||
.next_state = {
|
||||
[RFM22B_EVENT_START_TRANSFER] = RFM22B_STATE_TX_START,
|
||||
[RFM22B_EVENT_INITIALIZE] = RFM22B_STATE_INITIALIZING,
|
||||
[RFM22B_EVENT_ERROR] = RFM22B_STATE_ERROR,
|
||||
[RFM22B_EVENT_INITIALIZE] = RFM22B_STATE_INITIALIZING,
|
||||
[RFM22B_EVENT_FATAL_ERROR] = RFM22B_STATE_FATAL_ERROR,
|
||||
},
|
||||
},
|
||||
[RFM22B_STATE_SENDING_NACK] = {
|
||||
.entry_fn = rfm22_sendNack,
|
||||
.next_state = {
|
||||
[RFM22B_EVENT_START_TRANSFER] = RFM22B_STATE_TX_START,
|
||||
[RFM22B_EVENT_INITIALIZE] = RFM22B_STATE_INITIALIZING,
|
||||
[RFM22B_EVENT_ERROR] = RFM22B_STATE_ERROR,
|
||||
[RFM22B_EVENT_INITIALIZE] = RFM22B_STATE_INITIALIZING,
|
||||
[RFM22B_EVENT_FATAL_ERROR] = RFM22B_STATE_FATAL_ERROR,
|
||||
},
|
||||
},
|
||||
[RFM22B_STATE_TIMEOUT] = {
|
||||
.entry_fn = rfm22_timeout,
|
||||
.next_state = {
|
||||
[RFM22B_EVENT_TX_START] = RFM22B_STATE_TX_START,
|
||||
[RFM22B_EVENT_START_TRANSFER] = RFM22B_STATE_TX_START,
|
||||
[RFM22B_EVENT_INITIALIZE] = RFM22B_STATE_INITIALIZING,
|
||||
[RFM22B_EVENT_ERROR] = RFM22B_STATE_ERROR,
|
||||
[RFM22B_EVENT_INITIALIZE] = RFM22B_STATE_INITIALIZING,
|
||||
[RFM22B_EVENT_FATAL_ERROR] = RFM22B_STATE_FATAL_ERROR,
|
||||
},
|
||||
},
|
||||
@ -339,14 +405,13 @@ const static struct pios_rfm22b_transition rfm22b_transitions[RFM22B_STATE_NUM_S
|
||||
.next_state = {
|
||||
[RFM22B_EVENT_INITIALIZE] = RFM22B_STATE_INITIALIZING,
|
||||
[RFM22B_EVENT_ERROR] = RFM22B_STATE_ERROR,
|
||||
[RFM22B_EVENT_INITIALIZE] = RFM22B_STATE_INITIALIZING,
|
||||
[RFM22B_EVENT_FATAL_ERROR] = RFM22B_STATE_FATAL_ERROR,
|
||||
},
|
||||
},
|
||||
[RFM22B_STATE_FATAL_ERROR] = {
|
||||
.entry_fn = rfm22_fatal_error,
|
||||
.next_state = {
|
||||
[RFM22B_EVENT_ERROR] = RFM22B_STATE_ERROR,
|
||||
[RFM22B_EVENT_FATAL_ERROR] = RFM22B_STATE_FATAL_ERROR,
|
||||
},
|
||||
},
|
||||
};
|
||||
@ -411,6 +476,12 @@ static const uint8_t ss_reg_70[] = { 0x24, 0x2D}; // rfm22_modulation_mode_cont
|
||||
static const uint8_t ss_reg_71[] = { 0x2B, 0x23}; // rfm22_modulation_mode_control2
|
||||
|
||||
|
||||
static inline uint32_t timeDifferenceMs(portTickType start_time, portTickType end_time) {
|
||||
if(end_time > start_time)
|
||||
return (end_time - start_time) * portTICK_RATE_MS;
|
||||
return ((((portTICK_RATE_MS) -1) - start_time) + end_time) * portTICK_RATE_MS;
|
||||
}
|
||||
|
||||
bool PIOS_RFM22B_validate(struct pios_rfm22b_dev * rfm22b_dev)
|
||||
{
|
||||
return (rfm22b_dev != NULL && rfm22b_dev->magic == PIOS_RFM22B_DEV_MAGIC);
|
||||
@ -498,12 +569,18 @@ int32_t PIOS_RFM22B_Init(uint32_t *rfm22b_id, uint32_t spi_id, uint32_t slave_nu
|
||||
rfm22b_dev->stats.rx_error = 0;
|
||||
rfm22b_dev->stats.rx_missed = 0;
|
||||
rfm22b_dev->stats.tx_dropped = 0;
|
||||
rfm22b_dev->stats.tx_resent = 0;
|
||||
rfm22b_dev->stats.resets = 0;
|
||||
rfm22b_dev->stats.timeouts = 0;
|
||||
rfm22b_dev->stats.link_quality = 0;
|
||||
rfm22b_dev->stats.rssi = 0;
|
||||
rfm22b_dev->stats.link_state = OPLINKSTATUS_LINKSTATE_DISCONNECTED;
|
||||
rfm22b_dev->tx_power = RFM22B_DEFAULT_TX_POWER;
|
||||
rfm22b_dev->destination_id = 0xffffffff;
|
||||
rfm22b_dev->coordinator = false;
|
||||
rfm22b_dev->send_status = false;
|
||||
rfm22b_dev->send_ppm = false;
|
||||
rfm22b_dev->send_connection_request = false;
|
||||
|
||||
// Bind the configuration to the device instance
|
||||
rfm22b_dev->cfg = *cfg;
|
||||
@ -512,6 +589,7 @@ int32_t PIOS_RFM22B_Init(uint32_t *rfm22b_id, uint32_t spi_id, uint32_t slave_nu
|
||||
// Initialize the packets.
|
||||
rfm22b_dev->rx_packet_len = 0;
|
||||
rfm22b_dev->tx_packet = NULL;
|
||||
rfm22b_dev->prev_tx_packet = NULL;
|
||||
rfm22b_dev->tx_seq = 0;
|
||||
|
||||
*rfm22b_id = (uint32_t)rfm22b_dev;
|
||||
@ -577,7 +655,7 @@ bool PIOS_RFM22_EXT_Int(void)
|
||||
* \param[in] event The event to inject
|
||||
* \param[in] inISR Is this being called from an interrrup service routine?
|
||||
*/
|
||||
static void PIOS_RFM22B_InjectEvent(struct pios_rfm22b_dev *rfm22b_dev, enum pios_rfm22b_event event, bool inISR)
|
||||
void PIOS_RFM22B_InjectEvent(struct pios_rfm22b_dev *rfm22b_dev, enum pios_rfm22b_event event, bool inISR)
|
||||
{
|
||||
|
||||
// Store the event.
|
||||
@ -663,6 +741,22 @@ void PIOS_RFM22B_SetDestinationId(uint32_t rfm22b_id, uint32_t dest_id)
|
||||
rfm22b_dev->pair_stats[0].lastContact = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Configures the radio as a coordinator or not.
|
||||
* \param[in] rfm22b_id The RFM22B device index.
|
||||
* \param[in] coordinator Sets as coordinator if true.
|
||||
*/
|
||||
void PIOS_RFM22B_SetCoordinator(uint32_t rfm22b_id, bool coordinator)
|
||||
{
|
||||
struct pios_rfm22b_dev *rfm22b_dev = (struct pios_rfm22b_dev *)rfm22b_id;
|
||||
if (!PIOS_RFM22B_validate(rfm22b_dev))
|
||||
return;
|
||||
rfm22b_dev->coordinator = coordinator;
|
||||
|
||||
// Re-initialize the radio device.
|
||||
PIOS_RFM22B_InjectEvent(rfm22b_dev, RFM22B_EVENT_INITIALIZE, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the device statistics RFM22B device.
|
||||
* \param[in] rfm22b_id The RFM22B device index.
|
||||
@ -677,7 +771,6 @@ void PIOS_RFM22B_GetStats(uint32_t rfm22b_id, struct rfm22b_stats *stats) {
|
||||
rfm22_calculateLinkQuality(rfm22b_dev);
|
||||
|
||||
// We are connected if our destination ID is in the pair stats.
|
||||
rfm22b_dev->stats.connected = false;
|
||||
if (rfm22b_dev->destination_id != 0xffffffff)
|
||||
for (uint8_t i = 0; i < OPLINKSTATUS_PAIRIDS_NUMELEM; ++i)
|
||||
{
|
||||
@ -686,10 +779,10 @@ void PIOS_RFM22B_GetStats(uint32_t rfm22b_id, struct rfm22b_stats *stats) {
|
||||
{
|
||||
rfm22b_dev->stats.rssi = rfm22b_dev->pair_stats[i].rssi;
|
||||
rfm22b_dev->stats.afc_correction = rfm22b_dev->pair_stats[i].afc_correction;
|
||||
rfm22b_dev->stats.connected = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
rfm22b_dev->stats.tx_resent = rfm22b_dev->state;
|
||||
*stats = rfm22b_dev->stats;
|
||||
}
|
||||
|
||||
@ -752,7 +845,7 @@ bool PIOS_RFM22B_LinkStatus(uint32_t rfm22b_id)
|
||||
struct pios_rfm22b_dev *rfm22b_dev = (struct pios_rfm22b_dev *)rfm22b_id;
|
||||
if(!PIOS_RFM22B_validate(rfm22b_dev))
|
||||
return false;
|
||||
return rfm22b_dev->stats.connected && (rfm22b_dev->stats.link_quality > RFM22B_LINK_QUALITY_THRESHOLD);
|
||||
return (rfm22b_dev->stats.link_state == OPLINKSTATUS_LINKSTATE_CONNECTED) && (rfm22b_dev->stats.link_quality > RFM22B_LINK_QUALITY_THRESHOLD);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -766,6 +859,7 @@ static void PIOS_RFM22B_Task(void *parameters)
|
||||
portTickType lastEventTicks = xTaskGetTickCount();
|
||||
portTickType lastStatusTicks = lastEventTicks;
|
||||
portTickType lastPPMTicks = lastEventTicks;
|
||||
portTickType lastConnectTicks = lastEventTicks;
|
||||
|
||||
while(1)
|
||||
{
|
||||
@ -792,10 +886,7 @@ static void PIOS_RFM22B_Task(void *parameters)
|
||||
{
|
||||
// Has it been too long since the last event?
|
||||
portTickType curTicks = xTaskGetTickCount();
|
||||
if (curTicks < lastEventTicks)
|
||||
lastEventTicks = curTicks;
|
||||
portTickType ticksSinceEvent = curTicks - lastEventTicks;
|
||||
if ((ticksSinceEvent / portTICK_RATE_MS) > PIOS_RFM22B_SUPERVISOR_TIMEOUT)
|
||||
if (timeDifferenceMs(lastEventTicks, curTicks) > PIOS_RFM22B_SUPERVISOR_TIMEOUT)
|
||||
{
|
||||
// Transsition through an error event.
|
||||
rfm22_process_event(rfm22b_dev, RFM22B_EVENT_ERROR);
|
||||
@ -806,40 +897,33 @@ static void PIOS_RFM22B_Task(void *parameters)
|
||||
;
|
||||
lastEventTicks = xTaskGetTickCount();
|
||||
}
|
||||
else if (rfm22b_dev->state == RFM22B_STATE_RX_MODE)
|
||||
// Try to start a transmission
|
||||
rfm22_process_event(rfm22b_dev, RFM22B_EVENT_TX_START);
|
||||
}
|
||||
|
||||
// Have we locked up sending / receiving a packet?
|
||||
if (rfm22b_dev->packet_start_ticks > 0)
|
||||
{
|
||||
portTickType cur_ticks = xTaskGetTickCount();
|
||||
|
||||
// Did the clock wrap around?
|
||||
if (cur_ticks < rfm22b_dev->packet_start_ticks)
|
||||
rfm22b_dev->packet_start_ticks = (cur_ticks > 0) ? cur_ticks : 1;
|
||||
|
||||
// Have we been sending this packet too long?
|
||||
if (((cur_ticks - rfm22b_dev->packet_start_ticks) / portTICK_RATE_MS) > (rfm22b_dev->max_packet_time * 3))
|
||||
rfm22_process_event(rfm22b_dev, RFM22B_EVENT_TIMEOUT);
|
||||
}
|
||||
|
||||
// Queue up a ppm packet if it's time.
|
||||
portTickType curTicks = xTaskGetTickCount();
|
||||
// Rollover
|
||||
if (curTicks < lastPPMTicks)
|
||||
lastPPMTicks = curTicks;
|
||||
if (((curTicks - lastPPMTicks) / portTICK_RATE_MS) > PPM_UPDATE_PERIOD_MS)
|
||||
if (rfm22_sendPPM(rfm22b_dev))
|
||||
// Have we been sending this packet too long?
|
||||
if ((rfm22b_dev->packet_start_ticks > 0) && (timeDifferenceMs(rfm22b_dev->packet_start_ticks, curTicks) > (rfm22b_dev->max_packet_time * 3)))
|
||||
rfm22_process_event(rfm22b_dev, RFM22B_EVENT_TIMEOUT);
|
||||
|
||||
// Queue up a connection request packet if it's necessary
|
||||
else if (rfm22b_dev->coordinator && (rfm22b_dev->stats.link_state != OPLINKSTATUS_LINKSTATE_CONNECTED) && (timeDifferenceMs(lastConnectTicks, curTicks) > CONNECT_ATTEMPT_PERIOD_MS))
|
||||
{
|
||||
lastConnectTicks = curTicks;
|
||||
rfm22_process_event(rfm22b_dev, RFM22B_EVENT_INITIALIZE);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Queue up a PPM packet if it's time.
|
||||
if ((timeDifferenceMs(lastPPMTicks, curTicks) > PPM_UPDATE_PERIOD_MS) && rfm22_sendPPM(rfm22b_dev))
|
||||
lastPPMTicks = curTicks;
|
||||
// Rollover
|
||||
if (curTicks < lastStatusTicks)
|
||||
lastStatusTicks = curTicks;
|
||||
// Queue up a status packet if it's time.
|
||||
if (((curTicks - lastStatusTicks) / portTICK_RATE_MS) > RADIOSTATS_UPDATE_PERIOD_MS)
|
||||
if (rfm22_sendStatus(rfm22b_dev))
|
||||
|
||||
// Queue up a status packet if it's time.
|
||||
if ((timeDifferenceMs(lastStatusTicks, curTicks) > RADIOSTATS_UPDATE_PERIOD_MS) && rfm22_sendStatus(rfm22b_dev))
|
||||
lastStatusTicks = curTicks;
|
||||
|
||||
// Can we kick of a transmit?
|
||||
if (rfm22b_dev->prev_tx_packet && timeDifferenceMs(rfm22b_dev->tx_complete_ticks, curTicks) > rfm22b_dev->max_ack_delay)
|
||||
rfm22_process_event(rfm22b_dev, RFM22B_EVENT_PACKET_NACKED);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -865,6 +949,7 @@ void RFM22_SetDatarate(uint32_t rfm22b_id, enum rfm22b_datarate datarate, bool d
|
||||
uint32_t datarate_bps = data_rate[datarate];
|
||||
rfm22b_dev->datarate = datarate;
|
||||
rfm22b_dev->max_packet_time = (uint16_t)((float)(PIOS_PH_MAX_PACKET * 8 * 1000) / (float)(datarate_bps) + 0.5);
|
||||
rfm22b_dev->max_ack_delay = 25;
|
||||
|
||||
// rfm22_if_filter_bandwidth
|
||||
rfm22_write(0x1C, reg_1C[datarate]);
|
||||
@ -1206,14 +1291,45 @@ static enum pios_rfm22b_event rfm22_setRxMode(struct pios_rfm22b_dev *rfm22b_dev
|
||||
|
||||
static enum pios_rfm22b_event rfm22_txStart(struct pios_rfm22b_dev *rfm22b_dev)
|
||||
{
|
||||
// See if there's a packet on the packet queue.
|
||||
PHPacketHandle p;
|
||||
if (xQueueReceive(rfm22b_dev->packetQueue, &p, 0) != pdTRUE)
|
||||
PHPacketHandle p = NULL;
|
||||
|
||||
// See if there's a packet ready to send.
|
||||
if (rfm22b_dev->tx_packet)
|
||||
p = rfm22b_dev->tx_packet;
|
||||
|
||||
// Are we waiting for an ACK?
|
||||
else
|
||||
{
|
||||
// Clear the TX buffer.
|
||||
rfm22b_dev->tx_data_rd = rfm22b_dev->tx_data_wr = 0;
|
||||
return RFM22B_EVENT_RX_MODE;
|
||||
|
||||
// Don't send a packet if we're waiting for an ACK
|
||||
if (rfm22b_dev->prev_tx_packet)
|
||||
return RFM22B_EVENT_RX_MODE;
|
||||
|
||||
// Is there a packet in the queue to send?
|
||||
if (xQueueReceive(rfm22b_dev->packetQueue, &p, 0) != pdTRUE)
|
||||
p = NULL;
|
||||
|
||||
if (!p)
|
||||
{
|
||||
|
||||
// Try to get some data to send
|
||||
bool need_yield = false;
|
||||
p = &rfm22b_dev->data_packet;
|
||||
p->header.type = PACKET_TYPE_DATA;
|
||||
p->header.destination_id = rfm22b_dev->destination_id;
|
||||
p->header.data_size = (rfm22b_dev->tx_out_cb)(rfm22b_dev->tx_out_context, p->data,
|
||||
PH_MAX_DATA, NULL, &need_yield);
|
||||
if (p->header.data_size == 0)
|
||||
p = NULL;
|
||||
|
||||
// Don't send any data until we're connected.
|
||||
else if (rfm22b_dev->stats.link_state != OPLINKSTATUS_LINKSTATE_CONNECTED)
|
||||
return RFM22B_EVENT_RX_MODE;
|
||||
}
|
||||
|
||||
}
|
||||
if (!p)
|
||||
return RFM22B_EVENT_RX_MODE;
|
||||
|
||||
// Add the error correcting code.
|
||||
p->header.source_id = rfm22b_dev->deviceID;
|
||||
@ -1288,22 +1404,27 @@ static enum pios_rfm22b_event rfm22_txStart(struct pios_rfm22b_dev *rfm22b_dev)
|
||||
|
||||
static bool rfm22_sendStatus(struct pios_rfm22b_dev *rfm22b_dev)
|
||||
{
|
||||
PHPacketHandle sph = (PHPacketHandle)&(rfm22b_dev->status_packet);
|
||||
// We don't send status if we're a coordinator
|
||||
if (rfm22b_dev->coordinator)
|
||||
return true;
|
||||
|
||||
// Update the link quality metric.
|
||||
rfm22_calculateLinkQuality(rfm22b_dev);
|
||||
|
||||
// Queue the status message
|
||||
rfm22b_dev->status_packet.header.destination_id = 0xffffffff; // Broadcast
|
||||
PHPacketHandle sph = (PHPacketHandle)&(rfm22b_dev->status_packet);
|
||||
if (rfm22b_dev->stats.link_state == OPLINKSTATUS_LINKSTATE_CONNECTED)
|
||||
rfm22b_dev->status_packet.header.destination_id = rfm22b_dev->destination_id;
|
||||
else
|
||||
rfm22b_dev->status_packet.header.destination_id = 0xffffffff; // Broadcast
|
||||
rfm22b_dev->status_packet.header.type = PACKET_TYPE_STATUS;
|
||||
rfm22b_dev->status_packet.header.data_size = PH_STATUS_DATA_SIZE(&(rfm22b_dev->status_packet));
|
||||
rfm22b_dev->status_packet.link_quality = rfm22b_dev->stats.link_quality;
|
||||
rfm22b_dev->status_packet.received_rssi = rfm22b_dev->rssi_dBm;
|
||||
//rfm22b_dev->send_status = true;
|
||||
if (xQueueSend(rfm22b_dev->packetQueue, &sph, 0) != pdTRUE)
|
||||
return false;
|
||||
|
||||
// Process a SEND_PACKT event.
|
||||
rfm22_process_event(rfm22b_dev, RFM22B_EVENT_SEND_PACKET);
|
||||
rfm22_process_event(rfm22b_dev, RFM22B_EVENT_START_TRANSFER);
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -1444,7 +1565,7 @@ static enum pios_rfm22b_event rfm22_detectSync(struct pios_rfm22b_dev *rfm22b_de
|
||||
else if (rfm22b_dev->int_status2 & !RFM22_is2_ipreaval)
|
||||
{
|
||||
// Waiting for sync timed out.
|
||||
return RFM22B_EVENT_TX_START;
|
||||
return RFM22B_EVENT_START_TRANSFER;
|
||||
}
|
||||
|
||||
return RFM22B_EVENT_NUM_EVENTS;
|
||||
@ -1573,10 +1694,7 @@ static enum pios_rfm22b_event rfm22_rxData(struct pios_rfm22b_dev *rfm22b_dev)
|
||||
ret_event = RFM22B_EVENT_STATUS_RECEIVED;
|
||||
break;
|
||||
case PACKET_TYPE_CON_REQUEST:
|
||||
ret_event = RFM22B_EVENT_CONNECTION_REQUEST;
|
||||
break;
|
||||
case PACKET_TYPE_CON_ACCEPT:
|
||||
ret_event = RFM22B_EVENT_CONNECTION_ACCEPT;
|
||||
ret_event = RFM22B_EVENT_CONNECTION_REQUESTED;
|
||||
break;
|
||||
case PACKET_TYPE_DATA:
|
||||
{
|
||||
@ -1585,6 +1703,12 @@ static enum pios_rfm22b_event rfm22_rxData(struct pios_rfm22b_dev *rfm22b_dev)
|
||||
(rfm22b_dev->rx_in_cb)(rfm22b_dev->rx_in_context, rfm22b_dev->rx_packet.data, rfm22b_dev->rx_packet.header.data_size, NULL, &rx_need_yield);
|
||||
break;
|
||||
}
|
||||
case PACKET_TYPE_ACK:
|
||||
ret_event = RFM22B_EVENT_PACKET_ACKED;
|
||||
break;
|
||||
case PACKET_TYPE_NACK:
|
||||
ret_event = RFM22B_EVENT_PACKET_NACKED;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@ -1602,6 +1726,7 @@ static enum pios_rfm22b_event rfm22_rxData(struct pios_rfm22b_dev *rfm22b_dev)
|
||||
|
||||
static enum pios_rfm22b_event rfm22_txData(struct pios_rfm22b_dev *rfm22b_dev)
|
||||
{
|
||||
enum pios_rfm22b_event ret_event = RFM22B_EVENT_NUM_EVENTS;
|
||||
|
||||
// Read the device status registers
|
||||
if (!rfm22_readStatus(rfm22b_dev))
|
||||
@ -1645,16 +1770,93 @@ static enum pios_rfm22b_event rfm22_txData(struct pios_rfm22b_dev *rfm22b_dev)
|
||||
{
|
||||
rfm22b_dev->stats.tx_count++;
|
||||
rfm22b_dev->stats.tx_byte_count += PH_PACKET_SIZE(rfm22b_dev->tx_packet);
|
||||
// Free the tx packet
|
||||
PHReleaseTXPacket(pios_packet_handler, rfm22b_dev->tx_packet);
|
||||
ret_event = (rfm22b_dev->tx_packet->header.type == PACKET_TYPE_ACK) ? RFM22B_EVENT_TX_START : RFM22B_EVENT_RX_MODE;
|
||||
|
||||
// Do we require an ACK?
|
||||
if ((rfm22b_dev->tx_packet->header.type != PACKET_TYPE_ACK) && (rfm22b_dev->tx_packet->header.type != PACKET_TYPE_NACK))
|
||||
{
|
||||
rfm22b_dev->prev_tx_packet = rfm22b_dev->tx_packet;
|
||||
rfm22b_dev->tx_complete_ticks = xTaskGetTickCount();
|
||||
}
|
||||
else
|
||||
// Free the tx packet
|
||||
PHReleaseTXPacket(pios_packet_handler, rfm22b_dev->tx_packet);
|
||||
|
||||
rfm22b_dev->tx_packet = 0;
|
||||
rfm22b_dev->tx_data_wr = rfm22b_dev->tx_data_rd = 0;
|
||||
// Start a new transaction
|
||||
rfm22b_dev->packet_start_ticks = 0;
|
||||
return RFM22B_EVENT_TX_COMPLETE;
|
||||
}
|
||||
|
||||
return RFM22B_EVENT_NUM_EVENTS;
|
||||
return ret_event;
|
||||
}
|
||||
|
||||
/**
|
||||
* Send an ACK to a received packet.
|
||||
* \param[in] rfm22b_dev The device structure
|
||||
*/
|
||||
static enum pios_rfm22b_event rfm22_sendAck(struct pios_rfm22b_dev *rfm22b_dev)
|
||||
{
|
||||
PHAckNackPacketHandle aph = (PHAckNackPacketHandle)(&(rfm22b_dev->ack_nack_packet));
|
||||
aph->header.destination_id = rfm22b_dev->rx_packet.header.source_id;
|
||||
aph->header.type = PACKET_TYPE_ACK;
|
||||
aph->header.data_size = 0;
|
||||
aph->seq_num = rfm22b_dev->rx_packet.header.seq_num;
|
||||
//aph->ready_to_send = (uxQueueMessagesWaiting(rfm22b_dev->packetQueue) > 0);
|
||||
aph->ready_to_send = false;
|
||||
rfm22b_dev->tx_packet = (PHPacketHandle)aph;
|
||||
return RFM22B_EVENT_START_TRANSFER;
|
||||
}
|
||||
|
||||
/**
|
||||
* Send an NACK to a received packet.
|
||||
* \param[in] rfm22b_dev The device structure
|
||||
*/
|
||||
static enum pios_rfm22b_event rfm22_sendNack(struct pios_rfm22b_dev *rfm22b_dev)
|
||||
{
|
||||
PHAckNackPacketHandle aph = (PHAckNackPacketHandle)(&(rfm22b_dev->ack_nack_packet));
|
||||
aph->header.destination_id = rfm22b_dev->rx_packet.header.source_id;
|
||||
aph->header.type = PACKET_TYPE_NACK;
|
||||
aph->header.data_size = 0;
|
||||
aph->seq_num = rfm22b_dev->rx_packet.header.seq_num;
|
||||
rfm22b_dev->tx_packet = (PHPacketHandle)aph;
|
||||
return RFM22B_EVENT_START_TRANSFER;
|
||||
}
|
||||
|
||||
/**
|
||||
* Receive an ACK.
|
||||
* \param[in] rfm22b_dev The device structure
|
||||
*/
|
||||
static enum pios_rfm22b_event rfm22_receiveAck(struct pios_rfm22b_dev *rfm22b_dev)
|
||||
{
|
||||
PHPacketHandle prev = rfm22b_dev->prev_tx_packet;
|
||||
PHAckNackPacketHandle aph = (PHAckNackPacketHandle)&(rfm22b_dev->rx_packet);
|
||||
|
||||
// Clear the previous TX packet.
|
||||
rfm22b_dev->prev_tx_packet = NULL;
|
||||
|
||||
// Was this a connection request?
|
||||
if (prev->header.type == PACKET_TYPE_CON_REQUEST)
|
||||
return RFM22B_EVENT_CONNECTION_ACCEPTED;
|
||||
|
||||
// Should we try to start another TX?
|
||||
if (aph->ready_to_send)
|
||||
return RFM22B_EVENT_RX_MODE;
|
||||
else
|
||||
return RFM22B_EVENT_TX_START;
|
||||
}
|
||||
|
||||
/**
|
||||
* Receive an MACK.
|
||||
* \param[in] rfm22b_dev The device structure
|
||||
*/
|
||||
static enum pios_rfm22b_event rfm22_receiveNack(struct pios_rfm22b_dev *rfm22b_dev)
|
||||
{
|
||||
// Resend the previous TX packet.
|
||||
rfm22b_dev->tx_packet = rfm22b_dev->prev_tx_packet;
|
||||
rfm22b_dev->prev_tx_packet = NULL;
|
||||
//rfm22b_dev->stats.tx_resent++;
|
||||
return RFM22B_EVENT_START_TRANSFER;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1713,24 +1915,70 @@ static enum pios_rfm22b_event rfm22_receiveStatus(struct pios_rfm22b_dev *rfm22b
|
||||
return RFM22B_EVENT_RX_COMPLETE;
|
||||
}
|
||||
|
||||
static enum pios_rfm22b_event rfm22_initConnection(struct pios_rfm22b_dev *rfm22b_dev)
|
||||
{
|
||||
if (rfm22b_dev->coordinator)
|
||||
return RFM22B_EVENT_REQUEST_CONNECTION;
|
||||
else
|
||||
return RFM22B_EVENT_WAIT_FOR_CONNECTION;
|
||||
}
|
||||
|
||||
static enum pios_rfm22b_event rfm22_requestConnection(struct pios_rfm22b_dev *rfm22b_dev)
|
||||
{
|
||||
// Generate and set a connection request message.
|
||||
return RFM22B_EVENT_RX_COMPLETE;
|
||||
PHConnectionPacketHandle cph = &(rfm22b_dev->con_packet);
|
||||
|
||||
// Set our connection state to requesting connection.
|
||||
rfm22b_dev->stats.link_state = OPLINKSTATUS_LINKSTATE_CONNECTING;
|
||||
|
||||
// Fill in the connection request
|
||||
cph->header.destination_id = rfm22b_dev->destination_id;
|
||||
cph->header.type = PACKET_TYPE_CON_REQUEST;
|
||||
cph->header.data_size = PH_CONNECTION_DATA_SIZE(&(rfm22b_dev->con_packet));
|
||||
cph->datarate = rfm22b_dev->datarate;
|
||||
cph->frequency_hz = rfm22b_dev->frequency_hz;
|
||||
cph->min_frequency = rfm22b_dev->min_frequency;
|
||||
cph->max_frequency = rfm22b_dev->max_frequency;
|
||||
cph->max_tx_power = rfm22b_dev->tx_power;
|
||||
rfm22b_dev->tx_packet = (PHPacketHandle)cph;
|
||||
|
||||
return RFM22B_EVENT_START_TRANSFER;
|
||||
}
|
||||
|
||||
static enum pios_rfm22b_event rfm22_acceptConnection(struct pios_rfm22b_dev *rfm22b_dev)
|
||||
{
|
||||
return RFM22B_EVENT_RX_COMPLETE;
|
||||
// Set our connection state to connected
|
||||
rfm22b_dev->stats.link_state = OPLINKSTATUS_LINKSTATE_CONNECTED;
|
||||
|
||||
// Copy the connection packet
|
||||
PHConnectionPacketHandle cph = (PHConnectionPacketHandle)(&(rfm22b_dev->rx_packet));
|
||||
PHConnectionPacketHandle lcph = (PHConnectionPacketHandle)(&(rfm22b_dev->con_packet));
|
||||
memcpy((uint8_t*)lcph, (uint8_t*)cph, PH_PACKET_SIZE((PHPacketHandle)cph));
|
||||
|
||||
// Configure this modem from the connection request message.
|
||||
PIOS_RFM22B_SetDestinationId((uint32_t)rfm22b_dev, cph->header.source_id);
|
||||
RFM22_SetDatarate((uint32_t)rfm22b_dev, cph->datarate, true);
|
||||
PIOS_RFM22B_SetTxPower((uint32_t)rfm22b_dev, cph->max_tx_power);
|
||||
rfm22b_dev->min_frequency = cph->min_frequency;
|
||||
rfm22b_dev->max_frequency = cph->max_frequency;
|
||||
rfm22_setNominalCarrierFrequency(rfm22b_dev, cph->frequency_hz);
|
||||
|
||||
return RFM22B_EVENT_CONNECTION_ACCEPTED;
|
||||
}
|
||||
|
||||
static enum pios_rfm22b_event rfm22_connectionAccepted(struct pios_rfm22b_dev *rfm22b_dev)
|
||||
{
|
||||
return RFM22B_EVENT_RX_COMPLETE;
|
||||
}
|
||||
PHConnectionPacketHandle cph = (PHConnectionPacketHandle)(&(rfm22b_dev->con_packet));
|
||||
|
||||
// Set our connection state to connected
|
||||
rfm22b_dev->stats.link_state = OPLINKSTATUS_LINKSTATE_CONNECTED;
|
||||
|
||||
// Configure this modem from the connection request message.
|
||||
RFM22_SetDatarate((uint32_t)rfm22b_dev, cph->datarate, true);
|
||||
PIOS_RFM22B_SetTxPower((uint32_t)rfm22b_dev, cph->max_tx_power);
|
||||
rfm22b_dev->min_frequency = cph->min_frequency;
|
||||
rfm22b_dev->max_frequency = cph->max_frequency;
|
||||
rfm22_setNominalCarrierFrequency(rfm22b_dev, cph->frequency_hz);
|
||||
|
||||
static enum pios_rfm22b_event rfm22_connectionDeclined(struct pios_rfm22b_dev *rfm22b_dev)
|
||||
{
|
||||
return RFM22B_EVENT_RX_COMPLETE;
|
||||
}
|
||||
|
||||
@ -1997,7 +2245,7 @@ static enum pios_rfm22b_event rfm22_timeout(struct pios_rfm22b_dev *rfm22b_dev)
|
||||
rfm22b_dev->tx_data_rd = rfm22b_dev->tx_data_wr = 0;
|
||||
}
|
||||
rfm22b_dev->rx_buffer_wr = 0;
|
||||
return RFM22B_EVENT_TX_START;
|
||||
return RFM22B_EVENT_START_TRANSFER;
|
||||
}
|
||||
|
||||
static enum pios_rfm22b_event rfm22_error(struct pios_rfm22b_dev *rfm22b_dev)
|
||||
|
@ -89,29 +89,8 @@ static void PIOS_RFM22B_COM_TxStart(uint32_t rfm22b_id, uint16_t tx_bytes_avail)
|
||||
if (!PIOS_RFM22B_validate(rfm22b_dev))
|
||||
return;
|
||||
|
||||
// Get a packet when we see the sync
|
||||
PHPacketHandle p = PHGetTXPacket(pios_packet_handler);
|
||||
if (!p)
|
||||
return;
|
||||
|
||||
// Get some data to send
|
||||
bool need_yield = false;
|
||||
p->header.type = PACKET_TYPE_DATA;
|
||||
p->header.destination_id = rfm22b_dev->destination_id;
|
||||
p->header.data_size = (rfm22b_dev->tx_out_cb)(rfm22b_dev->tx_out_context, p->data,
|
||||
PH_MAX_DATA, NULL, &need_yield);
|
||||
if (p->header.data_size == 0)
|
||||
{
|
||||
PHReleaseTXPacket(pios_packet_handler, p);
|
||||
return;
|
||||
}
|
||||
|
||||
// Send the data packet.
|
||||
if (!PIOS_RFM22B_Send_Packet(rfm22b_id, p, 5))
|
||||
{
|
||||
rfm22b_dev->stats.tx_dropped++;
|
||||
PHReleaseTXPacket(pios_packet_handler, p);
|
||||
}
|
||||
// Send a signal to the radio to start a transmit.
|
||||
PIOS_RFM22B_InjectEvent(rfm22b_dev, RFM22B_EVENT_SEND_PACKET, false);
|
||||
}
|
||||
|
||||
static void PIOS_RFM22B_COM_RegisterRxCallback(uint32_t rfm22b_id, pios_com_callback rx_in_cb, uint32_t context)
|
||||
|
@ -83,12 +83,13 @@ struct rfm22b_stats {
|
||||
uint8_t rx_error;
|
||||
uint8_t rx_missed;
|
||||
uint8_t tx_dropped;
|
||||
uint8_t tx_resent;
|
||||
uint8_t resets;
|
||||
uint8_t timeouts;
|
||||
uint8_t link_quality;
|
||||
int8_t rssi;
|
||||
int8_t afc_correction;
|
||||
bool connected;
|
||||
uint8_t link_state;
|
||||
};
|
||||
|
||||
/* Public Functions */
|
||||
@ -97,6 +98,7 @@ extern void PIOS_RFM22B_SetFrequencyRange(uint32_t rfm22b_id, uint32_t min_frequ
|
||||
extern void PIOS_RFM22B_SetTxPower(uint32_t rfm22b_id, enum rfm22b_tx_power tx_pwr);
|
||||
extern void RFM22_SetDatarate(uint32_t rfm22b_id, enum rfm22b_datarate datarate, bool data_whitening);
|
||||
extern void PIOS_RFM22B_SetDestinationId(uint32_t rfm22b_id, uint32_t dest_id);
|
||||
extern void PIOS_RFM22B_SetCoordinator(uint32_t rfm22b_id, bool coordinator);
|
||||
extern uint32_t PIOS_RFM22B_DeviceID(uint32_t rfb22b_id);
|
||||
extern void PIOS_RFM22B_GetStats(uint32_t rfm22b_id, struct rfm22b_stats *stats);
|
||||
extern bool PIOS_RFM22B_Send_Packet(uint32_t rfm22b_id, PHPacketHandle p, uint32_t max_delay);
|
||||
|
@ -578,10 +578,11 @@ enum pios_rfm22b_state {
|
||||
RFM22B_STATE_UNINITIALIZED,
|
||||
RFM22B_STATE_INITIALIZING,
|
||||
RFM22B_STATE_INITIALIZED,
|
||||
RFM22B_STATE_INITIATING_CONNECTION,
|
||||
RFM22B_STATE_WAIT_FOR_CONNECTION,
|
||||
RFM22B_STATE_REQUESTING_CONNECTION,
|
||||
RFM22B_STATE_ACCEPTING_CONNECTION,
|
||||
RFM22B_STATE_CONNECTION_ACCEPTED,
|
||||
RFM22B_STATE_CONNECTION_DECLINED,
|
||||
RFM22B_STATE_RX_MODE,
|
||||
RFM22B_STATE_WAIT_PREAMBLE,
|
||||
RFM22B_STATE_WAIT_SYNC,
|
||||
@ -589,6 +590,10 @@ enum pios_rfm22b_state {
|
||||
RFM22B_STATE_RECEIVING_STATUS,
|
||||
RFM22B_STATE_TX_START,
|
||||
RFM22B_STATE_TX_DATA,
|
||||
RFM22B_STATE_SENDING_ACK,
|
||||
RFM22B_STATE_SENDING_NACK,
|
||||
RFM22B_STATE_RECEIVING_ACK,
|
||||
RFM22B_STATE_RECEIVING_NACK,
|
||||
RFM22B_STATE_TIMEOUT,
|
||||
RFM22B_STATE_ERROR,
|
||||
RFM22B_STATE_FATAL_ERROR,
|
||||
@ -601,16 +606,18 @@ enum pios_rfm22b_event {
|
||||
RFM22B_EVENT_INITIALIZE,
|
||||
RFM22B_EVENT_INITIALIZED,
|
||||
RFM22B_EVENT_REQUEST_CONNECTION,
|
||||
RFM22B_EVENT_REQUESTED_CONNECTION,
|
||||
RFM22B_EVENT_CONNECTION_REQUEST,
|
||||
RFM22B_EVENT_CONNECTION_ACCEPT,
|
||||
RFM22B_EVENT_CONNECTION_DECLINED,
|
||||
RFM22B_EVENT_WAIT_FOR_CONNECTION,
|
||||
RFM22B_EVENT_CONNECTION_REQUESTED,
|
||||
RFM22B_EVENT_CONNECTION_ACCEPTED,
|
||||
RFM22B_EVENT_PACKET_ACKED,
|
||||
RFM22B_EVENT_PACKET_NACKED,
|
||||
RFM22B_EVENT_RX_MODE,
|
||||
RFM22B_EVENT_PREAMBLE_DETECTED,
|
||||
RFM22B_EVENT_SYNC_DETECTED,
|
||||
RFM22B_EVENT_RX_COMPLETE,
|
||||
RFM22B_EVENT_STATUS_RECEIVED,
|
||||
RFM22B_EVENT_SEND_PACKET,
|
||||
RFM22B_EVENT_START_TRANSFER,
|
||||
RFM22B_EVENT_TX_START,
|
||||
RFM22B_EVENT_TX_STARTED,
|
||||
RFM22B_EVENT_TX_COMPLETE,
|
||||
@ -649,6 +656,9 @@ struct pios_rfm22b_dev {
|
||||
// The destination ID
|
||||
uint32_t destination_id;
|
||||
|
||||
// Is this device a coordinator?
|
||||
bool coordinator;
|
||||
|
||||
// The task handle
|
||||
xTaskHandle taskHandle;
|
||||
|
||||
@ -704,8 +714,12 @@ struct pios_rfm22b_dev {
|
||||
// The packet queue handle
|
||||
xQueueHandle packetQueue;
|
||||
|
||||
// The tx data packet
|
||||
PHPacket data_packet;
|
||||
// The current tx packet
|
||||
PHPacketHandle tx_packet;
|
||||
// The previous tx packet (waiting for an ACK)
|
||||
PHPacketHandle prev_tx_packet;
|
||||
// the tx data read index
|
||||
uint16_t tx_data_rd;
|
||||
// the tx data write index
|
||||
@ -713,13 +727,32 @@ struct pios_rfm22b_dev {
|
||||
// The tx packet sequence number
|
||||
uint16_t tx_seq;
|
||||
|
||||
// The rx packet
|
||||
// The rx data packet
|
||||
PHPacket rx_packet;
|
||||
// the receive buffer write index
|
||||
uint16_t rx_buffer_wr;
|
||||
// the receive buffer write index
|
||||
uint16_t rx_packet_len;
|
||||
|
||||
// The status packet
|
||||
PHStatusPacket status_packet;
|
||||
|
||||
// The ACK/NACK packet
|
||||
PHAckNackPacket ack_nack_packet;
|
||||
|
||||
#ifdef PIOS_PPM_RECEIVER
|
||||
// The PPM packet
|
||||
PHPpmPacket ppm_packet;
|
||||
#endif
|
||||
|
||||
// The connection packet.
|
||||
PHConnectionPacket con_packet;
|
||||
|
||||
// Send flags
|
||||
bool send_status;
|
||||
bool send_ppm;
|
||||
bool send_connection_request;
|
||||
|
||||
// The minimum frequency
|
||||
uint32_t min_frequency;
|
||||
// The maximum frequency
|
||||
@ -735,17 +768,11 @@ struct pios_rfm22b_dev {
|
||||
// afc correction reading (in Hz)
|
||||
int8_t afc_correction_Hz;
|
||||
|
||||
// The status packet
|
||||
PHStatusPacket status_packet;
|
||||
|
||||
#ifdef PIOS_PPM_RECEIVER
|
||||
// The PPM packet
|
||||
PHPpmPacket ppm_packet;
|
||||
#endif
|
||||
|
||||
// The maximum time (ms) that it should take to transmit / receive a packet.
|
||||
uint32_t max_packet_time;
|
||||
portTickType packet_start_ticks;
|
||||
portTickType tx_complete_ticks;
|
||||
uint8_t max_ack_delay;
|
||||
};
|
||||
|
||||
|
||||
@ -753,6 +780,7 @@ struct pios_rfm22b_dev {
|
||||
|
||||
bool PIOS_RFM22_EXT_Int(void);
|
||||
bool PIOS_RFM22B_validate(struct pios_rfm22b_dev * rfm22b_dev);
|
||||
void PIOS_RFM22B_InjectEvent(struct pios_rfm22b_dev *rfm22b_dev, enum pios_rfm22b_event event, bool inISR);
|
||||
|
||||
|
||||
// Global variable definitions
|
||||
|
@ -246,6 +246,9 @@ void PIOS_Board_Init(void) {
|
||||
}
|
||||
}
|
||||
|
||||
/* Configure the RFM22B device as coordinator or not */
|
||||
PIOS_RFM22B_SetCoordinator(pios_rfm22b_id, oplinkSettings.Coordinator == OPLINKSETTINGS_COORDINATOR_TRUE);
|
||||
|
||||
// Initialize the packet handler
|
||||
PacketHandlerConfig pios_ph_cfg = {
|
||||
.default_destination_id = 0xffffffff, // Broadcast
|
||||
|
Loading…
x
Reference in New Issue
Block a user