Skip to content
Draft
Show file tree
Hide file tree
Changes from 28 commits
Commits
Show all changes
52 commits
Select commit Hold shift + click to select a range
c48ddb1
1st
olliw42 May 24, 2024
d07e8e3
2nd, seems ok
olliw42 May 24, 2024
062b73a
nfc
olliw42 May 24, 2024
f43d224
change to ack with last received seq no
olliw42 May 27, 2024
67e45e5
ups
olliw42 May 27, 2024
19c5402
rx, previous frame handling corrected
olliw42 May 28, 2024
6d1ee37
Merge branch 'main' into dev-arq
olliw42 May 28, 2024
325d3c8
Merge branch 'main' into dev-arq
olliw42 May 28, 2024
197c44d
tx, correct mavlink parser reset
olliw42 May 28, 2024
4ea70dd
some streamlining, preperation
olliw42 May 29, 2024
d83bb71
more
olliw42 May 29, 2024
5e0f0c7
separate out error simulator
olliw42 May 30, 2024
fecd1d5
attempt at retry cnt
olliw42 May 30, 2024
19d4fe7
comment, nfc
olliw42 May 30, 2024
432324a
Merge branch 'main' into dev-arq
olliw42 May 31, 2024
f0204e1
that's strange, memset seems to fail if not unit8/char
olliw42 May 31, 2024
dab1168
rx, slight rearrangment, tidies
olliw42 May 31, 2024
3a00326
Merge branch 'main' into dev-arq
olliw42 Jun 1, 2024
b03ec59
Merge branch 'main' into dev-arq
olliw42 Jun 2, 2024
2a42d4d
rx, let flow control respect frame transmission rate, rx, adjust arq …
olliw42 Jun 3, 2024
f8636d1
tx, mavlink, add seq-based LQ metric
olliw42 Jun 5, 2024
5890cf0
Merge branch 'main' into dev-arq
olliw42 Jun 5, 2024
0f0754f
Merge branch 'main' into dev-arq
olliw42 Jun 6, 2024
75f4d30
Merge branch 'main' into dev-arq
olliw42 Jun 6, 2024
3f6b82b
Merge branch 'main' into dev-arq
olliw42 Jun 6, 2024
6e24f98
Merge branch 'main' into dev-arq
olliw42 Jun 7, 2024
2988cf5
rx, arq, more retries for 111Hz mode
olliw42 Jun 7, 2024
e2e0d7f
add compiled binaries
olliw42 Jun 7, 2024
1accf76
tx, arq, some (incomplete) improvements on frame lost
olliw42 Jun 8, 2024
25a423a
arq, framelost via limited seq_no attempt
olliw42 Jun 10, 2024
b0a7d7d
Merge branch 'main' into dev-arq
olliw42 Jun 11, 2024
3384f4a
remove sender side restriction to seq_no advancement. Add/keep simple…
olliw42 Jun 11, 2024
609eb22
update precompiled binaries
olliw42 Jun 12, 2024
bcd6c90
test, scan payload for marker
olliw42 Jun 12, 2024
5f43fc8
Merge branch 'main' into dev-arq
olliw42 Jun 20, 2024
30fce69
sync
olliw42 Jun 21, 2024
9d17218
new pre compiled
olliw42 Jun 21, 2024
b39c98b
Merge branch 'main' into dev-arq
olliw42 Jun 22, 2024
aa4c41f
precompiled
olliw42 Jun 22, 2024
37a4ab8
Merge branch 'main' into dev-arq
olliw42 Jun 25, 2024
3106187
cc
olliw42 Jun 28, 2024
517e8d9
Merge branch 'main' into dev-arq
olliw42 Jun 28, 2024
4b5971e
cc
olliw42 Jun 28, 2024
6df029a
Merge branch 'main' into dev-arq
olliw42 Jul 16, 2024
286d991
Merge branch 'main' into dev-arq
olliw42 Jul 19, 2024
ed4f274
formatting
olliw42 Jul 19, 2024
15fd452
Merge branch 'main' into dev-arq
olliw42 Jul 20, 2024
b20b9a5
Merge branch 'main' into dev-arq
olliw42 Jul 21, 2024
d69c5b4
some doc
olliw42 Jul 21, 2024
e74735a
tidy, nfc
olliw42 Jul 21, 2024
40a8cbc
try to do only rx->tx, doesn't fully work
olliw42 Jul 21, 2024
8199f4d
Merge branch 'dev-arq' into merge-main
olliw42 Jul 26, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3,250 changes: 3,250 additions & 0 deletions firmware/rx-E77-MBLKit-wle5cc-400-v1.2.05-dev-arq-@2988cf56.hex

