Add a wait mode for the M0.
by Martin Ling 3 years 10 months
Add a wait mode for the M0.

In wait mode, the byte counter is advanced, but no SGPIO read/writes are
done. This mode is intended to be used for implementing timed operations.
cca7320f
Add a counter threshold at which the M0 will chang...
by Martin Ling 3 years 10 months
Add a counter threshold at which the M0 will change to a new mode.

This lays the groundwork for implementing timed operations (#86). The M0
can be configured to automatically change modes when its byte count
reaches a specific value.

Checking the counter against the threshold and dispatching to the next
mode is handled by a new `jump_next_mode` macro, which replaces the
unconditional branches back to the start of the TX and RX loops.

Making this change work requires some rearrangement of the code, such
that the destinations of all conditional branch instructions are within
reach. These branch instructions (`b[cond] label`) have a range of -256
to +254 bytes from the current program counter.

For this reason, the TX shortfall handling is moved earlier in the file,
and branches in the idle loop are restructured to use an unconditional
branch to rx_start, which is furthest away.

The additional code for switching modes adds 9 cycles to the normal RX
path, and 10 to the TX path (the difference is because the dispatch in
`jump_next_mode` is optimised for the longer RX path).
3618a535
Roll back shortfall stats if switched to idle in a...
by Martin Ling 3 years 10 months
Roll back shortfall stats if switched to idle in a shortfall.

During shutdown of TX or RX, the host may stop supplying or retrieving
sample data some time before a stop request causes the M0 to be set back
to idle mode.

This makes it common for a spurious shortfall to occur during shutdown,
giving the misleading impression that there has been a throughput
problem. In fact, the final shortfall is simply an artifact.

This commit detects when this happens, and excludes the spurious
shortfall from the stats.

To implement this, we back up the shortfall stats whenever a new
shortfall begins. If the new shortfall later turns out to be spurious,
as indicated by a transition to IDLE while it is ongoing, then we roll
back the stats to their previous values.

We actually only need to back up previous longest shortfall length. To
get a previous shortfall count, can simply to subtract one from the
current shortfall count.

This change adds four cycles to the two shortfall paths - a load and
store to back up the previous longest shortfall length.
7124b719
Don't update buffer pointer until after checking f...
by Martin Ling 3 years 10 months
Don't update buffer pointer until after checking for shortfall.

The buffer pointer is not needed in the shortfall paths. Moving this
update after the shortfall checks saves 3 cycles in each shortfall path.
a5e15215
Don't load M0 byte count from memory.
by Martin Ling 3 years 10 months
Don't load M0 byte count from memory.

This count is only written by the M0, so there's no need to reload it
when the current value is already retained in a register.

Removing this load saves two cycles in all code paths.
0e99419b
Use separate loops for RX and TX modes.
by Martin Ling 3 years 10 months
Use separate loops for RX and TX modes.

Using our newly-defined macros, it's now straightforward to write
separate loops for RX and TX, with the idle loop dispatching to them
when a new mode setting is written by the M4.

This saves some cycles by reducing branches needed within each loop, and
makes it simpler to add new modes.

For macros which use internal labels, a name parameter is added. This
parameter is prefixed to the labels used, so that each mode's use of
that macro produces its own label names.

Similarly, where branches were taken in the handle_shortfall macro to
the "loop" label, these are replaced with the appropriate tx_loop or
rx_loop label.

The syntax `\name\()_suffix` is necessary to perform concatenation in
the GNU assembler.
4e205994
Use new macros in M0 code.
by Martin Ling 3 years 10 months
Use new macros in M0 code.

This commit is separate from the previous one which adds the macros, in
order to make the diffs easier to read.
f08e0c17
Add macro versions of key parts of M0 code.
by Martin Ling 3 years 10 months
Add macro versions of key parts of M0 code.

This commit is separate from the following one which uses the macros, in
order to make the diffs easier to read.
9d570cb5
Don't send 16K of zeroes to the M0 at TX startup.
by Martin Ling 3 years 10 months
Don't send 16K of zeroes to the M0 at TX startup.

The M4 previously buffered 16K of zeroes for the M0 to transmit, whilst
waiting for the first USB bulk transfer from the host to complete. The
first bulk transfer was placed in the second 16K buffer.

This avoided the M0 transmitting uninitialised data, but was not a
reliable solution, and delayed the transmission of the first
host-supplied samples.

Now that the M0 is placed in TX_START mode, this trick is no longer
necessary, because the M0 can automatically send zeroes until the first
bulk transfer is completed.

As such, the first bulk transfer now goes to the first 16K buffer.
Once the M4 byte count is increased by the bulk transfer completion
callback, the M0 will start transmitting the samples immediately.
68688e0e
Add an M0 TX_START mode, in which zeroes are sent ...
by Martin Ling 3 years 10 months
Add an M0 TX_START mode, in which zeroes are sent until data is ready.

In TX_START mode, a lack of data to send is not treated as a shortfall.
Zeroes are written to SGPIO, but no shortfall is recorded in the stats.
Using this mode helps avoid spurious shortfalls at startup.

As soon as there is data to transmit, the M0 switches to TX_RUN mode.

This change adds five cycles to the normal TX path, in order to check
for TX_START mode before sending data, and to switch to TX_RUN in that
case.

It also adds two cycles to the TX shortfall path, to check for TX_START
mode and skip shortfall processing in that mode.

Note the allocation of r3 to store the mode setting, such that this
value is still available after the tx_zeros routine.
00b5ed7d
Report a bug