From 3673ffd0921a3b6bf2cc9985ead0e337c001baf3 Mon Sep 17 00:00:00 2001
From: Josh Blum <josh@joshknows.com>
Date: Fri, 5 Oct 2012 12:15:37 -0700
Subject: usrp: ensure that actual_scalar does not rollover

For certain decimations/interpolations,
the scale factor adjustment may be greater than 1.0.
The > 1.0 factor needs to be adjusted out in the host.
---
 host/lib/usrp/cores/rx_dsp_core_200.cpp | 5 +++--
 host/lib/usrp/cores/tx_dsp_core_200.cpp | 5 +++--
 2 files changed, 6 insertions(+), 4 deletions(-)

diff --git a/host/lib/usrp/cores/rx_dsp_core_200.cpp b/host/lib/usrp/cores/rx_dsp_core_200.cpp
index a9b7d8672..b73baa81e 100644
--- a/host/lib/usrp/cores/rx_dsp_core_200.cpp
+++ b/host/lib/usrp/cores/rx_dsp_core_200.cpp
@@ -184,9 +184,10 @@ public:
     }
 
     void update_scalar(void){
-        const double target_scalar = (1 << 17)*_scaling_adjustment/_dsp_extra_scaling;
+        const double factor = 1.0 + std::max(ceil_log2(_scaling_adjustment), 0.0);
+        const double target_scalar = (1 << 17)*_scaling_adjustment/_dsp_extra_scaling/factor;
         const boost::int32_t actual_scalar = boost::math::iround(target_scalar);
-        _fxpt_scalar_correction = target_scalar/actual_scalar; //should be small
+        _fxpt_scalar_correction = target_scalar/actual_scalar*factor; //should be small
         _iface->poke32(REG_DSP_RX_SCALE_IQ, actual_scalar);
     }
 
diff --git a/host/lib/usrp/cores/tx_dsp_core_200.cpp b/host/lib/usrp/cores/tx_dsp_core_200.cpp
index 2faf7c28b..f905a7551 100644
--- a/host/lib/usrp/cores/tx_dsp_core_200.cpp
+++ b/host/lib/usrp/cores/tx_dsp_core_200.cpp
@@ -136,9 +136,10 @@ public:
     }
 
     void update_scalar(void){
-        const double target_scalar = (1 << 17)*_scaling_adjustment/_dsp_extra_scaling;
+        const double factor = 1.0 + std::max(ceil_log2(_scaling_adjustment), 0.0);
+        const double target_scalar = (1 << 17)*_scaling_adjustment/_dsp_extra_scaling/factor;
         const boost::int32_t actual_scalar = boost::math::iround(target_scalar);
-        _fxpt_scalar_correction = target_scalar/actual_scalar; //should be small
+        _fxpt_scalar_correction = target_scalar/actual_scalar*factor; //should be small
         _iface->poke32(REG_DSP_TX_SCALE_IQ, actual_scalar);
     }
 
-- 
cgit v1.2.3