Large diffs are not rendered by default.

3,249 changes: 3,249 additions & 0 deletions firmware/rx-E77-MBLKit-wle5cc-400-xtal-v1.2.05-dev-arq-@2988cf56.hex

Large diffs are not rendered by default.

3,262 changes: 3,262 additions & 0 deletions firmware/rx-E77-MBLKit-wle5cc-900-v1.2.05-dev-arq-@2988cf56.hex

Large diffs are not rendered by default.

3,261 changes: 3,261 additions & 0 deletions firmware/rx-E77-MBLKit-wle5cc-900-xtal-v1.2.05-dev-arq-@2988cf56.hex

Large diffs are not rendered by default.

2,679 changes: 2,679 additions & 0 deletions firmware/rx-FRM303-f072cb-v1.2.05-dev-arq-@2988cf56.hex

Large diffs are not rendered by default.

Binary file not shown.
3,099 changes: 3,099 additions & 0 deletions firmware/rx-R9M-f103c8-v1.2.05-dev-arq-@2988cf56.hex

Large diffs are not rendered by default.

2,966 changes: 2,966 additions & 0 deletions firmware/rx-R9MLitePro-v15-f303cc-v1.2.05-dev-arq-@2988cf56.hex

Large diffs are not rendered by default.

Binary file not shown.
2,970 changes: 2,970 additions & 0 deletions firmware/rx-R9MM-f103rb-v1.2.05-dev-arq-@2988cf56.hex

Large diffs are not rendered by default.

Binary file not shown.
3,021 changes: 3,021 additions & 0 deletions firmware/rx-R9MX-l433cb-v1.2.05-dev-arq-@2988cf56.hex

Large diffs are not rendered by default.

3,139 changes: 3,139 additions & 0 deletions firmware/rx-Wio-E5-Grove-wle5jc-v1.2.05-dev-arq-@2988cf56.hex

Large diffs are not rendered by default.

3,290 changes: 3,290 additions & 0 deletions firmware/rx-Wio-E5-Mini-wle5jc-v1.2.05-dev-arq-@2988cf56.hex

Large diffs are not rendered by default.

Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

3,256 changes: 3,256 additions & 0 deletions firmware/rx-easysolder-E77-E22-dual-wle5cc-v1.2.05-dev-arq-@2988cf56.hex

Large diffs are not rendered by default.

3,255 changes: 3,255 additions & 0 deletions firmware/rx-easysolder-E77-E22-dual-wle5cc-xtal-v1.2.05-dev-arq-@2988cf56.hex

Large diffs are not rendered by default.

3,558 changes: 3,558 additions & 0 deletions firmware/rx-easysolder-E77-E28-dualband-wle5cc-v1.2.05-dev-arq-@2988cf56.hex

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
4,919 changes: 4,919 additions & 0 deletions firmware/tx-E77-MBLKit-wle5cc-400-v1.2.05-dev-arq-@2988cf56.hex

Large diffs are not rendered by default.

4,918 changes: 4,918 additions & 0 deletions firmware/tx-E77-MBLKit-wle5cc-400-xtal-v1.2.05-dev-arq-@2988cf56.hex

Large diffs are not rendered by default.

4,931 changes: 4,931 additions & 0 deletions firmware/tx-E77-MBLKit-wle5cc-900-v1.2.05-dev-arq-@2988cf56.hex

Large diffs are not rendered by default.

4,930 changes: 4,930 additions & 0 deletions firmware/tx-E77-MBLKit-wle5cc-900-xtal-v1.2.05-dev-arq-@2988cf56.hex

Large diffs are not rendered by default.

6,020 changes: 6,020 additions & 0 deletions firmware/tx-FRM303-f072cb-oled-v1.2.05-dev-arq-@2988cf56.hex

