Add a shortfall length limit.

This limit allows implementing a timeout: if a TX underrun or RX overrun
continues for the specified number of bytes, the M0 will revert to idle.

A setting of zero disables the limit.

This change adds 5 cycles to the TX & RX shortfall paths, to check if a
limit is set and to check the shortfall length against the limit.
This commit is contained in:
Martin Ling
2021-12-24 09:47:27 +00:00
parent 2c86f493d9
commit f0bc6eda30
4 changed files with 21 additions and 4 deletions

View File

@ -31,6 +31,7 @@ struct m0_state {
uint32_t m4_count;
uint32_t num_shortfalls;
uint32_t longest_shortfall;
uint32_t shortfall_limit;
};
enum m0_mode {

View File

@ -67,9 +67,9 @@ shadow registers.
There are four key code paths, with the following worst-case timings:
RX, normal: 147 cycles
RX, overrun: 71 cycles
RX, overrun: 76 cycles
TX, normal: 133 cycles
TX, underrun: 135 cycles
TX, underrun: 140 cycles
Design
======
@ -113,6 +113,7 @@ registers and fixed memory addresses.
.equ M4_COUNT, 0x08
.equ NUM_SHORTFALLS, 0x0C
.equ LONGEST_SHORTFALL, 0x10
.equ SHORTFALL_LIMIT, 0x14
// Operating modes.
.equ MODE_IDLE, 0
@ -174,6 +175,7 @@ main:
str zero, [state, #M4_COUNT] // state.m4_count = zero // 2
str zero, [state, #NUM_SHORTFALLS] // state.num_shortfalls = zero // 2
str zero, [state, #LONGEST_SHORTFALL] // state.longest_shortfall = zero // 2
str zero, [state, #SHORTFALL_LIMIT] // state.shortfall_limit = zero // 2
idle:
// Wait for RX or TX mode to be set.
@ -309,8 +311,19 @@ extend_shortfall:
blt loop // goto loop // 1 thru, 3 taken
str length, [state, #LONGEST_SHORTFALL] // state.longest_shortfall = length // 2
// Return to main loop.
b loop // goto loop // 3
// Is this shortfall long enough to trigger a timeout?
limit .req r1
ldr limit, [state, #SHORTFALL_LIMIT] // limit = state.shortfall_limit // 2
cmp limit, #0 // if limit == 0: // 1
beq loop // goto loop // 1 thru, 3 taken
cmp length, limit // if length < limit: // 1
blt loop // goto loop // 1 thru, 3 taken
// If so, reset mode to idle and return to idle loop.
mode .req r3
mov mode, #MODE_IDLE // mode = MODE_IDLE // 1
str mode, [state, #MODE] // state.mode = mode // 2
b idle // goto idle // 3
direction_rx:

View File

@ -390,6 +390,7 @@ static void print_state(hackrf_m0_state *state) {
printf("M4 count: %u bytes\n", state->m4_count);
printf("Number of shortfalls: %u\n", state->num_shortfalls);
printf("Longest shortfall: %u bytes\n", state->longest_shortfall);
printf("Shortfall limit: %u bytes\n", state->shortfall_limit);
}
static void usage() {

View File

@ -167,6 +167,8 @@ typedef struct {
uint32_t num_shortfalls;
/** Longest shortfall. */
uint32_t longest_shortfall;
/** Shortfall limit in bytes. */
uint32_t shortfall_limit;
} hackrf_m0_state;
struct hackrf_device_list {