356 Commits

Author SHA1 Message Date
Michael Ossmann
9329c5e44e Detect hardware platform at run-time.
Firmware now detects the hardware it is running on at startup and
refuses to run if it is compiled for the wrong platform. The board ID
returned by firmware to the host is now derived from run-time detection
rather than a compile-time value. A separate method to retrieve
compile-time supported platform is added.

On HackRF One, pin straps are checked to determine hardware revision.
This is informational to aid troubleshooting and does not affect any
function.
2022-09-14 07:08:47 -04:00
Michael Ossmann
fdfe310f9a Merge pull request #1139 from martinling/tx-flush
Support flushing the device TX buffer before ending transmission
2022-09-14 05:45:40 -04:00
Martin Ling
7650236839 Flush buffer when CW mode is used with -n. 2022-09-12 16:50:53 +01:00
Martin Ling
0142ae6da9 Don't await buffer flush if interrupted by Ctrl-C. 2022-09-12 16:32:11 +01:00
Michael Ossmann
8a9af7a1ad hackrf_transfer: report on only actual transfers
The statistics reported to the user now reflect only completed USB
transfers and do not include information about the empty buffers that
are preloaded with data at the start of a TX operation.
2022-09-09 16:32:07 -04:00
Michael Ossmann
e7b19ef2c2 hackrf_transfer: accept CW amplitude up to 128 2022-09-09 05:17:28 -04:00
Michael Ossmann
755ca960e5 hackrf_transfer: report power, not amplitude
improve accuracy and reliability of digital signal power measurement
2022-09-09 05:15:15 -04:00
Martin Ling
8f60e6b66f Wait for TX buffer flush at end of hackrf_transfer. 2022-08-24 23:48:24 +01:00
Martin Ling
9b6a0259a7 Remove message when rewinding input file.
For small input files this may be printed a very large number of times.
2022-08-23 09:30:04 +01:00
Martin Ling
0c35cff05b In repeat mode, rewind file as many times as needed to fill buffer.
Fixes #720.
2022-08-23 09:30:04 +01:00
Martin Ling
06a0c2b189 One more early return to simplify TX callback. 2022-08-23 09:30:02 +01:00
Martin Ling
85a86b8baa Use more early returns to further simplify callbacks. 2022-08-23 09:29:13 +01:00
Martin Ling
bcaebc00c3 Use some early returns to reduce deeply indented callbacks. 2022-08-23 09:26:00 +01:00
Martin Ling
344af5094b Merge pull request #1131 from martinling/hackrf-transfer-validation
Additional argument validation for hackrf_transfer
2022-08-23 08:57:17 +01:00
Michael Ossmann
c703a72ac0 add parentheses to avoid compiler warning
avoids a warning from -Wparentheses
2022-08-23 08:44:29 +01:00
Michael Ossmann
04cb3a4084 Merge pull request #1133 from martinling/hackrf-transfer-timing
Overhaul timing in hackrf_transfer
2022-08-22 18:37:34 -04:00
Martin Ling
a09e9a20ed Overhaul timing in hackrf_transfer.
Rather than using sleep() for 1s at a time, set up an interval timer
that will fire once per second, and wait in the main loop for either
this or some other event.

On POSIX, the timing is set up with setitimer(), which generates a
SIGALRM signal each time the timer fires. The main loop runs pause() to
wait for any signal.

On Windows, the timing is set up using CreateWaitableTimer, which
provides an event handle that is set each time the timer fires. The main
loop runs WaitForMultipleObjects() to wait on this and an interrupt
event.

The TX and RX callbacks can now stop the main loop immediately when they
stop streaming. This fixes #1019.
2022-08-17 13:05:03 +01:00
Martin Ling
eeaaaf3b9b Make use of Win32 functions conditional on _WIN32, not _MSC_VER.
Using _MSC_VER here means that the choice of signal() versus
SetConsoleCtrlHandler depends on the compiler being used, rather
than the OS being targeted. When built with MinGW rather than MSVC,
this happens to work because MinGW's signal emulation is used, but
that emulation is quite limited.

Instead, be consistent and use the Win32 API when building for that
platform, regardless of compiler.

