Add an idle mode for the M0.

In the idle mode, the M0 simply waits for a different mode to be set.
No SGPIO access is done.

One extra cycle is added to both TX code paths, to check whether the
M0 should return to the idle loop based on the mode setting. The RX
paths are unaffected as the branch to RX is handled first.
This commit is contained in:
Martin Ling
2021-12-24 08:27:34 +00:00
parent 5b50b2dfac
commit 32c725dd61
3 changed files with 18 additions and 8 deletions

View File

@ -32,8 +32,9 @@ struct m0_state {
};
enum m0_mode {
M0_MODE_RX = 0,
M0_MODE_TX = 1,
M0_MODE_IDLE = 0,
M0_MODE_RX = 1,
M0_MODE_TX = 2,
};
/* Address of m0_state is set in ldscripts. If you change the name of this

View File

@ -68,8 +68,8 @@ There are four key code paths, with the following worst-case timings:
RX, normal: 146 cycles
RX, overrun: 52 cycles
TX, normal: 131 cycles
TX, underrun: 118 cycles
TX, normal: 132 cycles
TX, underrun: 119 cycles
Design
======
@ -113,8 +113,9 @@ registers and fixed memory addresses.
.equ M4_COUNT, 0x08
// Operating modes.
.equ MODE_RX, 0
.equ MODE_TX, 1
.equ MODE_IDLE, 0
.equ MODE_RX, 1
.equ MODE_TX, 2
// Our slice chain is set up as follows (ascending data age; arrows are reversed for flow):
// L -> F -> K -> C -> J -> E -> I -> A
@ -167,6 +168,13 @@ main:
str zero, [state, #M0_COUNT] // state.m0_count = zero // 2
str zero, [state, #M4_COUNT] // state.m4_count = zero // 2
idle:
// Wait for RX or TX mode to be set.
mode .req r0
ldr mode, [state, #MODE] // mode = state.mode // 2
cmp mode, #MODE_IDLE // if mode == IDLE: // 1
beq idle // goto idle // 1 thru, 3 taken
loop:
// The worst case timing is assumed to occur when reading the interrupt
// status register *just* misses the flag being set - so we include the
@ -208,9 +216,10 @@ loop:
mode .req r0
ldr mode, [state, #MODE] // mode = state.mode // 2
// TX?
// Branch according to mode setting.
cmp mode, #MODE_RX // if mode == RX: // 1
beq direction_rx // goto direction_rx // 1 thru, 3 taken
blt idle // elif mode < RX: goto idle // 1 thru, 3 taken
direction_tx:

View File

@ -378,7 +378,7 @@ int write_register(hackrf_device* device, uint8_t part,
}
static void print_state(hackrf_m0_state *state) {
const char *mode_names[] = {"RX", "TX"};
const char *mode_names[] = {"IDLE", "RX", "TX"};
const uint32_t num_modes = sizeof(mode_names) / sizeof(mode_names[0]);
printf("M0 state:\n");
printf("Mode: %u (%s)\n",