diff options
Diffstat (limited to 'host/lib')
-rw-r--r-- | host/lib/transport/convert_types_impl.hpp | 95 | ||||
-rw-r--r-- | host/lib/usrp/dboard/db_basic_and_lf.cpp | 8 | ||||
-rw-r--r-- | host/lib/usrp/simple_usrp.cpp | 8 | ||||
-rw-r--r-- | host/lib/usrp/usrp2/dboard_iface.cpp | 20 |
4 files changed, 120 insertions, 11 deletions
diff --git a/host/lib/transport/convert_types_impl.hpp b/host/lib/transport/convert_types_impl.hpp index 5958b08cb..fdc859883 100644 --- a/host/lib/transport/convert_types_impl.hpp +++ b/host/lib/transport/convert_types_impl.hpp @@ -28,6 +28,10 @@ #define USE_EMMINTRIN_H //use sse2 intrinsics #endif +#if defined(USE_EMMINTRIN_H) + #include <emmintrin.h> +#endif + /*********************************************************************** * Typedefs **********************************************************************/ @@ -72,7 +76,7 @@ static UHD_INLINE void item32_to_sc16_bswap( } /*********************************************************************** - * Convert complex float buffer to items32 + * Convert complex float buffer to items32 (no swap) **********************************************************************/ static const float shorts_per_float = float(32767); @@ -82,6 +86,41 @@ static UHD_INLINE item32_t fc32_to_item32(fc32_t num){ return (item32_t(real) << 16) | (item32_t(imag) << 0); } +//////////////////////////////////// +// none-swap +//////////////////////////////////// +#if defined(USE_EMMINTRIN_H) +static UHD_INLINE void fc32_to_item32_nswap( + const fc32_t *input, item32_t *output, size_t nsamps +){ + __m128 scalar = _mm_set_ps1(shorts_per_float); + + //convert blocks of samples with intrinsics + size_t i = 0; for (; i < (nsamps & ~0x3); i+=4){ + //load from input + __m128 tmplo = _mm_loadu_ps(reinterpret_cast<const float *>(input+i+0)); + __m128 tmphi = _mm_loadu_ps(reinterpret_cast<const float *>(input+i+2)); + + //convert and scale + __m128i tmpilo = _mm_cvtps_epi32(_mm_mul_ps(tmplo, scalar)); + __m128i tmpihi = _mm_cvtps_epi32(_mm_mul_ps(tmphi, scalar)); + + //pack + swap 16-bit pairs + __m128i tmpi = _mm_packs_epi32(tmpilo, tmpihi); + tmpi = _mm_shufflelo_epi16(tmpi, _MM_SHUFFLE(2, 3, 0, 1)); + tmpi = _mm_shufflehi_epi16(tmpi, _MM_SHUFFLE(2, 3, 0, 1)); + + //store to output + _mm_storeu_si128(reinterpret_cast<__m128i *>(output+i), tmpi); + } + + //convert remainder + for (; i < nsamps; i++){ + output[i] = fc32_to_item32(input[i]); + } +} + +#else static UHD_INLINE void fc32_to_item32_nswap( const fc32_t *input, item32_t *output, size_t nsamps ){ @@ -90,9 +129,12 @@ static UHD_INLINE void fc32_to_item32_nswap( } } -#if defined(USE_EMMINTRIN_H) -#include <emmintrin.h> +#endif +//////////////////////////////////// +// byte-swap +//////////////////////////////////// +#if defined(USE_EMMINTRIN_H) static UHD_INLINE void fc32_to_item32_bswap( const fc32_t *input, item32_t *output, size_t nsamps ){ @@ -108,7 +150,7 @@ static UHD_INLINE void fc32_to_item32_bswap( __m128i tmpilo = _mm_cvtps_epi32(_mm_mul_ps(tmplo, scalar)); __m128i tmpihi = _mm_cvtps_epi32(_mm_mul_ps(tmphi, scalar)); - //pack + byteswap -> byteswap 32 bit words + //pack + byteswap -> byteswap 16 bit words __m128i tmpi = _mm_packs_epi32(tmpilo, tmpihi); tmpi = _mm_or_si128(_mm_srli_epi16(tmpi, 8), _mm_slli_epi16(tmpi, 8)); @@ -145,6 +187,43 @@ static UHD_INLINE fc32_t item32_to_fc32(item32_t item){ ); } +//////////////////////////////////// +// none-swap +//////////////////////////////////// +#if defined(USE_EMMINTRIN_H) +static UHD_INLINE void item32_to_fc32_nswap( + const item32_t *input, fc32_t *output, size_t nsamps +){ + __m128 scalar = _mm_set_ps1(floats_per_short/(1 << 16)); + __m128i zeroi = _mm_setzero_si128(); + + //convert blocks of samples with intrinsics + size_t i = 0; for (; i < (nsamps & ~0x3); i+=4){ + //load from input + __m128i tmpi = _mm_loadu_si128(reinterpret_cast<const __m128i *>(input+i)); + + //unpack + swap 16-bit pairs + tmpi = _mm_shufflelo_epi16(tmpi, _MM_SHUFFLE(2, 3, 0, 1)); + tmpi = _mm_shufflehi_epi16(tmpi, _MM_SHUFFLE(2, 3, 0, 1)); + __m128i tmpilo = _mm_unpacklo_epi16(zeroi, tmpi); //value in upper 16 bits + __m128i tmpihi = _mm_unpackhi_epi16(zeroi, tmpi); + + //convert and scale + __m128 tmplo = _mm_mul_ps(_mm_cvtepi32_ps(tmpilo), scalar); + __m128 tmphi = _mm_mul_ps(_mm_cvtepi32_ps(tmpihi), scalar); + + //store to output + _mm_storeu_ps(reinterpret_cast<float *>(output+i+0), tmplo); + _mm_storeu_ps(reinterpret_cast<float *>(output+i+2), tmphi); + } + + //convert remainder + for (; i < nsamps; i++){ + output[i] = item32_to_fc32(input[i]); + } +} + +#else static UHD_INLINE void item32_to_fc32_nswap( const item32_t *input, fc32_t *output, size_t nsamps ){ @@ -152,10 +231,12 @@ static UHD_INLINE void item32_to_fc32_nswap( output[i] = item32_to_fc32(input[i]); } } +#endif +//////////////////////////////////// +// byte-swap +//////////////////////////////////// #if defined(USE_EMMINTRIN_H) -#include <emmintrin.h> - static UHD_INLINE void item32_to_fc32_bswap( const item32_t *input, fc32_t *output, size_t nsamps ){ @@ -167,7 +248,7 @@ static UHD_INLINE void item32_to_fc32_bswap( //load from input __m128i tmpi = _mm_loadu_si128(reinterpret_cast<const __m128i *>(input+i)); - //byteswap + unpack -> byteswap 32 bit words + //byteswap + unpack -> byteswap 16 bit words tmpi = _mm_or_si128(_mm_srli_epi16(tmpi, 8), _mm_slli_epi16(tmpi, 8)); __m128i tmpilo = _mm_unpacklo_epi16(zeroi, tmpi); //value in upper 16 bits __m128i tmpihi = _mm_unpackhi_epi16(zeroi, tmpi); diff --git a/host/lib/usrp/dboard/db_basic_and_lf.cpp b/host/lib/usrp/dboard/db_basic_and_lf.cpp index f8236d598..0b6e4a75a 100644 --- a/host/lib/usrp/dboard/db_basic_and_lf.cpp +++ b/host/lib/usrp/dboard/db_basic_and_lf.cpp @@ -170,8 +170,8 @@ void basic_rx::rx_set(const wax::obj &key_, const wax::obj &val){ return; case SUBDEV_PROP_ANTENNA: - UHD_ASSERT_THROW(val.as<std::string>() == std::string("")); - return; + if (val.as<std::string>().empty()) return; + throw std::runtime_error("no selectable antennas on this board"); case SUBDEV_PROP_FREQ: return; // it wont do you much good, but you can set it @@ -259,8 +259,8 @@ void basic_tx::tx_set(const wax::obj &key_, const wax::obj &val){ return; case SUBDEV_PROP_ANTENNA: - UHD_ASSERT_THROW(val.as<std::string>() == std::string("")); - return; + if (val.as<std::string>().empty()) return; + throw std::runtime_error("no selectable antennas on this board"); case SUBDEV_PROP_FREQ: return; // it wont do you much good, but you can set it diff --git a/host/lib/usrp/simple_usrp.cpp b/host/lib/usrp/simple_usrp.cpp index 60b25a647..e573d0fc0 100644 --- a/host/lib/usrp/simple_usrp.cpp +++ b/host/lib/usrp/simple_usrp.cpp @@ -168,6 +168,10 @@ public: return _rx_subdev()[SUBDEV_PROP_RSSI].as<float>(); } + dboard_iface::sptr get_rx_dboard_iface(void){ + return _rx_dboard()[DBOARD_PROP_DBOARD_IFACE].as<dboard_iface::sptr>(); + } + /******************************************************************* * TX methods ******************************************************************/ @@ -232,6 +236,10 @@ public: return _tx_subdev()[SUBDEV_PROP_LO_LOCKED].as<bool>(); } + dboard_iface::sptr get_tx_dboard_iface(void){ + return _tx_dboard()[DBOARD_PROP_DBOARD_IFACE].as<dboard_iface::sptr>(); + } + private: device::sptr _dev; wax::obj _mboard(void){ diff --git a/host/lib/usrp/usrp2/dboard_iface.cpp b/host/lib/usrp/usrp2/dboard_iface.cpp index 8bded1ea3..f6d2b718a 100644 --- a/host/lib/usrp/usrp2/dboard_iface.cpp +++ b/host/lib/usrp/usrp2/dboard_iface.cpp @@ -51,6 +51,7 @@ public: void set_atr_reg(unit_t, atr_reg_t, boost::uint16_t); void set_gpio_ddr(unit_t, boost::uint16_t); void write_gpio(unit_t, boost::uint16_t); + void set_gpio_debug(unit_t, int); boost::uint16_t read_gpio(unit_t); void write_i2c(boost::uint8_t, const byte_vector_t &); @@ -219,6 +220,25 @@ void usrp2_dboard_iface::set_atr_reg(unit_t unit, atr_reg_t atr, boost::uint16_t _iface->poke16(unit_to_atr_to_addr[unit][atr], value); } +void usrp2_dboard_iface::set_gpio_debug(unit_t unit, int which){ + this->set_gpio_ddr(unit, 0xffff); //all outputs + + //calculate the new selection mux setting + boost::uint32_t new_sels = 0x0; + int sel = (which == 0)? + U2_FLAG_GPIO_SEL_DEBUG_0: + U2_FLAG_GPIO_SEL_DEBUG_1; + for(size_t i = 0; i < 16; i++){ + new_sels |= sel << (i*2); + } + + //write the selection mux value to register + switch(unit){ + case UNIT_RX: _iface->poke32(U2_REG_GPIO_RX_SEL, new_sels); return; + case UNIT_TX: _iface->poke32(U2_REG_GPIO_TX_SEL, new_sels); return; + } +} + /*********************************************************************** * SPI **********************************************************************/ |