Note that if building for Cygwin, _WIN32 is not defined and POSIX
APIs are used.
2022-08-17 12:54:22 +01:00
Martin Ling
e88a0387cb Extend force option to frequency ranges outside 1MHz-6GHz. 2022-08-15 21:47:49 +01:00
Martin Ling
2e1f55c2d5 Add hackrf_transfer -F option to force unsupported sample rates. 2022-08-15 21:47:49 +01:00
Martin Ling
8c12fa6007 Validate sample rates passed to hackrf_transfer. 2022-08-15 21:47:42 +01:00
Martin Ling
2fe3185f9d Use an array of buffers for u64->ASCII conversions. 2022-08-15 21:46:36 +01:00
Martin Ling
ba148ee047 Add a simpler way to check CLKIN status. 2022-08-05 09:37:38 +01:00
Martin Ling
01e0702013 Print hackrf_sweep usage with a single fprintf call. 2022-08-03 23:46:46 +01:00
Martin Ling
c0d13de598 Add braces to all control statements without them. 2022-08-03 23:46:46 +01:00
Martin Ling
c3fdf402d7 Reformat all code to new clang-format standard. 2022-08-03 23:46:44 +01:00
Martin Ling
ebb9e43fde Move some trailing comments on long lines. 2022-08-03 23:42:55 +01:00
Martin Ling
414b4a98da hackrf_transfer: Split a long line in usage(). 2022-08-03 23:03:15 +01:00
Martin Ling
7f5ae870ec hackrf_transfer: Clean up WAV headers. 2022-08-03 23:03:15 +01:00
colt
b5057b87e8 Report an amplitude of value -INFINITY as is instead of showing it as
-0.0 dBfs
2022-08-02 18:44:28 -05:00
colt
b47a808eaa Do dB ratio check BEFORE it's used 2022-07-11 13:25:14 -05:00
colt
151b431c64 Fix #902 - Report transmit amplitude 2022-07-06 22:34:26 -05:00
Yan
19a9074039 Avoid warnings by using PRIu64 2022-03-21 13:53:40 +00:00
Martin Ling
f3633e285f Replace direct setting of M0 mode with a request/ack mechanism.
This change avoids various possible races in which an autonomous mode
change by the M0 might clobber a mode change made from the M4, as well
as related races on other state fields that can be written by the M4.

The previous mode field is replaced by two separate ones:

- active_mode, which is written only by the M0, and indicates the
  current operating mode.

- requested_mode, which is written by the M4 to request a change.
  This field includes both the requested mode, and a flag bit. The M4
  writes the field with the flag bit set, and must then wait for the
  M0 to signal completion of the request by clearing the flag bit.

Whilst the M4 is blocked waiting for the flag bit to be cleared, the
M0 can safely make all the required changes to the state that are
needed for the transition to the requested mode. Once the transition
is complete, the M0 clears the flag bit and the M4 continues execution.

Request handling is implemented in the idle loop. To handle requests,
mode-specific loops simply need to check the request flag and branch to
idle if it is set.

A request from the M4 to change modes will always require passing
through the idle loop, and is not subject to timing guarantees. Only
transitions made autonomously by the M0 have guaranteed timing
constraints.

The work previously done in reset_counts is now implemented as part of
the request handling, so the tx_start, rx_start and wait_start labels
are no longer required.

An extra two cycles are required in the TX shortfall path because we
must now load the active mode to check whether we are in TX_START.

Two cycles are saved in the normal TX path because updating the active
mode to TX_RUN can now be done without checking the previous value.
2022-02-13 17:53:34 +00:00
Martin Ling
137f2481e5 Make an error code available when a shortfall limit is hit.
Previously, finding the M0 in IDLE mode was ambiguous; it could indicate
either a normal outcome, or a shortfall limit having being hit.

To disambiguate, we add an error field to the M0 state. The errors
currently possible are an RX timeout or a TX timeout, both of which
can be obtained efficiently from the current operating mode due to
the values used.