Large diffs are not rendered by default.

5,120 changes: 5,120 additions & 0 deletions firmware/tx-FRM303-f072cb-usb-v1.2.05-dev-arq-@2988cf56.hex

Large diffs are not rendered by default.

Binary file not shown.
4,795 changes: 4,795 additions & 0 deletions firmware/tx-R9M-f103c8-v1.2.05-dev-arq-@2988cf56.hex

Large diffs are not rendered by default.

Binary file not shown.
3,388 changes: 3,388 additions & 0 deletions firmware/tx-R9MX-l433cb-v1.2.05-dev-arq-@2988cf56.hex

Large diffs are not rendered by default.

4,918 changes: 4,918 additions & 0 deletions firmware/tx-Wio-E5-Mini-wle5jc-sdiode-v1.2.05-dev-arq-@2988cf56.hex

Large diffs are not rendered by default.

4,989 changes: 4,989 additions & 0 deletions firmware/tx-Wio-E5-Mini-wle5jc-v1.2.05-dev-arq-@2988cf56.hex

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

4,929 changes: 4,929 additions & 0 deletions firmware/tx-easysolder-E77-E22-dual-wle5cc-v1.2.05-dev-arq-@2988cf56.hex

Large diffs are not rendered by default.

4,928 changes: 4,928 additions & 0 deletions firmware/tx-easysolder-E77-E22-dual-wle5cc-xtal-v1.2.05-dev-arq-@2988cf56.hex

Large diffs are not rendered by default.

5,215 changes: 5,215 additions & 0 deletions firmware/tx-easysolder-E77-E28-dualband-wle5cc-v1.2.05-dev-arq-@2988cf56.hex

Large diffs are not rendered by default.

Large diffs are not rendered by default.

384 changes: 384 additions & 0 deletions mLRS/Common/arq.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,384 @@
//*******************************************************
// Copyright (c) MLRS project
// GPL3
// https://www.gnu.org/licenses/gpl-3.0.de.html
// OlliW @ www.olliw.eu
//*******************************************************
// ARQ Transmit/Receive
//*******************************************************
/*
TODOs:
- how does it behave with approaching link loss?
- all well with flow control?
- double check that it doesn't break TRANSMIT_FRAME_TYPE_CMD communication
- is rxLQ correct?
Notes:
- Lua script load/reload leads to few packet losses with 1/4/5
*/
#ifndef ARQ_H
#define ARQ_H
#pragma once

#define USE_ARQ
#define USE_ARQ_RETRY_CNT -1 // -1: set by SetRetryCnt(), 0 = off, 255 = infinite,
//#define USE_ARQ_DBG
//#define USE_ARQ_TX_SIM_MISS 4 //9 // 0 = off
//#define USE_ARQ_RX_SIM_MISS 3 //5 //5 // 0 = off

#ifdef USE_ARQ

//-------------------------------------------------------
// Transmit
//-------------------------------------------------------

class tTransmitArq
{
public:
void Init(void);

typedef enum {
ARQ_TX_IDLE = 0,
ARQ_TX_FRAME_MISSED,
ARQ_TX_RECEIVED,
} ARQ_TX_ENUM;

void Disconnected(void);
void FrameMissed(void);
void Received(uint8_t ack_seq_no);

bool GetFreshPayload(void);
uint8_t SeqNo(void);
void SetRetryCnt(uint8_t retry_cnt);

void SetRetryCntAuto(int32_t _frame_cnt, uint8_t mode);

uint8_t status;
uint8_t received_ack_seq_no; // attention: is 0/1 only, 0 = even, 1 = odd
uint8_t payload_seq_no; // the seq_no associated to this payload
uint8_t payload_retry_cnt; // retry count for this payload
Comment thread
olliw42 marked this conversation as resolved.
Outdated
uint8_t payload_retries; // number of retries for this payload

bool SimulateMiss(void);
};


void tTransmitArq::Init(void)
{
status = ARQ_TX_IDLE;
received_ack_seq_no = 0;
payload_seq_no = 0;
payload_retry_cnt = UINT8_MAX; // 0 = off, 255 = infinite
payload_retries = 0;
}


