diff options
author | Arturs Artamonovs <arturs.artamonovs@protonmail.com> | 2024-11-03 15:56:55 +0000 |
---|---|---|
committer | Arturs Artamonovs <arturs.artamonovs@protonmail.com> | 2024-11-03 15:56:55 +0000 |
commit | cf4444e7390365df43ecbd3d130015c1e06ef88f (patch) | |
tree | 8a6eb114135a04d5efd5af213577b4fac47532ae /Radio/HW/BladeRF/thirdparty | |
parent | ca50c0f64f1b2fce46b4cb83ed111854bac13852 (diff) | |
download | PrySDR-cf4444e7390365df43ecbd3d130015c1e06ef88f.tar.gz PrySDR-cf4444e7390365df43ecbd3d130015c1e06ef88f.zip |
BladeRF library compiles
Diffstat (limited to 'Radio/HW/BladeRF/thirdparty')
7 files changed, 1877 insertions, 0 deletions
diff --git a/Radio/HW/BladeRF/thirdparty/analogdevicesinc/no-OS_local/platform_bladerf2/adc_core.c b/Radio/HW/BladeRF/thirdparty/analogdevicesinc/no-OS_local/platform_bladerf2/adc_core.c new file mode 100644 index 0000000..9b7742d --- /dev/null +++ b/Radio/HW/BladeRF/thirdparty/analogdevicesinc/no-OS_local/platform_bladerf2/adc_core.c @@ -0,0 +1,261 @@ +/***************************************************************************//** + * @file adc_core.c + * @brief Implementation of ADC Core Driver. + * @author DBogdan (dragos.bogdan@analog.com) +******************************************************************************** + * Copyright 2013(c) Analog Devices, Inc. + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * - Neither the name of Analog Devices, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * - The use of this software may or may not infringe the patent rights + * of one or more patent holders. This license does not release you + * from the requirement that you obtain separate licenses from these + * patent holders to use this software. + * - Use of the software either in source or binary form, must be run + * on or directly connected to an Analog Devices Inc. component. + * + * THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT, + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, INTELLECTUAL PROPERTY RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*******************************************************************************/ + +/******************************************************************************/ +/***************************** Include Files **********************************/ +/******************************************************************************/ + +#include <stdint.h> + +#include "adc_core.h" +#include "platform.h" +#include "util.h" + +/***************************************************************************//** + * @brief adc_read +*******************************************************************************/ +int adc_read(struct ad9361_rf_phy *phy, uint32_t regAddr, uint32_t *data) +{ + return axiadc_read(phy->adc_state, regAddr, data); +} + +/***************************************************************************//** + * @brief adc_write +*******************************************************************************/ +int adc_write(struct ad9361_rf_phy *phy, uint32_t regAddr, uint32_t data) +{ + return axiadc_write(phy->adc_state, regAddr, data); +} + +/***************************************************************************//** + * @brief adc_init +*******************************************************************************/ +int adc_init(struct ad9361_rf_phy *phy) +{ + int ret; + + ret = adc_write(phy, ADC_REG_RSTN, 0); + if (ret < 0) { + return ret; + } + + ret = adc_write(phy, ADC_REG_RSTN, ADC_RSTN); + if (ret < 0) { + return ret; + } + + ret = adc_write(phy, ADC_REG_CHAN_CNTRL(0), + ADC_IQCOR_ENB | ADC_FORMAT_SIGNEXT | ADC_FORMAT_ENABLE | ADC_ENABLE); + if (ret < 0) { + return ret; + } + + ret = adc_write(phy, ADC_REG_CHAN_CNTRL(1), + ADC_IQCOR_ENB | ADC_FORMAT_SIGNEXT | ADC_FORMAT_ENABLE | ADC_ENABLE); + if (ret < 0) { + return ret; + } + + if (phy->pdata->rx2tx2) + { + ret = adc_write(phy, ADC_REG_CHAN_CNTRL(2), + ADC_IQCOR_ENB | ADC_FORMAT_SIGNEXT | ADC_FORMAT_ENABLE | ADC_ENABLE); + if (ret < 0) { + return ret; + } + + ret = adc_write(phy, ADC_REG_CHAN_CNTRL(3), + ADC_IQCOR_ENB | ADC_FORMAT_SIGNEXT | ADC_FORMAT_ENABLE | ADC_ENABLE); + if (ret < 0) { + return ret; + } + } + + return 0; +} + +/***************************************************************************//** + * @brief adc_set_calib_scale_phase +*******************************************************************************/ +int32_t adc_set_calib_scale_phase(struct ad9361_rf_phy *phy, + uint32_t phase, + uint32_t chan, + int32_t val, + int32_t val2) +{ + int ret; + uint32_t fract; + uint64_t llval; + uint32_t tmp; + + switch (val) { + case 1: + fract = 0x4000; + break; + case -1: + fract = 0xC000; + break; + case 0: + fract = 0; + if (val2 < 0) { + fract = 0x8000; + val2 *= -1; + } + break; + default: + return -1; + } + + llval = (uint64_t)val2 * 0x4000UL + (1000000UL / 2); + do_div(&llval, 1000000UL); + fract |= llval; + + ret = adc_read(phy, ADC_REG_CHAN_CNTRL_2(chan), &tmp); + if (ret < 0) { + return ret; + } + + if (!((chan + phase) % 2)) { + tmp &= ~ADC_IQCOR_COEFF_1(~0); + tmp |= ADC_IQCOR_COEFF_1(fract); + } else { + tmp &= ~ADC_IQCOR_COEFF_2(~0); + tmp |= ADC_IQCOR_COEFF_2(fract); + } + + ret = adc_write(phy, ADC_REG_CHAN_CNTRL_2(chan), tmp); + if (ret < 0) { + return ret; + } + + return 0; +} + +/***************************************************************************//** + * @brief adc_get_calib_scale_phase +*******************************************************************************/ +int32_t adc_get_calib_scale_phase(struct ad9361_rf_phy *phy, + uint32_t phase, + uint32_t chan, + int32_t *val, + int32_t *val2) +{ + int ret; + uint32_t tmp; + int32_t sign; + uint64_t llval; + + ret = adc_read(phy, ADC_REG_CHAN_CNTRL_2(chan), &tmp); + if (ret < 0) { + return ret; + } + + /* format is 1.1.14 (sign, integer and fractional bits) */ + + if (!((phase + chan) % 2)) { + tmp = ADC_TO_IQCOR_COEFF_1(tmp); + } else { + tmp = ADC_TO_IQCOR_COEFF_2(tmp); + } + + if (tmp & 0x8000) + sign = -1; + else + sign = 1; + + if (tmp & 0x4000) + *val = 1 * sign; + else + *val = 0; + + tmp &= ~0xC000; + + llval = tmp * 1000000ULL + (0x4000 / 2); + do_div(&llval, 0x4000); + if (*val == 0) + *val2 = (int32_t)llval * sign; + else + *val2 = (int32_t)llval; + + return 0; +} + +/***************************************************************************//** + * @brief adc_set_calib_scale +*******************************************************************************/ +int32_t adc_set_calib_scale(struct ad9361_rf_phy *phy, + uint32_t chan, + int32_t val, + int32_t val2) +{ + return adc_set_calib_scale_phase(phy, 0, chan, val, val2); +} + +/***************************************************************************//** + * @brief adc_get_calib_scale +*******************************************************************************/ +int32_t adc_get_calib_scale(struct ad9361_rf_phy *phy, + uint32_t chan, + int32_t *val, + int32_t *val2) +{ + return adc_get_calib_scale_phase(phy, 0, chan, val, val2); +} + +/***************************************************************************//** + * @brief adc_set_calib_phase +*******************************************************************************/ +int32_t adc_set_calib_phase(struct ad9361_rf_phy *phy, + uint32_t chan, + int32_t val, + int32_t val2) +{ + return adc_set_calib_scale_phase(phy, 1, chan, val, val2); +} + +/***************************************************************************//** + * @brief adc_get_calib_phase +*******************************************************************************/ +int32_t adc_get_calib_phase(struct ad9361_rf_phy *phy, + uint32_t chan, + int32_t *val, + int32_t *val2) +{ + return adc_get_calib_scale_phase(phy, 1, chan, val, val2); +} diff --git a/Radio/HW/BladeRF/thirdparty/analogdevicesinc/no-OS_local/platform_bladerf2/adc_core.h b/Radio/HW/BladeRF/thirdparty/analogdevicesinc/no-OS_local/platform_bladerf2/adc_core.h new file mode 100644 index 0000000..f03d2b8 --- /dev/null +++ b/Radio/HW/BladeRF/thirdparty/analogdevicesinc/no-OS_local/platform_bladerf2/adc_core.h @@ -0,0 +1,169 @@ +/***************************************************************************//** + * @file adc_core.h + * @brief Header file of ADC Core Driver. + * @author DBogdan (dragos.bogdan@analog.com) +******************************************************************************** + * Copyright 2013(c) Analog Devices, Inc. + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * - Neither the name of Analog Devices, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * - The use of this software may or may not infringe the patent rights + * of one or more patent holders. This license does not release you + * from the requirement that you obtain separate licenses from these + * patent holders to use this software. + * - Use of the software either in source or binary form, must be run + * on or directly connected to an Analog Devices Inc. component. + * + * THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT, + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, INTELLECTUAL PROPERTY RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*******************************************************************************/ +#ifndef ADC_CORE_API_H_ +#define ADC_CORE_API_H_ + +/******************************************************************************/ +/***************************** Include Files **********************************/ +/******************************************************************************/ +#include "ad9361.h" + +/******************************************************************************/ +/********************** Macros and Constants Definitions **********************/ +/******************************************************************************/ +/* ADC COMMON */ +#define ADC_REG_RSTN 0x0040 +#define ADC_RSTN (1 << 0) +#define ADC_MMCM_RSTN (1 << 1) + +#define ADC_REG_CNTRL 0x0044 +#define ADC_R1_MODE (1 << 2) +#define ADC_DDR_EDGESEL (1 << 1) +#define ADC_PIN_MODE (1 << 0) + +#define ADC_REG_STATUS 0x005C +#define ADC_MUX_PN_ERR (1 << 3) +#define ADC_MUX_PN_OOS (1 << 2) +#define ADC_MUX_OVER_RANGE (1 << 1) +#define ADC_STATUS (1 << 0) + +#define ADC_REG_DMA_CNTRL 0x0080 +#define ADC_DMA_STREAM (1 << 1) +#define ADC_DMA_START (1 << 0) + +#define ADC_REG_DMA_COUNT 0x0084 +#define ADC_DMA_COUNT(x) (((x) & 0xFFFFFFFF) << 0) +#define ADC_TO_DMA_COUNT(x) (((x) >> 0) & 0xFFFFFFFF) + +#define ADC_REG_DMA_STATUS 0x0088 +#define ADC_DMA_OVF (1 << 2) +#define ADC_DMA_UNF (1 << 1) +#define ADC_DMA_STATUS (1 << 0) + +#define ADC_REG_DMA_BUSWIDTH 0x008C +#define ADC_DMA_BUSWIDTH(x) (((x) & 0xFFFFFFFF) << 0) +#define ADC_TO_DMA_BUSWIDTH(x) (((x) >> 0) & 0xFFFFFFFF) + +/* ADC CHANNEL */ +#define ADC_REG_CHAN_CNTRL(c) (0x0400 + (c) * 0x40) +#define ADC_LB_EN (1 << 11) +#define ADC_PN_SEL (1 << 10) +#define ADC_IQCOR_ENB (1 << 9) +#define ADC_DCFILT_ENB (1 << 8) +#define ADC_FORMAT_SIGNEXT (1 << 6) +#define ADC_FORMAT_TYPE (1 << 5) +#define ADC_FORMAT_ENABLE (1 << 4) +#define ADC_PN23_TYPE (1 << 1) +#define ADC_ENABLE (1 << 0) + +#define ADC_REG_CHAN_STATUS(c) (0x0404 + (c) * 0x40) +#define ADC_PN_ERR (1 << 2) +#define ADC_PN_OOS (1 << 1) +#define ADC_OVER_RANGE (1 << 0) + +#define ADC_REG_CHAN_CNTRL_1(c) (0x0410 + (c) * 0x40) +#define ADC_DCFILT_OFFSET(x) (((x) & 0xFFFF) << 16) +#define ADC_TO_DCFILT_OFFSET(x) (((x) >> 16) & 0xFFFF) +#define ADC_DCFILT_COEFF(x) (((x) & 0xFFFF) << 0) +#define ADC_TO_DCFILT_COEFF(x) (((x) >> 0) & 0xFFFF) + +#define ADC_REG_CHAN_CNTRL_2(c) (0x0414 + (c) * 0x40) +#define ADC_IQCOR_COEFF_1(x) (((x) & 0xFFFF) << 16) +#define ADC_TO_IQCOR_COEFF_1(x) (((x) >> 16) & 0xFFFF) +#define ADC_IQCOR_COEFF_2(x) (((x) & 0xFFFF) << 0) +#define ADC_TO_IQCOR_COEFF_2(x) (((x) >> 0) & 0xFFFF) + +#define ADC_REG_CHAN_CNTRL_3(c) (0x0418 + (c) * 0x40) /* v8.0 */ +#define ADC_ADC_PN_SEL(x) (((x) & 0xF) << 16) +#define ADC_TO_ADC_PN_SEL(x) (((x) >> 16) & 0xF) +#define ADC_ADC_DATA_SEL(x) (((x) & 0xF) << 0) +#define ADC_TO_ADC_DATA_SEL(x) (((x) >> 0) & 0xF) + +#define AXI_DMAC_REG_IRQ_MASK 0x80 +#define AXI_DMAC_REG_IRQ_PENDING 0x84 +#define AXI_DMAC_REG_IRQ_SOURCE 0x88 + +#define AXI_DMAC_REG_CTRL 0x400 +#define AXI_DMAC_REG_TRANSFER_ID 0x404 +#define AXI_DMAC_REG_START_TRANSFER 0x408 +#define AXI_DMAC_REG_FLAGS 0x40c +#define AXI_DMAC_REG_DEST_ADDRESS 0x410 +#define AXI_DMAC_REG_SRC_ADDRESS 0x414 +#define AXI_DMAC_REG_X_LENGTH 0x418 +#define AXI_DMAC_REG_Y_LENGTH 0x41c +#define AXI_DMAC_REG_DEST_STRIDE 0x420 +#define AXI_DMAC_REG_SRC_STRIDE 0x424 +#define AXI_DMAC_REG_TRANSFER_DONE 0x428 +#define AXI_DMAC_REG_ACTIVE_TRANSFER_ID 0x42c +#define AXI_DMAC_REG_STATUS 0x430 +#define AXI_DMAC_REG_CURRENT_DEST_ADDR 0x434 +#define AXI_DMAC_REG_CURRENT_SRC_ADDR 0x438 +#define AXI_DMAC_REG_DBG0 0x43c +#define AXI_DMAC_REG_DBG1 0x440 + +#define AXI_DMAC_CTRL_ENABLE (1 << 0) +#define AXI_DMAC_CTRL_PAUSE (1 << 1) + +#define AXI_DMAC_IRQ_SOT (1 << 0) +#define AXI_DMAC_IRQ_EOT (1 << 1) + +/******************************************************************************/ +/************************ Functions Declarations ******************************/ +/******************************************************************************/ + +int adc_init(struct ad9361_rf_phy *phy); +int adc_read(struct ad9361_rf_phy *phy, uint32_t regAddr, uint32_t *data); +int adc_write(struct ad9361_rf_phy *phy, uint32_t regAddr, uint32_t data); +int32_t adc_set_calib_scale(struct ad9361_rf_phy *phy, + uint32_t chan, + int32_t val, + int32_t val2); +int32_t adc_get_calib_scale(struct ad9361_rf_phy *phy, + uint32_t chan, + int32_t *val, + int32_t *val2); +int32_t adc_set_calib_phase(struct ad9361_rf_phy *phy, + uint32_t chan, + int32_t val, + int32_t val2); +int32_t adc_get_calib_phase(struct ad9361_rf_phy *phy, + uint32_t chan, + int32_t *val, + int32_t *val2); +#endif diff --git a/Radio/HW/BladeRF/thirdparty/analogdevicesinc/no-OS_local/platform_bladerf2/config.h b/Radio/HW/BladeRF/thirdparty/analogdevicesinc/no-OS_local/platform_bladerf2/config.h new file mode 100644 index 0000000..179780d --- /dev/null +++ b/Radio/HW/BladeRF/thirdparty/analogdevicesinc/no-OS_local/platform_bladerf2/config.h @@ -0,0 +1,67 @@ +/***************************************************************************//** + * @file config.h + * @brief Config file of AD9361/API Driver. + * @author DBogdan (dragos.bogdan@analog.com) +******************************************************************************** + * Copyright 2015(c) Analog Devices, Inc. + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * - Neither the name of Analog Devices, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * - The use of this software may or may not infringe the patent rights + * of one or more patent holders. This license does not release you + * from the requirement that you obtain separate licenses from these + * patent holders to use this software. + * - Use of the software either in source or binary form, must be run + * on or directly connected to an Analog Devices Inc. component. + * + * THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT, + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, INTELLECTUAL PROPERTY RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*******************************************************************************/ +#ifndef ADI_NOOS_CONFIG_H_ +#define ADI_NOOS_CONFIG_H_ + +#define HAVE_VERBOSE_MESSAGES /* Recommended during development prints errors and warnings */ +//#define HAVE_DEBUG_MESSAGES /* For Debug purposes only */ + +/* + * In case memory footprint is a concern these options allow + * to disable unused functionality which may free up a few kb + */ + +#define HAVE_SPLIT_GAIN_TABLE 1 /* only set to 0 in case split_gain_table_mode_enable = 0*/ +#define HAVE_TDD_SYNTH_TABLE 1 /* only set to 0 in case split_gain_table_mode_enable = 0*/ + +#define AD9361_DEVICE 1 /* set it 1 if AD9361 device is used, 0 otherwise */ +#define AD9364_DEVICE 0 /* set it 1 if AD9364 device is used, 0 otherwise */ +#define AD9363A_DEVICE 0 /* set it 1 if AD9363A device is used, 0 otherwise */ + +//#define CONSOLE_COMMANDS +//#define XILINX_PLATFORM +#define ALTERA_PLATFORM +//#define FMCOMMS5 +//#define PICOZED_SDR +//#define PICOZED_SDR_CMOS +//#define CAPTURE_SCRIPT +//#define AXI_ADC_NOT_PRESENT +//#define TDD_SWITCH_STATE_EXAMPLE + +#endif diff --git a/Radio/HW/BladeRF/thirdparty/analogdevicesinc/no-OS_local/platform_bladerf2/dac_core.c b/Radio/HW/BladeRF/thirdparty/analogdevicesinc/no-OS_local/platform_bladerf2/dac_core.c new file mode 100644 index 0000000..a103ffe --- /dev/null +++ b/Radio/HW/BladeRF/thirdparty/analogdevicesinc/no-OS_local/platform_bladerf2/dac_core.c @@ -0,0 +1,717 @@ +/***************************************************************************//** + * @file dac_core.c + * @brief Implementation of DAC Core Driver. + * @author DBogdan (dragos.bogdan@analog.com) +******************************************************************************** + * Copyright 2013(c) Analog Devices, Inc. + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * - Neither the name of Analog Devices, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * - The use of this software may or may not infringe the patent rights + * of one or more patent holders. This license does not release you + * from the requirement that you obtain separate licenses from these + * patent holders to use this software. + * - Use of the software either in source or binary form, must be run + * on or directly connected to an Analog Devices Inc. component. + * + * THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT, + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, INTELLECTUAL PROPERTY RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*******************************************************************************/ + +/******************************************************************************/ +/***************************** Include Files **********************************/ +/******************************************************************************/ + +#include <stdint.h> + +#include "dac_core.h" +#include "platform.h" +#include "util.h" + +/******************************************************************************/ +/********************** Macros and Constants Definitions **********************/ +/******************************************************************************/ +const uint16_t sine_lut[32] = { + 0x000, 0x031, 0x061, 0x08D, 0x0B4, 0x0D4, 0x0EC, 0x0FA, + 0x0FF, 0x0FA, 0x0EC, 0x0D4, 0x0B4, 0x08D, 0x061, 0x031, + 0x000, 0xFCE, 0xF9E, 0xF72, 0xF4B, 0xF2B, 0xF13, 0xF05, + 0xF00, 0xF05, 0xF13, 0xF2B, 0xF4B, 0xF72, 0xF9E, 0xFCE +}; + +/***************************************************************************//** + * @brief dac_read +*******************************************************************************/ +int dac_read(struct ad9361_rf_phy *phy, uint32_t regAddr, uint32_t *data) +{ + return axiadc_read(phy->adc_state, regAddr + 0x4000, data); +} + +/***************************************************************************//** + * @brief dac_write +*******************************************************************************/ +int dac_write(struct ad9361_rf_phy *phy, uint32_t regAddr, uint32_t data) +{ + return axiadc_write(phy->adc_state, regAddr + 0x4000, data); +} + +/***************************************************************************//** + * @brief dds_default_setup +*******************************************************************************/ +static int dds_default_setup(struct ad9361_rf_phy *phy, + uint32_t chan, uint32_t phase, + uint32_t freq, int32_t scale) +{ + struct dds_state *dds_st = &phy->adc_state->dac_dds_state; + int ret; + + ret = dds_set_phase(phy, chan, phase); + if (ret < 0) { + return ret; + } + + ret = dds_set_frequency(phy, chan, freq); + if (ret < 0) { + return ret; + } + + ret = dds_set_scale(phy, chan, scale); + if (ret < 0) { + return ret; + } + + dds_st->cached_freq[chan] = freq; + dds_st->cached_phase[chan] = phase; + dds_st->cached_scale[chan] = scale; + + return 0; +} + +/***************************************************************************//** + * @brief dac_stop +*******************************************************************************/ +int dac_stop(struct ad9361_rf_phy *phy) +{ + struct dds_state *dds_st = &phy->adc_state->dac_dds_state; + + if (PCORE_VERSION_MAJOR(dds_st->pcore_version) < 8) + { + return dac_write(phy, DAC_REG_CNTRL_1, 0); + } + + return 0; +} + +/***************************************************************************//** + * @brief dac_start_sync +*******************************************************************************/ +int dac_start_sync(struct ad9361_rf_phy *phy, bool force_on) +{ + struct dds_state *dds_st = &phy->adc_state->dac_dds_state; + + if (PCORE_VERSION_MAJOR(dds_st->pcore_version) < 8) + { + return dac_write(phy, DAC_REG_CNTRL_1, (dds_st->enable || force_on) ? DAC_ENABLE : 0); + } + else + { + return dac_write(phy, DAC_REG_CNTRL_1, DAC_SYNC); + } +} + +/***************************************************************************//** + * @brief dac_init +*******************************************************************************/ +int dac_init(struct ad9361_rf_phy *phy, uint8_t data_sel, uint8_t config_dma) +{ + struct dds_state *dds_st; + int ret; + uint32_t reg_ctrl_2; + + dds_st = &phy->adc_state->dac_dds_state; + + ret = dac_write(phy, DAC_REG_RSTN, 0x0); + if (ret < 0) { + return ret; + } + + ret = dac_write(phy, DAC_REG_RSTN, DAC_RSTN); + if (ret < 0) { + return ret; + } + + dds_st->dac_clk = &phy->clks[TX_SAMPL_CLK]->rate; + dds_st->rx2tx2 = phy->pdata->rx2tx2; + + ret = dac_read(phy, DAC_REG_CNTRL_2, ®_ctrl_2); + if (ret < 0) { + return ret; + } + + if(dds_st->rx2tx2) + { + dds_st->num_dds_channels = 8; + + if(phy->pdata->port_ctrl.pp_conf[2] & LVDS_MODE) + ret = dac_write(phy, DAC_REG_RATECNTRL, DAC_RATE(3)); + else + ret = dac_write(phy, DAC_REG_RATECNTRL, DAC_RATE(1)); + + if (ret < 0) { + return ret; + } + + reg_ctrl_2 &= ~DAC_R1_MODE; + } + else + { + dds_st->num_dds_channels = 4; + + if(phy->pdata->port_ctrl.pp_conf[2] & LVDS_MODE) + ret = dac_write(phy, DAC_REG_RATECNTRL, DAC_RATE(1)); + else + ret = dac_write(phy, DAC_REG_RATECNTRL, DAC_RATE(0)); + + if (ret < 0) { + return ret; + } + + reg_ctrl_2 |= DAC_R1_MODE; + } + + ret = dac_write(phy, DAC_REG_CNTRL_2, reg_ctrl_2); + if (ret < 0) { + return ret; + } + + ret = dac_read(phy, DAC_REG_VERSION, &dds_st->pcore_version); + if (ret < 0) { + return ret; + } + + ret = dac_write(phy, DAC_REG_CNTRL_1, 0); + if (ret < 0) { + return ret; + } + + switch (data_sel) { + case DATA_SEL_DDS: + ret = dds_default_setup(phy, DDS_CHAN_TX1_I_F1, 90000, 1000000, 250000); + if (ret < 0) { + return ret; + } + + ret = dds_default_setup(phy, DDS_CHAN_TX1_I_F2, 90000, 1000000, 250000); + if (ret < 0) { + return ret; + } + + ret = dds_default_setup(phy, DDS_CHAN_TX1_Q_F1, 0, 1000000, 250000); + if (ret < 0) { + return ret; + } + + ret = dds_default_setup(phy, DDS_CHAN_TX1_Q_F2, 0, 1000000, 250000); + if (ret < 0) { + return ret; + } + + if(dds_st->rx2tx2) + { + ret = dds_default_setup(phy, DDS_CHAN_TX2_I_F1, 90000, 1000000, 250000); + if (ret < 0) { + return ret; + } + + ret = dds_default_setup(phy, DDS_CHAN_TX2_I_F2, 90000, 1000000, 250000); + if (ret < 0) { + return ret; + } + + ret = dds_default_setup(phy, DDS_CHAN_TX2_Q_F1, 0, 1000000, 250000); + if (ret < 0) { + return ret; + } + + ret = dds_default_setup(phy, DDS_CHAN_TX2_Q_F2, 0, 1000000, 250000); + if (ret < 0) { + return ret; + } + } + + ret = dac_datasel(phy, -1, DATA_SEL_DDS); + if (ret < 0) { + return ret; + } + + break; + case DATA_SEL_DMA: + ret = dac_datasel(phy, -1, DATA_SEL_DMA); + if (ret < 0) { + return ret; + } + break; + default: + break; + } + + dds_st->enable = true; + + ret = dac_start_sync(phy, 0); + if (ret < 0) { + return ret; + } + + return 0; +} + +/***************************************************************************//** + * @brief dds_set_frequency +*******************************************************************************/ +int dds_set_frequency(struct ad9361_rf_phy *phy, uint32_t chan, uint32_t freq) +{ + struct dds_state *dds_st = &phy->adc_state->dac_dds_state; + int ret; + uint64_t val64; + uint32_t reg; + + dds_st->cached_freq[chan] = freq; + + ret = dac_stop(phy); + if (ret < 0) { + return ret; + } + + ret = dac_read(phy, DAC_REG_CHAN_CNTRL_2_IIOCHAN(chan), ®); + if (ret < 0) { + return ret; + } + + reg &= ~DAC_DDS_INCR(~0); + val64 = (uint64_t) freq * 0xFFFFULL; + do_div(&val64, *dds_st->dac_clk); + reg |= DAC_DDS_INCR(val64) | 1; + + ret = dac_write(phy, DAC_REG_CHAN_CNTRL_2_IIOCHAN(chan), reg); + if (ret < 0) { + return ret; + } + + ret = dac_start_sync(phy, 0); + if (ret < 0) { + return ret; + } + + return 0; +} + +/***************************************************************************//** + * @brief dds_set_phase +*******************************************************************************/ +int dds_set_phase(struct ad9361_rf_phy *phy, uint32_t chan, uint32_t phase) +{ + struct dds_state *dds_st = &phy->adc_state->dac_dds_state; + int ret; + uint64_t val64; + uint32_t reg; + + dds_st->cached_phase[chan] = phase; + + ret = dac_stop(phy); + if (ret < 0) { + return ret; + } + + ret = dac_read(phy, DAC_REG_CHAN_CNTRL_2_IIOCHAN(chan), ®); + if (ret < 0) { + return ret; + } + + reg &= ~DAC_DDS_INIT(~0); + val64 = (uint64_t) phase * 0x10000ULL + (360000 / 2); + do_div(&val64, 360000); + reg |= DAC_DDS_INIT(val64); + + ret = dac_write(phy, DAC_REG_CHAN_CNTRL_2_IIOCHAN(chan), reg); + if (ret < 0) { + return ret; + } + + ret = dac_start_sync(phy, 0); + if (ret < 0) { + return ret; + } + + return 0; +} + +/***************************************************************************//** + * @brief dds_set_phase +*******************************************************************************/ +int dds_set_scale(struct ad9361_rf_phy *phy, uint32_t chan, int32_t scale_micro_units) +{ + struct dds_state *dds_st = &phy->adc_state->dac_dds_state; + int ret; + uint32_t scale_reg; + uint32_t sign_part; + uint32_t int_part; + uint32_t fract_part; + + if (PCORE_VERSION_MAJOR(dds_st->pcore_version) > 6) + { + if(scale_micro_units >= 1000000) + { + sign_part = 0; + int_part = 1; + fract_part = 0; + dds_st->cached_scale[chan] = 1000000; + goto set_scale_reg; + } + if(scale_micro_units <= -1000000) + { + sign_part = 1; + int_part = 1; + fract_part = 0; + dds_st->cached_scale[chan] = -1000000; + goto set_scale_reg; + } + dds_st->cached_scale[chan] = scale_micro_units; + if(scale_micro_units < 0) + { + sign_part = 1; + int_part = 0; + scale_micro_units *= -1; + } + else + { + sign_part = 0; + int_part = 0; + } + fract_part = (uint32_t)(((uint64_t)scale_micro_units * 0x4000) / 1000000); + set_scale_reg: + scale_reg = (sign_part << 15) | (int_part << 14) | fract_part; + } + else + { + if(scale_micro_units >= 1000000) + { + scale_reg = 0; + scale_micro_units = 1000000; + } + if(scale_micro_units <= 0) + { + scale_reg = 0; + scale_micro_units = 0; + } + dds_st->cached_scale[chan] = scale_micro_units; + fract_part = (uint32_t)(scale_micro_units); + scale_reg = 500000 / fract_part; + } + + ret = dac_stop(phy); + if (ret < 0) { + return ret; + } + + ret = dac_write(phy, DAC_REG_CHAN_CNTRL_1_IIOCHAN(chan), DAC_DDS_SCALE(scale_reg)); + if (ret < 0) { + return ret; + } + + ret = dac_start_sync(phy, 0); + if (ret < 0) { + return ret; + } + + return 0; +} + +/***************************************************************************//** + * @brief dds_update +*******************************************************************************/ +int dds_update(struct ad9361_rf_phy *phy) +{ + struct dds_state *dds_st = &phy->adc_state->dac_dds_state; + int ret; + uint32_t chan; + + for(chan = DDS_CHAN_TX1_I_F1; chan <= DDS_CHAN_TX2_Q_F2; chan++) + { + ret = dds_set_frequency(phy, chan, dds_st->cached_freq[chan]); + if (ret < 0) { + return ret; + } + + ret = dds_set_phase(phy, chan, dds_st->cached_phase[chan]); + if (ret < 0) { + return ret; + } + + ret = dds_set_scale(phy, chan, dds_st->cached_scale[chan]); + if (ret < 0) { + return ret; + } + } + + return 0; +} + +/***************************************************************************//** + * @brief dac_datasel +*******************************************************************************/ +int dac_datasel(struct ad9361_rf_phy *phy, int32_t chan, enum dds_data_select sel) +{ + struct dds_state *dds_st = &phy->adc_state->dac_dds_state; + int ret; + + if (PCORE_VERSION_MAJOR(dds_st->pcore_version) > 7) { + if (chan < 0) { /* ALL */ + uint32_t i; + for (i = 0; i < dds_st->num_dds_channels; i++) { + ret = dac_write(phy, DAC_REG_CHAN_CNTRL_7(i), sel); + if (ret < 0) { + return ret; + } + } + } else { + ret = dac_write(phy, DAC_REG_CHAN_CNTRL_7(chan), sel); + if (ret < 0) { + return ret; + } + } + } else { + uint32_t reg; + + switch(sel) { + case DATA_SEL_DDS: + case DATA_SEL_SED: + case DATA_SEL_DMA: + ret = dac_read(phy, DAC_REG_CNTRL_2, ®); + if (ret < 0) { + return ret; + } + + reg &= ~DAC_DATA_SEL(~0); + reg |= DAC_DATA_SEL(sel); + + ret = dac_write(phy, DAC_REG_CNTRL_2, reg); + if (ret < 0) { + return ret; + } + break; + default: + return -EINVAL; + } + } + + return 0; +} + +/***************************************************************************//** + * @brief dds_to_signed_mag_fmt +*******************************************************************************/ +uint32_t dds_to_signed_mag_fmt(int32_t val, int32_t val2) +{ + uint32_t i; + uint64_t val64; + + /* format is 1.1.14 (sign, integer and fractional bits) */ + + switch (val) { + case 1: + i = 0x4000; + break; + case -1: + i = 0xC000; + break; + case 0: + i = 0; + if (val2 < 0) { + i = 0x8000; + val2 *= -1; + } + break; + default: + /* Invalid Value */ + i = 0; + } + + val64 = (uint64_t)val2 * 0x4000UL + (1000000UL / 2); + do_div(&val64, 1000000UL); + + return i | (uint32_t)val64; +} + +/***************************************************************************//** + * @brief dds_from_signed_mag_fmt +*******************************************************************************/ +void dds_from_signed_mag_fmt(uint32_t val, + int32_t *r_val, + int32_t *r_val2) +{ + uint64_t val64; + int32_t sign; + + if (val & 0x8000) + sign = -1; + else + sign = 1; + + if (val & 0x4000) + *r_val = 1 * sign; + else + *r_val = 0; + + val &= ~0xC000; + + val64 = val * 1000000ULL + (0x4000 / 2); + do_div(&val64, 0x4000); + + if (*r_val == 0) + *r_val2 = (uint32_t)val64 * sign; + else + *r_val2 = (uint32_t)val64; +} + +/***************************************************************************//** + * @brief dds_set_calib_scale_phase +*******************************************************************************/ +int32_t dds_set_calib_scale_phase(struct ad9361_rf_phy *phy, + uint32_t phase, + uint32_t chan, + int32_t val, + int32_t val2) +{ + struct dds_state *dds_st = &phy->adc_state->dac_dds_state; + int ret; + uint32_t reg; + uint32_t i; + + if (PCORE_VERSION_MAJOR(dds_st->pcore_version) < 8) { + return -1; + } + + i = dds_to_signed_mag_fmt(val, val2); + + ret = dac_read(phy, DAC_REG_CHAN_CNTRL_8(chan), ®); + if (ret < 0) { + return ret; + } + + if (!((chan + phase) % 2)) { + reg &= ~DAC_IQCOR_COEFF_1(~0); + reg |= DAC_IQCOR_COEFF_1(i); + } else { + reg &= ~DAC_IQCOR_COEFF_2(~0); + reg |= DAC_IQCOR_COEFF_2(i); + } + + ret = dac_write(phy, DAC_REG_CHAN_CNTRL_8(chan), reg); + if (ret < 0) { + return ret; + } + + ret = dac_write(phy, DAC_REG_CHAN_CNTRL_6(chan), DAC_IQCOR_ENB); + if (ret < 0) { + return ret; + } + + return 0; +} + +/***************************************************************************//** + * @brief dds_get_calib_scale_phase +*******************************************************************************/ +int32_t dds_get_calib_scale_phase(struct ad9361_rf_phy *phy, + uint32_t phase, + uint32_t chan, + int32_t *val, + int32_t *val2) +{ + struct dds_state *dds_st = &phy->adc_state->dac_dds_state; + int ret; + uint32_t reg; + + if (PCORE_VERSION_MAJOR(dds_st->pcore_version) < 8) { + return -1; + } + + ret = dac_read(phy, DAC_REG_CHAN_CNTRL_8(chan), ®); + if (ret < 0) { + return ret; + } + + /* format is 1.1.14 (sign, integer and fractional bits) */ + + if (!((phase + chan) % 2)) { + reg = DAC_TO_IQCOR_COEFF_1(reg); + } else { + reg = DAC_TO_IQCOR_COEFF_2(reg); + } + + dds_from_signed_mag_fmt(reg, val, val2); + + return 0; +} + +/***************************************************************************//** + * @brief dds_set_calib_scale +*******************************************************************************/ +int32_t dds_set_calib_scale(struct ad9361_rf_phy *phy, + uint32_t chan, + int32_t val, + int32_t val2) +{ + return dds_set_calib_scale_phase(phy, 0, chan, val, val2); +} + +/***************************************************************************//** + * @brief dds_get_calib_scale +*******************************************************************************/ +int32_t dds_get_calib_scale(struct ad9361_rf_phy *phy, + uint32_t chan, + int32_t *val, + int32_t *val2) +{ + return dds_get_calib_scale_phase(phy, 0, chan, val, val2); +} + +/***************************************************************************//** + * @brief dds_set_calib_phase +*******************************************************************************/ +int32_t dds_set_calib_phase(struct ad9361_rf_phy *phy, + uint32_t chan, + int32_t val, + int32_t val2) +{ + return dds_set_calib_scale_phase(phy, 1, chan, val, val2); +} + +/***************************************************************************//** + * @brief dds_get_calib_phase +*******************************************************************************/ +int32_t dds_get_calib_phase(struct ad9361_rf_phy *phy, + uint32_t chan, + int32_t *val, + int32_t *val2) +{ + return dds_get_calib_scale_phase(phy, 1, chan, val, val2); +} diff --git a/Radio/HW/BladeRF/thirdparty/analogdevicesinc/no-OS_local/platform_bladerf2/dac_core.h b/Radio/HW/BladeRF/thirdparty/analogdevicesinc/no-OS_local/platform_bladerf2/dac_core.h new file mode 100644 index 0000000..46b516a --- /dev/null +++ b/Radio/HW/BladeRF/thirdparty/analogdevicesinc/no-OS_local/platform_bladerf2/dac_core.h @@ -0,0 +1,199 @@ +/***************************************************************************//** + * @file dac_core.h + * @brief Header file of DAC Core Driver. + * @author DBogdan (dragos.bogdan@analog.com) +******************************************************************************** + * Copyright 2013(c) Analog Devices, Inc. + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * - Neither the name of Analog Devices, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * - The use of this software may or may not infringe the patent rights + * of one or more patent holders. This license does not release you + * from the requirement that you obtain separate licenses from these + * patent holders to use this software. + * - Use of the software either in source or binary form, must be run + * on or directly connected to an Analog Devices Inc. component. + * + * THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT, + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, INTELLECTUAL PROPERTY RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*******************************************************************************/ +#ifndef DAC_CORE_API_H_ +#define DAC_CORE_API_H_ + +/******************************************************************************/ +/***************************** Include Files **********************************/ +/******************************************************************************/ +#include "ad9361.h" + +/******************************************************************************/ +/********************** Macros and Constants Definitions **********************/ +/******************************************************************************/ +#define DAC_REG_VERSION 0x0000 +#define DAC_VERSION(x) (((x) & 0xffffffff) << 0) +#define VERSION_IS(x,y,z) ((x) << 16 | (y) << 8 | (z)) +#define DAC_REG_ID 0x0004 +#define DAC_ID(x) (((x) & 0xffffffff) << 0) +#define DAC_REG_SCRATCH 0x0008 +#define DAC_SCRATCH(x) (((x) & 0xffffffff) << 0) + +#define PCORE_VERSION_MAJOR(version) (version >> 16) + +#define DAC_REG_RSTN 0x0040 +#define DAC_RSTN (1 << 0) +#define DAC_MMCM_RSTN (1 << 1) + +#define DAC_REG_RATECNTRL 0x004C +#define DAC_RATE(x) (((x) & 0xFF) << 0) +#define DAC_TO_RATE(x) (((x) >> 0) & 0xFF) + +#define DAC_REG_CNTRL_1 0x0044 +#define DAC_ENABLE (1 << 0) /* v7.0 */ +#define DAC_SYNC (1 << 0) /* v8.0 */ + +#define DAC_REG_CNTRL_2 0x0048 +#define DAC_PAR_TYPE (1 << 7) +#define DAC_PAR_ENB (1 << 6) +#define DAC_R1_MODE (1 << 5) +#define DAC_DATA_FORMAT (1 << 4) +#define DAC_DATA_SEL(x) (((x) & 0xF) << 0) /* v7.0 */ +#define DAC_TO_DATA_SEL(x) (((x) >> 0) & 0xF) /* v7.0 */ + +#define DAC_REG_VDMA_FRMCNT 0x0084 +#define DAC_VDMA_FRMCNT(x) (((x) & 0xFFFFFFFF) << 0) +#define DAC_TO_VDMA_FRMCNT(x) (((x) >> 0) & 0xFFFFFFFF) + +#define DAC_REG_VDMA_STATUS 0x0088 +#define DAC_VDMA_OVF (1 << 1) +#define DAC_VDMA_UNF (1 << 0) + +enum dds_data_select { + DATA_SEL_DDS, + DATA_SEL_SED, + DATA_SEL_DMA, + DATA_SEL_ZERO, /* OUTPUT 0 */ + DATA_SEL_PN7, + DATA_SEL_PN15, + DATA_SEL_PN23, + DATA_SEL_PN31, + DATA_SEL_LB, /* loopback data (ADC) */ + DATA_SEL_PNXX, /* (Device specific) */ +}; + +#define DAC_REG_CHAN_CNTRL_1_IIOCHAN(x) (0x0400 + ((x) >> 1) * 0x40 + ((x) & 1) * 0x8) +#define DAC_DDS_SCALE(x) (((x) & 0xFFFF) << 0) +#define DAC_TO_DDS_SCALE(x) (((x) >> 0) & 0xFFFF) + +#define DAC_REG_CHAN_CNTRL_2_IIOCHAN(x) (0x0404 + ((x) >> 1) * 0x40 + ((x) & 1) * 0x8) +#define DAC_DDS_INIT(x) (((x) & 0xFFFF) << 16) +#define DAC_TO_DDS_INIT(x) (((x) >> 16) & 0xFFFF) +#define DAC_DDS_INCR(x) (((x) & 0xFFFF) << 0) +#define DAC_TO_DDS_INCR(x) (((x) >> 0) & 0xFFFF) + +#define DDS_CHAN_TX1_I_F1 0 +#define DDS_CHAN_TX1_I_F2 1 +#define DDS_CHAN_TX1_Q_F1 2 +#define DDS_CHAN_TX1_Q_F2 3 +#define DDS_CHAN_TX2_I_F1 4 +#define DDS_CHAN_TX2_I_F2 5 +#define DDS_CHAN_TX2_Q_F1 6 +#define DDS_CHAN_TX2_Q_F2 7 + +#define AXI_DMAC_REG_IRQ_MASK 0x80 +#define AXI_DMAC_REG_IRQ_PENDING 0x84 +#define AXI_DMAC_REG_IRQ_SOURCE 0x88 + +#define AXI_DMAC_REG_CTRL 0x400 +#define AXI_DMAC_REG_TRANSFER_ID 0x404 +#define AXI_DMAC_REG_START_TRANSFER 0x408 +#define AXI_DMAC_REG_FLAGS 0x40c +#define AXI_DMAC_REG_DEST_ADDRESS 0x410 +#define AXI_DMAC_REG_SRC_ADDRESS 0x414 +#define AXI_DMAC_REG_X_LENGTH 0x418 +#define AXI_DMAC_REG_Y_LENGTH 0x41c +#define AXI_DMAC_REG_DEST_STRIDE 0x420 +#define AXI_DMAC_REG_SRC_STRIDE 0x424 +#define AXI_DMAC_REG_TRANSFER_DONE 0x428 +#define AXI_DMAC_REG_ACTIVE_TRANSFER_ID 0x42c +#define AXI_DMAC_REG_STATUS 0x430 +#define AXI_DMAC_REG_CURRENT_DEST_ADDR 0x434 +#define AXI_DMAC_REG_CURRENT_SRC_ADDR 0x438 +#define AXI_DMAC_REG_DBG0 0x43c +#define AXI_DMAC_REG_DBG1 0x440 + +#define AXI_DMAC_CTRL_ENABLE (1 << 0) +#define AXI_DMAC_CTRL_PAUSE (1 << 1) + +#define AXI_DMAC_IRQ_SOT (1 << 0) +#define AXI_DMAC_IRQ_EOT (1 << 1) + +struct dds_state +{ + uint32_t cached_freq[8]; + uint32_t cached_phase[8]; + int32_t cached_scale[8]; + uint32_t *dac_clk; + uint32_t pcore_version; + uint32_t num_dds_channels; + bool enable; + bool rx2tx2; +}; + +#define DAC_REG_CHAN_CNTRL_6(c) (0x0414 + (c) * 0x40) +#define DAC_IQCOR_ENB (1 << 2) /* v8.0 */ + +#define DAC_REG_CHAN_CNTRL_7(c) (0x0418 + (c) * 0x40) /* v8.0 */ +#define DAC_DAC_DDS_SEL(x) (((x) & 0xF) << 0) +#define DAC_TO_DAC_DDS_SEL(x) (((x) >> 0) & 0xF) + +#define DAC_REG_CHAN_CNTRL_8(c) (0x041C + (c) * 0x40) /* v8.0 */ +#define DAC_IQCOR_COEFF_1(x) (((x) & 0xFFFF) << 16) +#define DAC_TO_IQCOR_COEFF_1(x) (((x) >> 16) & 0xFFFF) +#define DAC_IQCOR_COEFF_2(x) (((x) & 0xFFFF) << 0) +#define DAC_TO_IQCOR_COEFF_2(x) (((x) >> 0) & 0xFFFF) + +/******************************************************************************/ +/************************ Functions Declarations ******************************/ +/******************************************************************************/ + +int dac_init(struct ad9361_rf_phy *phy, uint8_t data_sel, uint8_t config_dma); +int dds_set_frequency(struct ad9361_rf_phy *phy, uint32_t chan, uint32_t freq); +int dds_set_phase(struct ad9361_rf_phy *phy, uint32_t chan, uint32_t phase); +int dds_set_scale(struct ad9361_rf_phy *phy, uint32_t chan, int32_t scale_micro_units); +int dds_update(struct ad9361_rf_phy *phy); +int dac_datasel(struct ad9361_rf_phy *phy, int32_t chan, enum dds_data_select sel); +int32_t dds_set_calib_scale(struct ad9361_rf_phy *phy, + uint32_t chan, + int32_t val, + int32_t val2); +int32_t dds_get_calib_scale(struct ad9361_rf_phy *phy, + uint32_t chan, + int32_t *val, + int32_t *val2); +int32_t dds_set_calib_phase(struct ad9361_rf_phy *phy, + uint32_t chan, + int32_t val, + int32_t val2); +int32_t dds_get_calib_phase(struct ad9361_rf_phy *phy, + uint32_t chan, + int32_t *val, + int32_t *val2); +#endif diff --git a/Radio/HW/BladeRF/thirdparty/analogdevicesinc/no-OS_local/platform_bladerf2/platform.c b/Radio/HW/BladeRF/thirdparty/analogdevicesinc/no-OS_local/platform_bladerf2/platform.c new file mode 100644 index 0000000..3d09c9f --- /dev/null +++ b/Radio/HW/BladeRF/thirdparty/analogdevicesinc/no-OS_local/platform_bladerf2/platform.c @@ -0,0 +1,295 @@ +#include <stdint.h> + +#include "board/board.h" + +#include "platform.h" + +#include "adc_core.h" +#include "dac_core.h" + +/***************************************************************************//** + * @brief spi_init +*******************************************************************************/ + +int spi_init(struct ad9361_rf_phy *phy, void *userdata) +{ + phy->spi->userdata = userdata; + return 0; +} + +/***************************************************************************//** + * @brief spi_write +*******************************************************************************/ + +int spi_write(struct spi_device *spi, uint16_t cmd, const uint8_t *buf, + unsigned int len) +{ + struct bladerf *dev = spi->userdata; + int status; + uint64_t data; + unsigned int i; + + /* Copy buf to data */ + data = 0; + for (i = 0; i < len; i++) { + data |= (((uint64_t)buf[i]) << 8*(7-i)); + } + + /* SPI transaction */ + status = dev->backend->ad9361_spi_write(dev, cmd, data); + if (status < 0) { + return -EIO; + } + + return 0; +} + +/***************************************************************************//** + * @brief spi_read +*******************************************************************************/ + +#include <inttypes.h> + +int spi_read(struct spi_device *spi, uint16_t cmd, uint8_t *buf, + unsigned int len) +{ + struct bladerf *dev = spi->userdata; + int status; + uint64_t data = 0; + unsigned int i; + + /* SPI transaction */ + status = dev->backend->ad9361_spi_read(dev, cmd, &data); + if (status < 0) { + return -EIO; + } + + /* Copy data to buf */ + for (i = 0; i < len; i++) { + buf[i] = (data >> 8*(7-i)) & 0xff; + } + + return 0; +} + +/***************************************************************************//** + * @brief gpio_init +*******************************************************************************/ + +int gpio_init(struct ad9361_rf_phy *phy, void *userdata) +{ + phy->gpio->userdata = userdata; + return 0; +} + +/***************************************************************************//** + * @brief gpio_is_valid +*******************************************************************************/ + +bool gpio_is_valid(struct gpio_device *gpio, int32_t number) +{ + if (number == RFFE_CONTROL_RESET_N) { + return true; + } else if (number == RFFE_CONTROL_SYNC_IN) { + return true; + } + + return false; +} + +/***************************************************************************//** + * @brief gpio_set_value +*******************************************************************************/ + +int gpio_set_value(struct gpio_device *gpio, int32_t number, bool value) +{ + struct bladerf *dev = gpio->userdata; + int status; + uint32_t reg; + + /* Read */ + status = dev->backend->rffe_control_read(dev, ®); + if (status < 0) { + return -EIO; + } + + /* Modify */ + if (value) { + reg |= (1 << number); + } else { + reg &= ~(1 << number); + } + + /* Write */ + status = dev->backend->rffe_control_write(dev, reg); + if (status < 0) { + return -EIO; + } + + return 0; +} + +/***************************************************************************//** + * @brief udelay +*******************************************************************************/ + +void udelay(unsigned long usecs) +{ + usleep(usecs); +} + +/***************************************************************************//** + * @brief mdelay +*******************************************************************************/ + +void mdelay(unsigned long msecs) +{ + usleep(msecs * 1000); +} + +/***************************************************************************//** + * @brief msleep_interruptible +*******************************************************************************/ + +unsigned long msleep_interruptible(unsigned int msecs) +{ + usleep(msecs * 1000); + return 0; +} + +/***************************************************************************//** + * @brief axiadc_init +*******************************************************************************/ + +int axiadc_init(struct ad9361_rf_phy *phy, void *userdata) +{ + int status; + + phy->adc_state->userdata = userdata; + + status = adc_init(phy); + if (status < 0) { + return status; + } + + status = dac_init(phy, DATA_SEL_DMA, 0); + if (status < 0) { + return status; + } + + return 0; +} + +/***************************************************************************//** + * @brief axiadc_post_setup +*******************************************************************************/ + +int axiadc_post_setup(struct ad9361_rf_phy *phy) +{ + return ad9361_post_setup(phy); +} + +/***************************************************************************//** + * @brief axiadc_read +*******************************************************************************/ + +int axiadc_read(struct axiadc_state *st, uint32_t addr, uint32_t *data) +{ + struct bladerf *dev = st->userdata; + int status; + + /* Read */ + status = dev->backend->adi_axi_read(dev, addr, data); + if (status < 0) { + return -EIO; + } + + return 0; +} + +/***************************************************************************//** + * @brief axiadc_write +*******************************************************************************/ + +int axiadc_write(struct axiadc_state *st, uint32_t addr, uint32_t data) +{ + struct bladerf *dev = st->userdata; + int status; + + /* Write */ + status = dev->backend->adi_axi_write(dev, addr, data); + if (status < 0) { + return -EIO; + } + + return 0; +} + +/***************************************************************************//** + * @brief axiadc_set_pnsel +*******************************************************************************/ + +int axiadc_set_pnsel(struct axiadc_state *st, unsigned int channel, enum adc_pn_sel sel) +{ + int status; + uint32_t reg; + + if (PCORE_VERSION_MAJOR(st->pcore_version) > 7) { + status = axiadc_read(st, ADI_REG_CHAN_CNTRL_3(channel), ®); + if (status != 0) + return status; + + reg &= ~ADI_ADC_PN_SEL(~0); + reg |= ADI_ADC_PN_SEL(sel); + + status = axiadc_write(st, ADI_REG_CHAN_CNTRL_3(channel), reg); + if (status != 0) + return status; + } else { + status = axiadc_read(st, ADI_REG_CHAN_CNTRL(channel), ®); + if (status != 0) + return status; + + if (sel == ADC_PN_CUSTOM) { + reg |= ADI_PN_SEL; + } else if (sel == ADC_PN9) { + reg &= ~ADI_PN23_TYPE; + reg &= ~ADI_PN_SEL; + } else { + reg |= ADI_PN23_TYPE; + reg &= ~ADI_PN_SEL; + } + + status = axiadc_write(st, ADI_REG_CHAN_CNTRL(channel), reg); + if (status != 0) + return status; + } + + return 0; +} + +/***************************************************************************//** + * @brief axiadc_idelay_set +*******************************************************************************/ + +int axiadc_idelay_set(struct axiadc_state *st, unsigned int lane, unsigned int val) +{ + int status; + + if (PCORE_VERSION_MAJOR(st->pcore_version) > 8) { + status = axiadc_write(st, ADI_REG_DELAY(lane), val); + if (status != 0) + return status; + } else { + status = axiadc_write(st, ADI_REG_DELAY_CNTRL, 0); + if (status != 0) + return status; + + status = axiadc_write(st, ADI_REG_DELAY_CNTRL, + ADI_DELAY_ADDRESS(lane) | ADI_DELAY_WDATA(val) | ADI_DELAY_SEL); + if (status != 0) + return status; + } + + return 0; +} diff --git a/Radio/HW/BladeRF/thirdparty/analogdevicesinc/no-OS_local/platform_bladerf2/platform.h b/Radio/HW/BladeRF/thirdparty/analogdevicesinc/no-OS_local/platform_bladerf2/platform.h new file mode 100644 index 0000000..badbc65 --- /dev/null +++ b/Radio/HW/BladeRF/thirdparty/analogdevicesinc/no-OS_local/platform_bladerf2/platform.h @@ -0,0 +1,169 @@ +/***************************************************************************//** + * @file platform.h + * @brief Header file of Platform driver. + * @author DBogdan (dragos.bogdan@analog.com) +******************************************************************************** + * Copyright 2014(c) Analog Devices, Inc. + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * - Neither the name of Analog Devices, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * - The use of this software may or may not infringe the patent rights + * of one or more patent holders. This license does not release you + * from the requirement that you obtain separate licenses from these + * patent holders to use this software. + * - Use of the software either in source or binary form, must be run + * on or directly connected to an Analog Devices Inc. component. + * + * THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT, + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, INTELLECTUAL PROPERTY RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*******************************************************************************/ +#ifndef PLATFORM_H_ +#define PLATFORM_H_ + +/******************************************************************************/ +/***************************** Include Files **********************************/ +/******************************************************************************/ + +#include "stdint.h" +#include "util.h" +#include "config.h" + +/******************************************************************************/ +/********************** Macros and Constants Definitions **********************/ +/******************************************************************************/ +#define ADI_REG_VERSION 0x0000 + +#define ADI_REG_ID 0x0004 + +#define ADI_REG_RSTN 0x0040 +#define ADI_RSTN (1 << 0) +#define ADI_MMCM_RSTN (1 << 1) + +#define ADI_REG_CNTRL 0x0044 +#define ADI_R1_MODE (1 << 2) +#define ADI_DDR_EDGESEL (1 << 1) +#define ADI_PIN_MODE (1 << 0) + +#define ADI_REG_STATUS 0x005C +#define ADI_MUX_PN_ERR (1 << 3) +#define ADI_MUX_PN_OOS (1 << 2) +#define ADI_MUX_OVER_RANGE (1 << 1) +#define ADI_STATUS (1 << 0) + +#define ADI_REG_DELAY_CNTRL 0x0060 /* <= v8.0 */ +#define ADI_DELAY_SEL (1 << 17) +#define ADI_DELAY_RWN (1 << 16) +#define ADI_DELAY_ADDRESS(x) (((x) & 0xFF) << 8) +#define ADI_TO_DELAY_ADDRESS(x) (((x) >> 8) & 0xFF) +#define ADI_DELAY_WDATA(x) (((x) & 0x1F) << 0) +#define ADI_TO_DELAY_WDATA(x) (((x) >> 0) & 0x1F) + +#define ADI_REG_CHAN_CNTRL(c) (0x0400 + (c) * 0x40) +#define ADI_PN_SEL (1 << 10) /* !v8.0 */ +#define ADI_IQCOR_ENB (1 << 9) +#define ADI_DCFILT_ENB (1 << 8) +#define ADI_FORMAT_SIGNEXT (1 << 6) +#define ADI_FORMAT_TYPE (1 << 5) +#define ADI_FORMAT_ENABLE (1 << 4) +#define ADI_PN23_TYPE (1 << 1) /* !v8.0 */ +#define ADI_ENABLE (1 << 0) + +#define ADI_REG_CHAN_STATUS(c) (0x0404 + (c) * 0x40) +#define ADI_PN_ERR (1 << 2) +#define ADI_PN_OOS (1 << 1) +#define ADI_OVER_RANGE (1 << 0) + +#define ADI_REG_CHAN_CNTRL_1(c) (0x0410 + (c) * 0x40) +#define ADI_DCFILT_OFFSET(x) (((x) & 0xFFFF) << 16) +#define ADI_TO_DCFILT_OFFSET(x) (((x) >> 16) & 0xFFFF) +#define ADI_DCFILT_COEFF(x) (((x) & 0xFFFF) << 0) +#define ADI_TO_DCFILT_COEFF(x) (((x) >> 0) & 0xFFFF) + +#define ADI_REG_CHAN_CNTRL_2(c) (0x0414 + (c) * 0x40) +#define ADI_IQCOR_COEFF_1(x) (((x) & 0xFFFF) << 16) +#define ADI_TO_IQCOR_COEFF_1(x) (((x) >> 16) & 0xFFFF) +#define ADI_IQCOR_COEFF_2(x) (((x) & 0xFFFF) << 0) +#define ADI_TO_IQCOR_COEFF_2(x) (((x) >> 0) & 0xFFFF) + +#define PCORE_VERSION(major, minor, letter) ((major << 16) | (minor << 8) | letter) +#define PCORE_VERSION_MAJOR(version) (version >> 16) +#define PCORE_VERSION_MINOR(version) ((version >> 8) & 0xff) +#define PCORE_VERSION_LETTER(version) (version & 0xff) + +#define ADI_REG_CHAN_CNTRL_3(c) (0x0418 + (c) * 0x40) /* v8.0 */ +#define ADI_ADC_PN_SEL(x) (((x) & 0xF) << 16) +#define ADI_TO_ADC_PN_SEL(x) (((x) >> 16) & 0xF) +#define ADI_ADC_DATA_SEL(x) (((x) & 0xF) << 0) +#define ADI_TO_ADC_DATA_SEL(x) (((x) >> 0) & 0xF) + +/* PCORE Version > 8.00 */ +#define ADI_REG_DELAY(l) (0x0800 + (l) * 0x4) + +enum adc_pn_sel { + ADC_PN9 = 0, + ADC_PN23A = 1, + ADC_PN7 = 4, + ADC_PN15 = 5, + ADC_PN23 = 6, + ADC_PN31 = 7, + ADC_PN_CUSTOM = 9, + ADC_PN_END = 10, +}; + +enum adc_data_sel { + ADC_DATA_SEL_NORM, + ADC_DATA_SEL_LB, /* DAC loopback */ + ADC_DATA_SEL_RAMP, /* TBD */ +}; + +/* Bitwise positions of GPOs in RFFE control register */ +#define RFFE_CONTROL_RESET_N 0 +#define RFFE_CONTROL_SYNC_IN 4 + +/******************************************************************************/ +/************************ Functions Declarations ******************************/ +/******************************************************************************/ + +int spi_init(struct ad9361_rf_phy *phy, void *userdata); +int spi_write(struct spi_device *spi, uint16_t cmd, const uint8_t *buf, + unsigned int len); +int spi_read(struct spi_device *spi, uint16_t cmd, uint8_t *buf, + unsigned int len); + +int gpio_init(struct ad9361_rf_phy *phy, void *userdata); +bool gpio_is_valid(struct gpio_device *gpio, int32_t number); +int gpio_set_value(struct gpio_device *gpio, int32_t number, bool value); + +void udelay(unsigned long usecs); +void mdelay(unsigned long msecs); +unsigned long msleep_interruptible(unsigned int msecs); + +#ifndef AXI_ADC_NOT_PRESENT +int axiadc_init(struct ad9361_rf_phy *phy, void *userdata); +int axiadc_post_setup(struct ad9361_rf_phy *phy); +int axiadc_read(struct axiadc_state *st, uint32_t addr, uint32_t *data); +int axiadc_write(struct axiadc_state *st, uint32_t addr, uint32_t data); +int axiadc_set_pnsel(struct axiadc_state *st, unsigned int channel, enum adc_pn_sel sel); +int axiadc_idelay_set(struct axiadc_state *st, unsigned int lane, unsigned int val); +#endif + +#endif |