diff --git a/firmware/hackrf_usb/m0_state.h b/firmware/hackrf_usb/m0_state.h index db79c6db..2ce24980 100644 --- a/firmware/hackrf_usb/m0_state.h +++ b/firmware/hackrf_usb/m0_state.h @@ -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 { diff --git a/firmware/hackrf_usb/sgpio_m0.s b/firmware/hackrf_usb/sgpio_m0.s index ec26b2b3..b2189c9c 100644 --- a/firmware/hackrf_usb/sgpio_m0.s +++ b/firmware/hackrf_usb/sgpio_m0.s @@ -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: diff --git a/host/hackrf-tools/src/hackrf_debug.c b/host/hackrf-tools/src/hackrf_debug.c index 96895e5d..ee90435e 100644 --- a/host/hackrf-tools/src/hackrf_debug.c +++ b/host/hackrf-tools/src/hackrf_debug.c @@ -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() { diff --git a/host/libhackrf/src/hackrf.h b/host/libhackrf/src/hackrf.h index da5dded1..5bd23aed 100644 --- a/host/libhackrf/src/hackrf.h +++ b/host/libhackrf/src/hackrf.h @@ -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 {