Skip to content

Commit

Permalink
libbladeRF: Moved system gain functions, deadlock fix
Browse files Browse the repository at this point in the history
Moved system gain functions from bladerf_priv.c to gain.c as part of
the cleanup efforts for issue #190.

In doing so, a stray MUTEX_LOCK() (without a matching MUTEX_UNLOCK) was
removed, which caused deadlocks.
  • Loading branch information
jynik committed Aug 3, 2014
1 parent 9297161 commit 294566d
Show file tree
Hide file tree
Showing 6 changed files with 170 additions and 109 deletions.
1 change: 1 addition & 0 deletions host/libraries/libbladeRF/CMakeLists.txt
Expand Up @@ -204,6 +204,7 @@ set(LIBBLADERF_SOURCE
src/dc_cal_table.c
src/file_ops.c
src/fpga.c
src/gain.c
src/lms.c
src/si5338.c
src/xb.c
Expand Down
3 changes: 2 additions & 1 deletion host/libraries/libbladeRF/src/bladerf.c
Expand Up @@ -29,6 +29,7 @@
#include "async.h"
#include "sync.h"
#include "tuning.h"
#include "gain.h"
#include "lms.h"
#include "xb.h"
#include "si5338.h"
Expand Down Expand Up @@ -537,7 +538,7 @@ int bladerf_set_gain(struct bladerf *dev, bladerf_module mod, int gain) {
int status;
MUTEX_LOCK(&dev->ctrl_lock);

status = set_gain(dev, mod, gain);
status = gain_set(dev, mod, gain);

MUTEX_UNLOCK(&dev->ctrl_lock);
return status;
Expand Down
99 changes: 0 additions & 99 deletions host/libraries/libbladeRF/src/bladerf_priv.c
Expand Up @@ -233,102 +233,3 @@ int load_calibration_table(struct bladerf *dev, const char *filename)
bladerf_free_image(image);
return status;
}

static inline int set_rx_gain_combo(struct bladerf *dev,
bladerf_lna_gain lnagain,
int rxvga1, int rxvga2)
{
int status;
status = lms_lna_set_gain(dev, lnagain);
if (status < 0) {
return status;
}

status = lms_rxvga1_set_gain(dev, rxvga1);
if (status < 0) {
return status;
}

return lms_rxvga2_set_gain(dev, rxvga2);
}

static int set_rx_gain(struct bladerf *dev, int gain)
{
if (gain <= BLADERF_LNA_GAIN_MID_DB) {
return set_rx_gain_combo(dev,
BLADERF_LNA_GAIN_BYPASS,
BLADERF_RXVGA1_GAIN_MIN,
BLADERF_RXVGA2_GAIN_MIN);
} else if (gain <= BLADERF_LNA_GAIN_MID_DB + BLADERF_RXVGA1_GAIN_MIN) {
return set_rx_gain_combo(dev,
BLADERF_LNA_GAIN_MID_DB,
BLADERF_RXVGA1_GAIN_MIN,
BLADERF_RXVGA2_GAIN_MIN);
} else if (gain <= (BLADERF_LNA_GAIN_MAX_DB + BLADERF_RXVGA1_GAIN_MAX)) {
return set_rx_gain_combo(dev,
BLADERF_LNA_GAIN_MID,
gain - BLADERF_LNA_GAIN_MID_DB,
BLADERF_RXVGA2_GAIN_MIN);
} else if (gain < (BLADERF_LNA_GAIN_MAX_DB + BLADERF_RXVGA1_GAIN_MAX + BLADERF_RXVGA2_GAIN_MAX)) {
return set_rx_gain_combo(dev,
BLADERF_LNA_GAIN_MAX,
BLADERF_RXVGA1_GAIN_MAX,
gain - (BLADERF_LNA_GAIN_MAX_DB + BLADERF_RXVGA1_GAIN_MAX));
} else {
return set_rx_gain_combo(dev,
BLADERF_LNA_GAIN_MAX,
BLADERF_RXVGA1_GAIN_MAX,
BLADERF_RXVGA2_GAIN_MAX);
}
}

static inline int set_tx_gain_combo(struct bladerf *dev, int txvga1, int txvga2)
{
int status;

status = lms_txvga1_set_gain(dev, txvga1);
if (status == 0) {
status = lms_txvga2_set_gain(dev, txvga2);
}

return status;
}

static int set_tx_gain(struct bladerf *dev, int gain)
{
int status;
MUTEX_LOCK(&dev->ctrl_lock);

if (gain < 0) {
gain = 0;
}

if (gain <= BLADERF_TXVGA2_GAIN_MAX) {
status = set_tx_gain_combo(dev, BLADERF_TXVGA1_GAIN_MIN, gain);
} else if (gain <= ((BLADERF_TXVGA1_GAIN_MAX - BLADERF_TXVGA1_GAIN_MIN) + BLADERF_TXVGA2_GAIN_MAX)) {
status = set_tx_gain_combo(dev,
BLADERF_TXVGA1_GAIN_MIN + gain - BLADERF_TXVGA2_GAIN_MAX,
BLADERF_TXVGA2_GAIN_MAX);
} else {
status =set_tx_gain_combo(dev,
BLADERF_TXVGA1_GAIN_MAX,
BLADERF_TXVGA2_GAIN_MAX);
}

return status;
}

int set_gain(struct bladerf *dev, bladerf_module module, int gain)
{
int status;

if (module == BLADERF_MODULE_TX) {
status = set_tx_gain(dev, gain);
} else if (module == BLADERF_MODULE_RX) {
status = set_rx_gain(dev, gain);
} else {
status = BLADERF_ERR_INVAL;
}

return status;
}
9 changes: 0 additions & 9 deletions host/libraries/libbladeRF/src/bladerf_priv.h
Expand Up @@ -172,13 +172,4 @@ int populate_abs_timeout(struct timespec *t_abs, unsigned int timeout_ms);
*/
int load_calibration_table(struct bladerf *dev, const char *filename);

/**
* Set system gain for the specified module
*
* @param dev Device handle
* @param module Module to configure
* @param gain Desired gain
*/
int set_gain(struct bladerf *dev, bladerf_module module, int gain);

#endif
124 changes: 124 additions & 0 deletions host/libraries/libbladeRF/src/gain.c
@@ -0,0 +1,124 @@
/*
* This file is part of the bladeRF project:
* http://www.github.com/nuand/bladeRF
*
* Copyright (C) 2014 Nuand LLC
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
*/

#include "gain.h"
#include "lms.h"

static inline int set_rx_gain_combo(struct bladerf *dev,
bladerf_lna_gain lnagain,
int rxvga1, int rxvga2)
{
int status;
status = lms_lna_set_gain(dev, lnagain);
if (status < 0) {
return status;
}

status = lms_rxvga1_set_gain(dev, rxvga1);
if (status < 0) {
return status;
}

return lms_rxvga2_set_gain(dev, rxvga2);
}

static int set_rx_gain(struct bladerf *dev, int gain)
{
if (gain <= BLADERF_LNA_GAIN_MID_DB) {
return set_rx_gain_combo(dev,
BLADERF_LNA_GAIN_BYPASS,
BLADERF_RXVGA1_GAIN_MIN,
BLADERF_RXVGA2_GAIN_MIN);
} else if (gain <= BLADERF_LNA_GAIN_MID_DB + BLADERF_RXVGA1_GAIN_MIN) {
return set_rx_gain_combo(dev,
BLADERF_LNA_GAIN_MID_DB,
BLADERF_RXVGA1_GAIN_MIN,
BLADERF_RXVGA2_GAIN_MIN);
} else if (gain <= (BLADERF_LNA_GAIN_MAX_DB + BLADERF_RXVGA1_GAIN_MAX)) {
return set_rx_gain_combo(dev,
BLADERF_LNA_GAIN_MID,
gain - BLADERF_LNA_GAIN_MID_DB,
BLADERF_RXVGA2_GAIN_MIN);
} else if (gain < (BLADERF_LNA_GAIN_MAX_DB + BLADERF_RXVGA1_GAIN_MAX + BLADERF_RXVGA2_GAIN_MAX)) {
return set_rx_gain_combo(dev,
BLADERF_LNA_GAIN_MAX,
BLADERF_RXVGA1_GAIN_MAX,
gain - (BLADERF_LNA_GAIN_MAX_DB + BLADERF_RXVGA1_GAIN_MAX));
} else {
return set_rx_gain_combo(dev,
BLADERF_LNA_GAIN_MAX,
BLADERF_RXVGA1_GAIN_MAX,
BLADERF_RXVGA2_GAIN_MAX);
}
}

static inline int set_tx_gain_combo(struct bladerf *dev, int txvga1, int txvga2)
{
int status;

status = lms_txvga1_set_gain(dev, txvga1);
if (status == 0) {
status = lms_txvga2_set_gain(dev, txvga2);
}

return status;
}

static int set_tx_gain(struct bladerf *dev, int gain)
{
int status;
const int max_gain =
(BLADERF_TXVGA1_GAIN_MAX - BLADERF_TXVGA1_GAIN_MIN)
+ BLADERF_TXVGA2_GAIN_MAX;

if (gain < 0) {
gain = 0;
}

if (gain <= BLADERF_TXVGA2_GAIN_MAX) {
status = set_tx_gain_combo(dev, BLADERF_TXVGA1_GAIN_MIN, gain);
} else if (gain <= max_gain) {
status = set_tx_gain_combo(dev,
BLADERF_TXVGA1_GAIN_MIN + gain - BLADERF_TXVGA2_GAIN_MAX,
BLADERF_TXVGA2_GAIN_MAX);
} else {
status = set_tx_gain_combo(dev,
BLADERF_TXVGA1_GAIN_MAX,
BLADERF_TXVGA2_GAIN_MAX);
}

return status;
}

int gain_set(struct bladerf *dev, bladerf_module module, int gain)
{
int status;

if (module == BLADERF_MODULE_TX) {
status = set_tx_gain(dev, gain);
} else if (module == BLADERF_MODULE_RX) {
status = set_rx_gain(dev, gain);
} else {
status = BLADERF_ERR_INVAL;
}

return status;
}

43 changes: 43 additions & 0 deletions host/libraries/libbladeRF/src/gain.h
@@ -0,0 +1,43 @@
/**
* @file gain.h
*
* @brief Higher level system gain functions
*
* This file is part of the bladeRF project:
* http://www.github.com/nuand/bladeRF
*
* Copyright (C) 2014 Nuand LLC
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef BLADERF_GAIN_H_
#define BLADERF_GAIN_H_

#include "libbladeRF.h"

/**
* Set system gain for the specified module
*
* @param dev Device handle
* @param module Module to configure
* @param gain Desired gain
*
* @return 0 on success, BLADERF_ERR_* value on failure
*/
int gain_set(struct bladerf *dev, bladerf_module module, int gain);

/* TODO gain_get() */

#endif

0 comments on commit 294566d

Please sign in to comment.