/**

\page relnotes_2_0_0 libbladeRF 2.0.0 Release Notes

This page describes many of the changes in libbladeRF 2.0.0, our first major
version increment in more than three years. This release adds support for the
bladeRF Micro, and improves the API for all bladeRF products. This is also the
first release with bindings for the Python programming language.

@attention libbladeRF 2.0.0 introduces breaking changes to the parameter lists
           for bladerf_get_frequency(), bladerf_stream(), and
           bladerf_sync_config().
@attention Existing code using these functions @b must be updated to be
           compatible with this version. See the
           \ref relnotes_2_0_0_api_freq_uint64 and
           \ref relnotes_2_0_0_api_stream sections for guidance.

We are very excited to release this library alongside the new bladeRF Micro.
libbladeRF 2.0.0 began as a fork of the bladeRF codebase in February 2017.
Across the FPGA, firmware, and host software trees, four engineers added
95,000+ lines (and deleted 18,000+) to the bladeRF codebase, in more than 600
commits.

Inevitably, there will be bugs or missing features. Please use our issue
tracker at https://github.com/Nuand/bladeRF/issues to report any problems
you encounter with this release. Also, visit our forums at
https://nuand.com/forums/ to discuss this release with other bladeRF users.

\tableofcontents

\section relnotes_2_0_0_api Significant changes to the libbladeRF API

We attempted to minimize the changes required to make existing applications
work with libbladeRF 2.x. However, the nature of this project required some
changes to the API.

Many of the changes can be transparently handled by compilers. However,
applications will generally need to be recompiled and relinked to work with
this version.

\subsection relnotes_2_0_0_api_freq_uint64 Tuning frequencies are now uint64_t

In libbladeRF 1.x, RF frequencies were specified as 32-bit `unsigned int`. To
support the wider frequency range of the bladeRF Micro, frequencies are now
specified as `uint64_t`, which is typedef'd as `bladerf_frequency`.

<table>
<caption id="multi_row">Required actions</caption>
<tr><th>API Component</th><th>Importance</th><th>Action</th></tr>
<tr>
    <td>bladerf_get_frequency()</td>
    <td><b>Required</b></td>
    <td>
        The `frequency` parameter is now of type `bladerf_frequency*`.

        \warning Applications using this function must be modified to pass in
                 the correct type.
    </td>
</tr>
<tr>
    <td>bladerf_set_frequency()</td>
    <td rowspan="3">Minor</td>
    <td rowspan="3">
        The `frequency` parameter is now of type `bladerf_frequency`.

        \note Compilers will generally implicitly cast `unsigned int` to
              `bladerf_frequency`.
    </td>
</tr>
<tr><td>bladerf_select_band()</td></tr>
<tr><td>bladerf_schedule_retune()</td></tr>
</table>

\subsection relnotes_2_0_0_api_stream MIMO support in streaming API

The data transfer APIs were expanded to support MIMO (multiple-input,
multiple-output). This capability is used to transmit or receive samples via
multiple RF ports simultaneously.

<table>
<caption id="multi_row">Required actions</caption>
<tr><th>API Component</th><th>Importance</th><th>Action</th></tr>
<tr>
    <td>bladerf_sync_config()</td>
    <td rowspan="2"><b>Required</b></td>
    <td rowspan="2">
        The `bladerf_module` argument has been replaced with
        \ref bladerf_channel_layout.

        Replace `BLADERF_MODULE_RX` with \ref BLADERF_RX_X1, and
        `BLADERF_MODULE_TX` with \ref BLADERF_TX_X1.

        \warning Applications using these functions must be modified to pass
                 in the correct type.

        \note Existing `bladerf_module` values are valid for SISO applications,
              but an explicit cast is required:
```
void configure_module_sync(bladerf_module module) {
    // ...
    status = bladerf_sync_config(dev, (bladerf_channel_layout)module, format, num_buffers, buffer_size, num_transfers, stream_timeout);
    // ...
}
```
    </td>
</tr>
<tr><td>bladerf_stream()</td></tr>
<tr>
    <td>bladerf_get_timestamp()</td>
    <td rowspan="4">Minor</td>
    <td rowspan="3">
        The `bladerf_module` argument has been replaced with
        \ref bladerf_direction.

        Replace `BLADERF_MODULE_RX` with \ref BLADERF_RX, and
        `BLADERF_MODULE_TX` with \ref BLADERF_TX.

        \note Existing `bladerf_module` values are still valid, and a cast
              should not be necessary.
    </td>
</tr>
<tr><td>bladerf_set_stream_timeout()</td></tr>
<tr><td>bladerf_get_stream_timeout()</td></tr>
<tr>
    <td>bladerf_sync_tx()</td>
    <td>
        The `samples` parameter is now a pointer to a `const`.

        This should not impact user code.
    </td>
</tr>
</table>

\see \ref BLADERF_FORMAT_SC16_Q11 describes the sample interleaving format.
\see bladerf_interleave_stream_buffer() - Interleaves contiguous blocks of
     samples in preparation for MIMO TX.
\see bladerf_deinterleave_stream_buffer() - Deinterleaves samples into
     contiguous blocks after MIMO RX.
\see bladerf_get_channel_count() - Get the number of RX or TX channels
     supported by the given device.

\subsection relnotes_2_0_0_api_channel bladerf_channel replaces bladerf_module

In libbladeRF 1.x, `bladerf_module` was an enum with two valid choices:
`BLADERF_MODULE_RX` and `BLADERF_MODULE_TX`. To support MIMO, this enum has
been replaced with \ref bladerf_channel, and a pair of convenience macros have
been defined to specify channels: BLADERF_CHANNEL_RX(ch) and
BLADERF_CHANNEL_TX(ch).

For backwards compatibility, `bladerf_module` is a typedef of
\ref bladerf_channel, and the `BLADERF_MODULE_RX` and `BLADERF_MODULE_TX`
identifiers are now macros for BLADERF_CHANNEL_RX(0) and BLADERF_CHANNEL_TX(0)
respectively.

Note that some `bladerf_module` instances have been replaced with
\ref bladerf_direction and \ref bladerf_channel_layout depending on context.
See the \ref api_stream section elsewhere in this document.

<table>
<caption id="multi_row">Required actions</caption>
<tr><th>API Component</th><th>Importance</th><th>Action</th></tr>
<tr>
    <td>bladerf_enable_module()</td>
    <td rowspan="27">Required for MIMO support, optional otherwise</td>
    <td rowspan="27">
        Replace `bladerf_module` with \ref bladerf_channel.

        Replace `BLADERF_MODULE_RX` with `BLADERF_CHANNEL_RX(0)`, or
        generally, `BLADERF_CHANNEL_RX(channel_number)`

        Replace `BLADERF_MODULE_TX` with `BLADERF_CHANNEL_TX(0)`, or
        generally, `BLADERF_CHANNEL_TX(channel_number)`
    </td>
</tr>
<tr><td>bladerf_set_gain()</td></tr>
<tr><td>bladerf_set_gain_mode()</td></tr>
<tr><td>bladerf_get_gain_mode()</td></tr>
<tr><td>bladerf_set_sample_rate()</td></tr>
<tr><td>bladerf_set_rational_sample_rate()</td></tr>
<tr><td>bladerf_get_sample_rate()</td></tr>
<tr><td>bladerf_get_rational_sample_rate()</td></tr>
<tr><td>bladerf_set_bandwidth()</td></tr>
<tr><td>bladerf_get_bandwidth()</td></tr>
<tr><td>bladerf_set_lpf_mode()</td></tr>
<tr><td>bladerf_get_lpf_mode()</td></tr>
<tr><td>bladerf_select_band()</td></tr>
<tr><td>bladerf_set_frequency()</td></tr>
<tr><td>bladerf_schedule_retune()</td></tr>
<tr><td>bladerf_cancel_scheduled_retunes()</td></tr>
<tr><td>bladerf_get_frequency()</td></tr>
<tr><td>bladerf_get_quick_tune()</td></tr>
<tr><td>bladerf_trigger_init()</td></tr>
<tr><td>bladerf_set_correction()</td></tr>
<tr><td>bladerf_get_correction()</td></tr>
<tr><td>bladerf_xb200_set_filterbank()</td></tr>
<tr><td>bladerf_xb200_get_filterbank()</td></tr>
<tr><td>bladerf_xb200_set_path()</td></tr>
<tr><td>bladerf_xb200_get_path()</td></tr>
<tr><td>bladerf_read_trigger()</td></tr>
<tr><td>bladerf_write_trigger()</td></tr>
</table>

\see bladerf_get_channel_count() - Get the number of RX or TX channels
     supported by the given device.

\subsection relnotes_2_0_0_api_range bladerf_get_*_range functions replace #define'd constants

The `#define`'d constants for supported minimum/maximum values have been
deprecated and replaced with a set of context-aware functions.

<table>
<caption id="multi_row">Required actions</caption>
<tr><th>API Component</th><th>Importance</th><th>Action</th></tr>
<tr>
    <td>BLADERF_RXVGA1_GAIN_MIN</td>
    <td rowspan="17">Required for complete bladeRF Micro compatibility</td>
    <td rowspan="10">
        Use bladerf_get_gain_stage_range() to retrieve the range of allowable
        gains for a specific gain stage. This should be called after setting
        the frequency with bladerf_set_frequency().
    </td>
</tr>
<tr><td>BLADERF_RXVGA1_GAIN_MAX</td></tr>
<tr><td>BLADERF_RXVGA2_GAIN_MIN</td></tr>
<tr><td>BLADERF_RXVGA2_GAIN_MAX</td></tr>
<tr><td>BLADERF_TXVGA1_GAIN_MIN</td></tr>
<tr><td>BLADERF_TXVGA1_GAIN_MAX</td></tr>
<tr><td>BLADERF_TXVGA2_GAIN_MIN</td></tr>
<tr><td>BLADERF_TXVGA2_GAIN_MAX</td></tr>
<tr><td>BLADERF_LNA_GAIN_MID_DB</td></tr>
<tr><td>BLADERF_LNA_GAIN_MAX_DB</td></tr>
<tr>
    <td>BLADERF_SAMPLERATE_MIN</td>
    <td rowspan="2">
        Use bladerf_get_sample_rate_range() to retrieve the range of allowable
        sample rates for a given channel.
    </td>
</tr>
<tr><td>BLADERF_SAMPLERATE_REC_MAX</td></tr>
<tr>
    <td>BLADERF_BANDWIDTH_MIN</td>
    <td rowspan="2">
        Use bladerf_get_bandwidth_range() to retrieve the supported range of
        bandwidths for a given channel.
    </td>
</tr>
<tr><td>BLADERF_BANDWIDTH_MAX</td></tr>
<tr>
    <td>BLADERF_FREQUENCY_MIN_XB200</td>
    <td rowspan="3">
        Use bladerf_get_frequency_range() to retrieve the supported range of
        frequencies for a given channel.

        \note This will vary depending on the particular hardware configuration
              (such as if a XB-200 is attached).
    </td>
</tr>
<tr><td>BLADERF_FREQUENCY_MIN</td></tr>
<tr><td>BLADERF_FREQUENCY_MAX</td></tr>
</table>

An example use of bladerf_get_frequency_range():

\code{.c}
bool is_frequency_within_range(struct bladerf *dev, bladerf_channel channel, bladerf_frequency frequency)
{
    int status;
    struct bladerf_range range;

    status = bladerf_get_frequency_range(dev, channel, &range);
    if (status < 0) {
        // error case
    }

    return ((frequency / range.scale) >= range.min && (frequency / range.scale) <= range.max);
}
\endcode

\see bladerf_get_gain_stages() - Get a list of available gain stages.
\see bladerf_set_gain() - Set overall system gain.
\see bladerf_get_gain() - Get overall system gain.

\subsection relnotes_2_0_0_api_typedefs New type definitions for parameters

The following types are now defined:

\li ::bladerf_gain (gain value in dB; `int`)
\li ::bladerf_sample_rate (sample rate in samples per second; `unsigned int`)
\li ::bladerf_bandwidth (bandwidth in Hz; `unsigned int`)
\li ::bladerf_frequency (center frequency in Hz; `uint64_t`)
\li ::bladerf_timestamp (timestamp in ticks; `uint64_t`)
\li ::bladerf_correction_value (correction value in arbitrary units; `int16_t`)

With the exception of ::bladerf_frequency, none of the underlying types changed
from libbladeRF 1.x.x and no changes are strictly necessary. However, the
declarations changed for the following functions:

\li bladerf_set_gain()
\li bladerf_get_gain()
\li bladerf_set_gain_stage()
\li bladerf_get_gain_stage()
\li bladerf_set_sample_rate()
\li bladerf_get_sample_rate()
\li bladerf_set_bandwidth()
\li bladerf_get_bandwidth()
\li bladerf_select_band()
\li bladerf_set_frequency()
\li bladerf_get_frequency()
\li bladerf_schedule_retune()
\li bladerf_set_correction()
\li bladerf_get_correction()
\li bladerf_get_timestamp()

As well as:

\li struct bladerf_metadata

\section relnotes_2_0_0_feats New features

\subsection relnotes_2_0_0_feats_platform Multiple platform support

We reorganized libbladeRF to easily support multiple hardware platforms.  You
will find a new directory tree, `host/libraries/libbladeRF/src/board/`,
containing subdirectories for each supported platform (currently `bladerf1/` for
the LMS6002D-based bladeRF family, and `bladerf2/` for the AD9361-based bladeRF
Micro family).

Likewise, product-specific API calls have been moved into two new header files:
bladeRF1.h and bladeRF2.h. Functions which apply to all boards remain in
libbladeRF.h.

\see Refer to bladeRF1.h and bladeRF2.h for a list of affected functions.

\note Using API calls specified in bladeRF1.h or bladeRF2.h is not recommended
      for most use cases. They are provided for backwards compatibility and
      low-level hardware control, and are subject to change.

We also rearranged a number of source files into subdirectories of
`host/libraries/libbladeRF/src/`. In addition to the pre-existing `backend/`,
you'll also find `board/` (product-specific code), `driver/` (device drivers),
`expansion/` (expansion board drivers), `helpers/` (helpful utility functions),
and `streaming/` (sample streaming code).

\subsection relnotes_2_0_0_feats_gc Gain control improvements

The original manual gain control functionality in libbladeRF is very low-level
and hardware-specific, and requires significant knowledge of the underlying
RF module to adjust. As such, new gain control methods have been introduced
to the API, and the following functions are now deprecated:

\li bladerf_set_lna_gain() and bladerf_get_lna_gain()
\li bladerf_set_rxvga1() and bladerf_get_rxvga1()
\li bladerf_set_rxvga2() and bladerf_get_rxvga2()
\li bladerf_set_txvga1() and bladerf_get_txvga1()
\li bladerf_set_txvga2() and bladerf_get_txvga2()

Instead, applications should use one of the following approaches:

\subsubsection relnotes_2_0_0_feats_gc_agc Automatic Gain Control (AGC)

Automatic gain control is available for RX channels, starting with
<a class="el" href="https://github.com/Nuand/bladeRF/releases/tag/libbladeRF_v1.9.0">libbladeRF v1.9.0</a>
and
<a class="el" href="https://github.com/Nuand/bladeRF/releases/tag/fpga_v0.7.0">FPGA v0.7.0</a>.
AGC continually adjusts the system's gain to ensure the received signal has a
high dynamic range, while avoiding clipping.

\li bladerf_get_gain_modes() reports the available gain modes on a channel
\li bladerf_get_gain_mode() reports the current gain mode for a channel
\li bladerf_set_gain_mode() sets the gain mode for a channel

As of this writing, the available gain modes are:

\li bladeRF: \b ::BLADERF_GAIN_AUTOMATIC (default), ::BLADERF_GAIN_MANUAL
\li bladeRF Micro: ::BLADERF_GAIN_MGC, ::BLADERF_GAIN_FASTATTACK_AGC,
                   \b ::BLADERF_GAIN_SLOWATTACK_AGC (default),
                   ::BLADERF_GAIN_HYBRID_AGC

\note bladerf_get_gain_mode() and bladerf_set_gain_mode() will return
      ::BLADERF_ERR_UNSUPPORTED for TX channels.

\code{.c}
void agc_example(struct bladerf *dev, bladerf_channel channel)
{
    int i, status;
    const struct bladerf_gain_modes *modes = NULL;
    bladerf_gain_mode mode;

    // What gain modes are available?
    status = bladerf_get_gain_modes(dev, channel, &modes);
    if (status < 0) {
        // error case
    }

    for (i = 0; i < status; ++i) {
        printf("enum %d is gain mode %s\n", modes[i]->mode, modes[i]->name);
    }

    // Get current gain mode
    status = bladerf_get_gain_mode(dev, channel, &mode);
    if (status < 0) {
        // error case
    }

    printf("current gain mode: %d\n", mode);

    // Enable AGC
    mode = BLADERF_GAIN_AUTOMATIC;
    status = bladerf_set_gain_mode(dev, channel, mode);
    if (status < 0) {
        // error case
    }
}
\endcode

\subsubsection relnotes_2_0_0_feats_gc_auto System gain proportioning

In previous versions, setting the gain required careful proportioning of gain
between LNAs and VGAs. To reduce the implementation burden, an overall gain may
now be specified, and the RFIC's gain stages will be set appropriately.

\li bladerf_get_gain_range() reports the allowable values for a channel's gain
\li bladerf_get_gain() reports the current overall gain for a channel
\li bladerf_set_gain() sets the overall gain for a channel

The gain scales are defined such that a 60 dB gain on a TX channel is
\em approximately 0 dBm CW output, and a 60 dB gain on a RX channel is the
maximum available amplification.

\note bladerf_set_gain() may be unavailable or may not operate as expected if
      \ref relnotes_2_0_0_feats_gc_agc is enabled, or if the channel
      is not currently enabled.

\note The range returned by bladerf_get_gain_range() may vary depending on the
      selected center frequency.

\code{.c}
void gain_example(struct bladerf *dev, bladerf_channel channel, int gain)
{
    int old_gain, status;
    const struct bladerf_range *range = NULL;

    // What is the valid range?
    status = bladerf_get_gain_range(dev, channel, &range);
    if (status < 0) {
        // error case
    }

    // What is the current gain?
    status = bladerf_get_gain(dev, channel, &old_gain);
    if (status < 0) {
        // error case
    };

    printf("Channel %d current gain: %4d dB (Range: [%g, %g])\n",
           channel, old_gain, range->min * range->scale, range->max * range->scale);

    // Set the new gain value
    status = bladerf_set_gain(dev, channel, gain);
    if (status < 0) {
        // error case
    };
}

...

gain_example(dev, BLADERF_CHANNEL_TX(0), 60);  // set 60 dB TX gain (~ 0 dBm)
gain_example(dev, BLADERF_CHANNEL_RX(0), 60);  // set 60 dB RX gain (max)
\endcode

\subsubsection relnotes_2_0_0_feats_gc_manual Individual gain stage control

Advanced implementations that need to directly configure the gain stages may
use the following family of functions:

\li bladerf_get_gain_stages() reports the gain stages on a given channel
\li bladerf_get_gain_stage_range() reports the range of allowable values for a
    given gain stage
\li bladerf_get_gain_stage() reports the current value for a gain stage
\li bladerf_set_gain_stage() sets the gain for a given gain stage

\note The values set here will be reflected in bladerf_get_gain(), but using
      bladerf_set_gain() will override any individual gain stage settings on
      a particular channel.

\note bladerf_set_gain_stage() may be unavailable or may not operate as
      expected if \ref relnotes_2_0_0_feats_gc_agc is enabled, or if
      the channel is not currently enabled.

\note The range returned by bladerf_get_gain_stage_range() may vary depending
      on the selected center frequency.

\subsection relnotes_2_0_0_feats_mimo MIMO

\subsection relnotes_2_0_0_feats_python Python bindings

*/