// methods called upon receive or expected receive (in doPostReceive)
// the calling sequence is:
// 1. Received(seq_no) or FrameMissed() (in handle_receive() or handle_receive_none())
// 2. Disconnected()

void tTransmitArq::Disconnected(void)
{
status = ARQ_TX_IDLE;
}


void tTransmitArq::FrameMissed(void)
{
status = ARQ_TX_FRAME_MISSED;
}


void tTransmitArq::Received(uint8_t ack_seq_no)
{
received_ack_seq_no = ack_seq_no; // is 0/1
status = ARQ_TX_RECEIVED;
}


// methods called for transmit

// called at begin of prepare_transmit_frame()
bool tTransmitArq::GetFreshPayload(void)
{
if (payload_retry_cnt == 0) { // ARQ disabled, new payload each time
payload_seq_no++;
payload_retries = 0;
return true;
}

switch (status) {
case ARQ_TX_IDLE:
// send new payload
payload_seq_no++;
payload_retries = 0;
return true;

case ARQ_TX_RECEIVED:
Comment thread
olliw42 marked this conversation as resolved.
// keep previous payload if received_seq_no != payload_seq_no
// attention: received_seq_no is 1 bit!
// next = (received_seq_no & 0x01) == (payload_seq_no & 0x01)
if ((received_ack_seq_no & 0x01) != (payload_seq_no & 0x01)) {
Comment thread
olliw42 marked this conversation as resolved.
if (payload_retry_cnt == UINT8_MAX) { // ARQ with infinite retries, so never next
payload_retries = 0;
return false;
} else { // ARQ with finite retries
payload_retries++;
if (payload_retries <= payload_retry_cnt) { // we still can retry
return false;
}
}
}
payload_seq_no++; // give this payload the next seq_no
payload_retries = 0;
return true;

case ARQ_TX_FRAME_MISSED:
if (payload_retry_cnt == UINT8_MAX) { // ARQ with infinite retries, so never next
payload_retries = 0;
return false;
} else { // ARQ with finite retries
payload_retries++;
if (payload_retries > payload_retry_cnt) { // no further retry, send new payload
payload_seq_no++;
payload_retries = 0;
return true;
}
}
return false;
}

return false;
}


uint8_t tTransmitArq::SeqNo(void)
{
return payload_seq_no; // will be converted to 3 bit or 0...7
}


void tTransmitArq::SetRetryCnt(uint8_t retry_cnt)
{
#if USE_ARQ_RETRY_CNT < 0
payload_retry_cnt = retry_cnt;
#else
payload_retry_cnt = USE_ARQ_RETRY_CNT;
#endif
// payload_retries = 0; ?? I think to better not do this, allows to shorten retry cnt and the ARQ to react immediately
}


void tTransmitArq::SetRetryCntAuto(int32_t _frame_cnt, uint8_t mode)
{
switch (mode) {
case MODE_FLRC_111HZ:
if (_frame_cnt >= 800) {
SetRetryCnt(3);
} else if (_frame_cnt >= 700) {
SetRetryCnt(2);
} else {
SetRetryCnt(1);
}
break;
case MODE_FSK_50HZ:
case MODE_50HZ:
case MODE_31HZ:
case MODE_19HZ:
SetRetryCnt((_frame_cnt >= 800) ? 2 : 1);
}
SetRetryCnt(1);
}


// miscellaneous

bool tTransmitArq::SimulateMiss(void)
{
#if USE_ARQ_RX_SIM_MISS
static uint8_t miss_cnt = 0;
DECc(miss_cnt, USE_ARQ_RX_SIM_MISS);
if (miss_cnt == 0) return true;
#endif
return false;
}


//-------------------------------------------------------
// Receive
//-------------------------------------------------------

