Skip to content

Commit

Permalink
libbladeRF: Introduced timestamp metadata support for sync data i/f
Browse files Browse the repository at this point in the history
API support for timestamp metadata has been introduced. This is made
available when using the newly introduced BLADERF_FORMAT_SC16_Q11_META
format value.

When using the synchronous interface, metadata is exchanged between the
caller and the API via the updated bladerf_metadata structure. Users of
the asynchronous interface must currently manually manage the metadata
headers as desired, as documented in libbladeRF.h.

When using the BLADERF_FORMAT_SC16_Q11_META format in conjunction with
the synchronous interface, it is possible to retrieve the timestamp for
received samples and an indication of overrun.  An RX operation may also
be scheduled for at a specific timestamp value the future.  Similarly,
bursts of samples can be scheduled to be transmitted at a specific
timestamp value, or at the first available timestamp ("now").
  • Loading branch information
jynik committed Oct 21, 2014
1 parent 5774aa0 commit fbe0b6a
Show file tree
Hide file tree
Showing 27 changed files with 5,388 additions and 105 deletions.
173 changes: 146 additions & 27 deletions host/libraries/libbladeRF/include/libbladeRF.h
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ extern "C" {
#define BLADERF_ERR_NO_FILE (-11) /**< File not found */
#define BLADERF_ERR_UPDATE_FPGA (-12) /**< An FPGA update is required */
#define BLADERF_ERR_UPDATE_FW (-13) /**< A firmware update is requied */
#define BLADERF_ERR_TIME_PAST (-14) /**< Requested timestamp is in the past */

/** @} (End RETCODES) */

Expand Down Expand Up @@ -1174,57 +1175,123 @@ typedef enum {
* large.
*/
BLADERF_FORMAT_SC16_Q11,

/**
* This format is the same as the BLADERF_FORMAT_SC16_Q11 format, except the
* first 4 samples (16 bytes) in every block of 1024 samples are replaced
* with metadata, organized as follows, with all fields being little endian
* byte order:
*
* <pre>
* 0x00 [uint32_t: Reserved]
* 0x04 [uint64_t: 64-bit Timestamp]
* 0x0c [uint32_t: BLADERF_META_FLAG_* flags]
* </pre>
*
* When using the bladerf_sync_rx() and bladerf_sync_tx() functions,
* this detail is transparent to caller. These functions take care of
* packing/unpacking the metadata into/from the data, via the
* bladerf_metadata structure.
*
* Currently, when using the asynchronous data transfer interface, the user
* is responsible for manually packing/unpacking this metadata into/from
* their sample data.
*/
BLADERF_FORMAT_SC16_Q11_META,
} bladerf_format;

/*
* Metadata status bits
*
* These are used in conjunction with the bladerf_metadata structure's
* `status` field.
*/

/**
* The host-side data stream encountered an overrun failure
*/
#define BLADERF_META_STATUS_SW_OVERRUN (1 << 0)

/**
* The host-side data stream encountered an underrun failure
*/
#define BLADERF_META_STATUS_SW_UNDERRUN (1 << 1)

/**
* An overrun failure occurred in the FPGA
* A sample overrun has occurred. This indicates that either the host
* (more likely) or the FPGA is not keeping up with the incoming samples
*/
#define BLADERF_META_STATUS_HW_OVERRUN (1 << 8)
#define BLADERF_META_STATUS_OVERRUN (1 << 0)

/**
* An underrrun failure occurred in the FPGA
* A sample underrun has occurred. This generally only occurrs on the TX module
* when the FPGA is starved of samples.
*
* @note libbladeRF does not report this status. It is here for future use.
*/
#define BLADERF_META_STATUS_HW_UNDERRUN (1 << 9)
#define BLADERF_META_STATUS_UNDERRUN (1 << 1)



/*
* Metadata flags
*
* These are used in conjunction with the bladerf_metadata structure's
* `flags` field.
*/

/**
* Mark the associated buffer as the start of a burst transmission.
* This is only used for the bladerf_sync_tx() call.
*/
#define BLADERF_META_FLAG_TX_BURST_START (1 << 0)

/**
* Mark the associated buffer as the start of a burst transfer
* Mark the associated buffer as the end of a burst transmission. This will
* flush the remainder of the sync interfaces' current working buffer and
* enqueue samples into the transmit FIFO.
*
* When specifying this flag to bladerf_sync_tx(), the final two samples
* in the synchronous interface's internal working buffer <b>must</b> be zero.
* Unexpected results may occur if this is not the case. To ensure this
* requirement is met, API users should ensure the last two samples provided to
* bladerf_sync_tx() are zero when using ::BLADERF_META_FLAG_TX_BURST_END. One
* way to do this is to end bursts with a call of bladerf_sync_tx() with this
* flag set and a buffer of 2 or more zero samples.
*
* Flushing the sync interface's working buffer implies that after specifying
* this flag, the next timestamp that can be transmitted is the current
* timestamp plus the duration of the burst that this flag is ending <b>and</b>
* the remaining length of the remaining buffer that is flushed. (The buffer
* size, in this case, is the `buffer_size` value passed to the previous
* bladerf_sync_config() call.)
*
* Rather than attempting to keep track of the number of samples sent with
* respect to buffer sizes, it is easiest to always assume 1 buffer's worth of
* time is required between bursts. In this case "buffer" refers to the
* `buffer_size` parameter provided to bladerf_sync_config().) If this is too
* much time, consider combining multiple bursts and manually zero-padding
* samples between them.
*
* This is only used for the bladerf_sync_tx() call. It is ignored by the
* bladerf_sync_rx() call.
*
*/
#define BLADERF_META_FLAG_BURST_START (1 << 0)
#define BLADERF_META_FLAG_TX_BURST_END (1 << 1)

/**
* Mark the associated buffer as the end of a burst transfer
* Use this flag in conjunction with ::BLADERF_META_FLAG_TX_BURST_START to
* indicate that the burst should be transmitted as soon as possible, as opposed
* to waiting for a specific timestamp.
*
* When this flag is used, there is no need to set the
* bladerf_metadata::timestamp field.
*/
#define BLADERF_META_FLAG_BURST_END (1 << 1)
#define BLADERF_META_FLAG_TX_NOW (1 << 2)

/**
* This flag indicates that calls to bladerf_sync_rx should return any available
* samples, rather than wait until the timestamp indicated in the
* bladerf_metadata timestamp field.
*/
#define BLADERF_META_FLAG_RX_NOW (1 << 31)

/**
* Sample metadata
*
* @bug Metadata support is not yet implemented. API users should not attempt
* to read or write to metadata structures.
*
* The size of this structure may change when metadata support is
* completed, which may affect binary compatibility of library versions.
* This structure is used in conjunction with the BLADERF_FORMAT_SC16_Q11_META
* format to TX scheduled bursts or retrieve timestamp information about
* received samples.
*/
struct bladerf_metadata {

Expand All @@ -1238,17 +1305,43 @@ struct bladerf_metadata {
* structure is passed to. API calls read this field from the provided
* data structure, and do not modify it.
*
* See the BLADERF_META_FLAG_* values for available options.
* Valid flags include
* ::BLADERF_META_FLAG_TX_BURST_START, ::BLADERF_META_FLAG_TX_BURST_END,
* ::BLADERF_META_FLAG_TX_NOW, and ::BLADERF_META_FLAG_RX_NOW
*
*/
uint32_t flags;

/**
* Output bit field to denoting the status of transmissions/receptions. API
* calls will write this field.
*
* See the BLADERF_META_STATUS_* values for possible status items.
* Possible status flags include ::BLADERF_META_STATUS_OVERRUN and
* ::BLADERF_META_STATUS_UNDERRUN;
*
*/
uint32_t status;

/**
* This output parameter is updated to reflect the actual number of
* contiguous samples that have been populated in an RX buffer during
* a bladerf_sync_rx() call.
*
* This will not be equal to the requested count in the event of a
* discontinuity (i.e., when the status field has the
* ::BLADERF_META_STATUS_OVERRUN flag set). When an overrun occurs, it is
* important not to read past the number of samples specified by this
* value, as the remaining contents of the buffer are undefined.
*
* This parameter is not currently used by bladerf_sync_tx().
*/
unsigned int actual_count;

/**
* Reserved for future use. This is not used by any functions.
* It is recommended that users zero out this field.
*/
uint8_t reserved[32];
};


Expand Down Expand Up @@ -1672,9 +1765,16 @@ int CALL_CONV bladerf_sync_config(struct bladerf *dev,
* parameter passed to bladerf_sync_config().
*
* @param[in] dev Device handle
*
* @param[in] samples Array of samples
*
* @param[in] num_samples Number of samples to write
* @param[in] metadata Sample metadata. (Currently not used.)
*
* @param[in] metadata Sample metadata. This must be provided when using
* the BLADERF_FORMAT_SC16_Q11_META format, but may
* be NULL when the interface is configured for
* the BLADERF_FORMAT_SC16_Q11 format.
*
* @param[in] timeout_ms Timeout (milliseconds) for this call to complete.
* Zero implies "infinite."
*
Expand Down Expand Up @@ -1713,7 +1813,10 @@ int CALL_CONV bladerf_sync_tx(struct bladerf *dev,
*
* @param[in] num_samples Number of samples to read
*
* @param[out] metadata Sample metadata. Currently not used. Pass NULL.
* @param[out] metadata Sample metadata. This must be provided when using
* the BLADERF_FORMAT_SC16_Q11_META format, but may
* be NULL when the interface is configured for
* the BLADERF_FORMAT_SC16_Q11 format.
*
* @param[in] timeout_ms Timeout (milliseconds) for this call to complete.
* Zero implies "infinite."
Expand Down Expand Up @@ -2401,6 +2504,22 @@ int CALL_CONV bladerf_lms_get_dc_cals(struct bladerf *dev,
*/
#define BLADERF_GPIO_FEATURE_SMALL_DMA_XFER (1 << 7)

/**
* Enable-bit for timestamp counter in the FPGA
*/
#define BLADERF_GPIO_TIMESTAMP (1 << 16)

/**
* Timestamp 2x divider control
*
* By default (value = 0), the sample counter is incremented with I and Q,
* yielding two counts per sample.
*
* Set this bit to 1 to enable a 2x timestamp divider, effectively
* achieving 1 timestamp count per sample.
* */
#define BLADERF_GPIO_TIMESTAMP_DIV2 (1 << 17)

/**
* Read a configuration GPIO register
*
Expand Down
3 changes: 3 additions & 0 deletions host/libraries/libbladeRF/src/async.c
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ int async_init_stream(struct bladerf_stream **stream,

switch(format) {
case BLADERF_FORMAT_SC16_Q11:
case BLADERF_FORMAT_SC16_Q11_META:
buffer_size_bytes = sc16q11_to_bytes(samples_per_buffer);
break;

Expand Down Expand Up @@ -183,6 +184,8 @@ int async_submit_stream_buffer(struct bladerf_stream *stream,

if (status == ETIMEDOUT) {
status = BLADERF_ERR_TIMEOUT;
log_debug("%s: %u ms timeout expired",
__FUNCTION__, timeout_ms);
goto error;
} else if (status != 0) {
status = BLADERF_ERR_UNEXPECTED;
Expand Down
2 changes: 2 additions & 0 deletions host/libraries/libbladeRF/src/backend/usb/libusb.c
Original file line number Diff line number Diff line change
Expand Up @@ -1013,6 +1013,8 @@ int lusb_submit_stream_buffer(void *driver, struct bladerf_stream *stream,
}

if (status == ETIMEDOUT) {
log_debug("%s: Timed out waiting for a transfer to become availble.\n",
__FUNCTION__);
return BLADERF_ERR_TIMEOUT;
} else if (status != 0) {
return BLADERF_ERR_UNEXPECTED;
Expand Down
4 changes: 4 additions & 0 deletions host/libraries/libbladeRF/src/backend/usb/usb.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,10 @@
# define BULK_TIMEOUT_MS 1000
#endif

/* Size of a host<->FPGA message in BYTES */
#define USB_MSG_SIZE_SS 2048
#define USB_MSG_SIZE_HS 1024

typedef enum {
USB_TARGET_DEVICE,
USB_TARGET_INTERFACE,
Expand Down
Loading

3 comments on commit fbe0b6a

@mambrus
Copy link
Contributor

@mambrus mambrus commented on fbe0b6a Nov 3, 2014

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This commit breaks YateBTS transceiver.

Here's a patch (also shared with the good folks at #yate) to fix the problem: http://pastebin.com/G1Y32Z9a

@habibur333
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi mambrus
when i use patch ( http://pastebin.com/G1Y32Z9a) by this command
sudo patch < G1Y32Z9a.txt
the output of the terminal is

(Stripping trailing CRs from patch; use --binary to disable.)
patching file bladeRFDevice.cpp
patch unexpectedly ends in middle of line
Hunk #3 succeeded at 185 with fuzz 1.

i don,t known how to solve this issu.Please help me abut this issue. Thanks

@mambrus
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi,
How did you download the patch? The patch command is not the most self explanatory tool and it's hard to say what the reason is without more details. But to begin with however, make sure to use the raw unformatted patch from here: http://pastebin.com/raw.php?i=G1Y32Z9a Also, look in the manage for the patch command regarding -p flag.

If that doesn't help, it might be that the patch doesn't fit anymore, in which case I need to take a closer look.

Please sign in to comment.