This adds 3 cycles to both shortfall paths, in order to shift down
the mode to obtain the error code, and store it to the M0 state.
2022-02-13 17:53:34 +00:00
Martin Ling
cca7320fe4 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.
2022-02-13 16:46:12 +00:00
Martin Ling
3618a5352f 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).
2022-02-13 16:46:12 +00:00
Martin Ling
00b5ed7d62 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.
2022-02-13 16:46:12 +00:00
Martin Ling
5abc39c53a Add USB requests and host support to set TX/RX shortfall limits.
This adds `-T` and `-R` options to `hackrf_debug`, which set the TX
underrun and RX overrun limits in bytes.
2022-02-13 16:46:12 +00:00
Martin Ling
2f79c03b2c hackrf_debug: allow parse_int() to handle 32-bit parameters. 2022-02-13 16:46:12 +00:00
Martin Ling
f0bc6eda30 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.
2022-02-13 16:46:12 +00:00
Martin Ling
2c86f493d9 Keep track of longest shortfall.
This adds six cycles to the TX and RX shortfall paths.
2022-02-13 16:46:12 +00:00
Martin Ling
a7bd1e3ede Keep count of number of shortfalls.
To enable this, we keep a count of the current shortfall length. Each
time an SGPIO read/write cannot be completed due to a shortfall, we
increase this length. Each time an SGPIO read/write is completed
successfully, we reset the shortfall length to zero.

When a shortfall occurs and the existing shortfall length is zero, this
indicates a new shortfall, and the shortfall count is incremented.

This change adds one cycle to the normal RX & TX paths, to zero the
shortfall count. To enable this to be done in a single cycle, we keep a
zero handy in a high register.

The extra accounting adds 10 cycles to the TX and RX shortfall paths,
plus an additional 3 cycles to the RX shortfall path since there are
now two branches involved: one to the shortfall handler, and another
back to the main loop.
2022-02-13 16:46:12 +00:00
Martin Ling
32c725dd61 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.
2022-02-13 16:46:12 +00:00
Martin Ling
5b50b2dfac Replace TX flag with a mode setting.
This is to let us start adding new operatin modes for the M0.
2022-02-13 16:46:12 +00:00
Martin Ling
c8d120ff6c Display total M0 and M4 counts at end of hackrf_transfer.
Doing this requires keeping track of when the 32-bit counters wrap, and
updating 64-bit running totals.
2022-02-13 16:46:12 +00:00
Martin Ling
eb2be7995c Add hackrf_transfer option to display buffer stats.
This adds the `hackrf_transfer -B` option, which displays the number of
bytes currently in the buffer along with the existing per-second stats.

The number of bytes in the buffer is indicated by the difference between
the M0 and M4 byte counters. In TX, the M4 count should lead the M0 count.
In RX, the M0 count should lead the M4 count.
2022-02-13 16:46:12 +00:00
Martin Ling
79853d2b28 Add a second counter to keep track of bytes transferred by the M4.
With both counters in place, the number of bytes in the buffer is now
indicated by the difference between the M0 and M4 counts.

The M4 count needs to be increased whenever the M4 produces or consumes
data in the USB bulk buffer, so that the two counts remain correctly
synchronised.

There are three places where this is done:

1. When a USB bulk transfer in or out of the buffer completes, the count
   is increased by the number of bytes transferred. This is the most
   common case.

2. At TX startup, the M4 effectively sends the M0 16K of zeroes to
   transmit, before the first host-provided data.

   This is done by zeroing the whole 32K buffer area, and then setting
   up the first bulk transfer to write to the second 16K, whilst the M0
   begins transmission of the first 16K.

   The count is therefore increased by 16K during TX startup, to account
   for the initial 16K of zeros.

3. In sweep mode, some data is discarded. When this is done, the count
   is incremented by the size of the discarded data.

   The USB IRQ is masked whilst doing this, since a read-modify-write is
   required, and the bulk transfer completion callback may be called at
   any point, which also increases the count.
2022-02-13 16:46:12 +00:00
Martin Ling
21dabc920f Replace M0 state offset field with a byte count.
Instead of this count wrapping at the buffer size, it now increments
continuously. The offset within the buffer is now obtained from the
lower bits of the count.

This makes it possible to keep track of the total number of bytes
transferred by the M0 core.

The count will wrap at 2^32 bytes, which at 20Msps will occur every
107 seconds.
2022-02-13 16:46:12 +00:00
Martin Ling
fd073e391f Add USB vendor request to read M0 state, and host support for doing so.
This adds a `hackrf_debug [-S|--state]` option, and the necessary
plumbing to libhackrf and the M4 firmware to support it.

The USB API and libhackrf versions are bumped to reflect the changes.
2022-02-13 16:46:12 +00:00