class tReceiveArq
{
public:
void Init(void);

typedef enum {
ARQ_RX_IDLE = 0,
ARQ_RX_FRAME_MISSED,
ARQ_RX_RECEIVED_WAS_IDLE,
ARQ_RX_RECEIVED,
} ARQ_RX_ENUM;

void Disconnected(void);
void FrameMissed(void);
void Received(uint8_t seq_no);

bool AcceptPayload(void);
bool FrameLost(void);

uint8_t AckSeqNo(void);

uint8_t status;
uint8_t received_seq_no_last; // all seq_no here are 3 bit, 0..7
uint8_t received_seq_no;
uint8_t ack_seq_no;
bool accept_received_payload; // maybe a state?
bool frame_lost; // maybe a state?

void spin(void);

bool SimulateMiss(void);
};


void tReceiveArq::Init(void)
{
status = ARQ_RX_IDLE;
received_seq_no = 0;
received_seq_no_last = 0;
accept_received_payload = false;
frame_lost = false;
ack_seq_no = 0;
}


// methods called upon receive or expected receive (in doPreTransmit)
// the calling sequence is:
// 1. Received(seq_no) or FrameMissed() (in handle_receive() or handle_receive_none())
// 2. AcceptPayload() (in process_received_frame())
// 3. FrameLost()
// 4. Disconnected()

void tReceiveArq::Disconnected(void)
{
status = ARQ_RX_IDLE;
}


void tReceiveArq::spin(void)
{
if (status == ARQ_RX_IDLE) { while(1); } // must not happen, should have been called after Missed,Received
Comment thread
olliw42 marked this conversation as resolved.
Outdated

switch (status) {
case ARQ_RX_RECEIVED_WAS_IDLE:
accept_received_payload = true;
received_seq_no_last = received_seq_no;
ack_seq_no = received_seq_no;
break;

case ARQ_RX_RECEIVED:
accept_received_payload = (received_seq_no != received_seq_no_last); // new seq no received, so accept it
received_seq_no_last = received_seq_no;
ack_seq_no = received_seq_no;
break;

case ARQ_RX_FRAME_MISSED: // is not called if handle_receive_none(), RX_STATUS_NONE !
accept_received_payload = false;
break;

default:
accept_received_payload = false;
}

frame_lost = false;
Comment thread
olliw42 marked this conversation as resolved.
Outdated
}


void tReceiveArq::FrameMissed(void)
{
status = ARQ_RX_FRAME_MISSED;
spin();
}


void tReceiveArq::Received(uint8_t seq_no)
{
received_seq_no = seq_no;
status = (status == ARQ_RX_IDLE) ? ARQ_RX_RECEIVED_WAS_IDLE : ARQ_RX_RECEIVED;
spin();
}


bool tReceiveArq::AcceptPayload(void)
{
return accept_received_payload;
}


bool tReceiveArq::FrameLost(void) // called to check if parsers need to be reset
{
return frame_lost;
}


// methods called for transmit

uint8_t tReceiveArq::AckSeqNo(void)
{
return ack_seq_no; // will be converted by 1 bit to 0/1
}


// miscellaneous

bool tReceiveArq::SimulateMiss(void)
{
#if USE_ARQ_TX_SIM_MISS
static uint8_t miss_cnt = 0;
DECc(miss_cnt, USE_ARQ_TX_SIM_MISS);
if (miss_cnt == 0) return true;
#endif
return false;
}


#else
// these should be nfc, i.e., result in exactly the same behavior as before

class tTransmitArq
{
public:
void Init(void) { seq_no = 0; }

void Disconnected(void) {}
void FrameMissed(void) {}
Comment thread
olliw42 marked this conversation as resolved.
void Received(uint8_t ack_seq_no) {}
Comment thread
olliw42 marked this conversation as resolved.
Outdated

bool GetFreshPayload(void) { return true; }
uint8_t SeqNo(void) { seq_no++; return seq_no; }
void SetRetryCnt(uint8_t retry_cnt) {}
void SetRetryCntAuto(int32_t _frame_cnt, uint8_t mode) {}

uint8_t seq_no;
};


class tReceiveArq
{
public:
void Init(void) {}

void Disconnected(void) {}
void FrameMissed(void) {}
void Received(uint8_t _seq_no) {}
bool AcceptPayload(void) { return true; }
bool FrameLost(void) { return false; }
Comment thread
olliw42 marked this conversation as resolved.

uint8_t AckSeqNo(void) { return 1; }
};

#undef USE_ARQ_DBG
#endif

#endif // ARQ_H
Loading