Igor Stepura / kw41z-rf-driver Featured

ARM mbed Nanostack RF driver for NXP KW41Z 802.15.4 wireless MCU

This driver is used with 6LoWPAN stack.

Code far from being stable yet, but basic functionality seems to be working. Two FRDM-KW41Z boards running code build from mbed-os-example-mesh-minimal and nanostack-border-router are able to build mesh.

Main repository is at https://github.com/istepura/kw41z-rf-driver

Committer:
igor Stepura
Date:
Thu Jul 20 13:06:20 2017 -0400
Revision:
0:bb6687c3a462
Initial commit

Who changed what in which revision?

UserRevisionLine numberNew contents of line
igor Stepura 0:bb6687c3a462 1 /*
igor Stepura 0:bb6687c3a462 2 * Copyright 2016-2017 NXP
igor Stepura 0:bb6687c3a462 3 *
igor Stepura 0:bb6687c3a462 4 * Redistribution and use in source and binary forms, with or without modification,
igor Stepura 0:bb6687c3a462 5 * are permitted provided that the following conditions are met:
igor Stepura 0:bb6687c3a462 6 *
igor Stepura 0:bb6687c3a462 7 * o Redistributions of source code must retain the above copyright notice, this list
igor Stepura 0:bb6687c3a462 8 * of conditions and the following disclaimer.
igor Stepura 0:bb6687c3a462 9 *
igor Stepura 0:bb6687c3a462 10 * o Redistributions in binary form must reproduce the above copyright notice, this
igor Stepura 0:bb6687c3a462 11 * list of conditions and the following disclaimer in the documentation and/or
igor Stepura 0:bb6687c3a462 12 * other materials provided with the distribution.
igor Stepura 0:bb6687c3a462 13 *
igor Stepura 0:bb6687c3a462 14 * o Neither the name of Freescale Semiconductor, Inc. nor the names of its
igor Stepura 0:bb6687c3a462 15 * contributors may be used to endorse or promote products derived from this
igor Stepura 0:bb6687c3a462 16 * software without specific prior written permission.
igor Stepura 0:bb6687c3a462 17 *
igor Stepura 0:bb6687c3a462 18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
igor Stepura 0:bb6687c3a462 19 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
igor Stepura 0:bb6687c3a462 20 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
igor Stepura 0:bb6687c3a462 21 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
igor Stepura 0:bb6687c3a462 22 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
igor Stepura 0:bb6687c3a462 23 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
igor Stepura 0:bb6687c3a462 24 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
igor Stepura 0:bb6687c3a462 25 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
igor Stepura 0:bb6687c3a462 26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
igor Stepura 0:bb6687c3a462 27 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
igor Stepura 0:bb6687c3a462 28 */
igor Stepura 0:bb6687c3a462 29
igor Stepura 0:bb6687c3a462 30 #include "fsl_device_registers.h"
igor Stepura 0:bb6687c3a462 31 #include "fsl_common.h"
igor Stepura 0:bb6687c3a462 32 #include "fsl_xcvr.h"
igor Stepura 0:bb6687c3a462 33 #include "fsl_xcvr_trim.h"
igor Stepura 0:bb6687c3a462 34 #include "dbg_ram_capture.h"
igor Stepura 0:bb6687c3a462 35 #include "math.h"
igor Stepura 0:bb6687c3a462 36
igor Stepura 0:bb6687c3a462 37 /*******************************************************************************
igor Stepura 0:bb6687c3a462 38 * Definitions
igor Stepura 0:bb6687c3a462 39 ******************************************************************************/
igor Stepura 0:bb6687c3a462 40
igor Stepura 0:bb6687c3a462 41
igor Stepura 0:bb6687c3a462 42 /*******************************************************************************
igor Stepura 0:bb6687c3a462 43 * Prototypes
igor Stepura 0:bb6687c3a462 44 ******************************************************************************/
igor Stepura 0:bb6687c3a462 45 void DC_Measure_short(IQ_t chan, DAC_SWEEP_STEP2_t dcoc_init_val);
igor Stepura 0:bb6687c3a462 46 float calc_dcoc_dac_step(GAIN_CALC_TBL_ENTRY2_T * meas_ptr, GAIN_CALC_TBL_ENTRY2_T * baseline_meas_ptr );
igor Stepura 0:bb6687c3a462 47 extern float roundf (float);
igor Stepura 0:bb6687c3a462 48
igor Stepura 0:bb6687c3a462 49 /*******************************************************************************
igor Stepura 0:bb6687c3a462 50 * Variables
igor Stepura 0:bb6687c3a462 51 ******************************************************************************/
igor Stepura 0:bb6687c3a462 52 const int8_t TsettleCal = 10;
igor Stepura 0:bb6687c3a462 53 static GAIN_CALC_TBL_ENTRY2_T measurement_tbl2[NUM_I_Q_CHAN][NUM_SWEEP_STEP_ENTRIES2];
igor Stepura 0:bb6687c3a462 54 static const int8_t sweep_step_values2[NUM_SWEEP_STEP_ENTRIES2] =
igor Stepura 0:bb6687c3a462 55 {
igor Stepura 0:bb6687c3a462 56 0, /* Baseline entry is first and not used in this table */
igor Stepura 0:bb6687c3a462 57 -16,
igor Stepura 0:bb6687c3a462 58 +16,
igor Stepura 0:bb6687c3a462 59 -4,
igor Stepura 0:bb6687c3a462 60 -4,
igor Stepura 0:bb6687c3a462 61 -4,
igor Stepura 0:bb6687c3a462 62 -4,
igor Stepura 0:bb6687c3a462 63 -4,
igor Stepura 0:bb6687c3a462 64 -4,
igor Stepura 0:bb6687c3a462 65 -4,
igor Stepura 0:bb6687c3a462 66 -4,
igor Stepura 0:bb6687c3a462 67 -4,
igor Stepura 0:bb6687c3a462 68 -4,
igor Stepura 0:bb6687c3a462 69 -4,
igor Stepura 0:bb6687c3a462 70 +4,
igor Stepura 0:bb6687c3a462 71 +4,
igor Stepura 0:bb6687c3a462 72 +4,
igor Stepura 0:bb6687c3a462 73 +4,
igor Stepura 0:bb6687c3a462 74 +4,
igor Stepura 0:bb6687c3a462 75 +4,
igor Stepura 0:bb6687c3a462 76 +4,
igor Stepura 0:bb6687c3a462 77 +4,
igor Stepura 0:bb6687c3a462 78 +4,
igor Stepura 0:bb6687c3a462 79 +4,
igor Stepura 0:bb6687c3a462 80 +4
igor Stepura 0:bb6687c3a462 81 };
igor Stepura 0:bb6687c3a462 82
igor Stepura 0:bb6687c3a462 83 /*******************************************************************************
igor Stepura 0:bb6687c3a462 84 * Macros
igor Stepura 0:bb6687c3a462 85 ******************************************************************************/
igor Stepura 0:bb6687c3a462 86 #define ISIGN(x) !((uint16_t)x & 0x8000)
igor Stepura 0:bb6687c3a462 87 #define ABS(x) ((x) > 0 ? (x) : -(x))
igor Stepura 0:bb6687c3a462 88
igor Stepura 0:bb6687c3a462 89 /*******************************************************************************
igor Stepura 0:bb6687c3a462 90 * Code
igor Stepura 0:bb6687c3a462 91 ******************************************************************************/
igor Stepura 0:bb6687c3a462 92 /*! *********************************************************************************
igor Stepura 0:bb6687c3a462 93 * \brief This function performs a trim of the BBA DCOC DAC on the DUT
igor Stepura 0:bb6687c3a462 94 *
igor Stepura 0:bb6687c3a462 95 * \return status - 1 if passed, 0 if failed.
igor Stepura 0:bb6687c3a462 96 *
igor Stepura 0:bb6687c3a462 97 * \ingroup PublicAPIs
igor Stepura 0:bb6687c3a462 98 *
igor Stepura 0:bb6687c3a462 99 * \details
igor Stepura 0:bb6687c3a462 100 * Requires the RX to be warmed up before this function is called.
igor Stepura 0:bb6687c3a462 101 *
igor Stepura 0:bb6687c3a462 102 ***********************************************************************************/
igor Stepura 0:bb6687c3a462 103 uint8_t rx_bba_dcoc_dac_trim_shortIQ(void)
igor Stepura 0:bb6687c3a462 104 {
igor Stepura 0:bb6687c3a462 105 uint8_t i;
igor Stepura 0:bb6687c3a462 106 float temp_mi = 0;
igor Stepura 0:bb6687c3a462 107 float temp_mq = 0;
igor Stepura 0:bb6687c3a462 108 float temp_pi = 0;
igor Stepura 0:bb6687c3a462 109 float temp_pq = 0;
igor Stepura 0:bb6687c3a462 110 float temp_step = 0;
igor Stepura 0:bb6687c3a462 111 uint8_t bbf_dacinit_i, bbf_dacinit_q;
igor Stepura 0:bb6687c3a462 112
igor Stepura 0:bb6687c3a462 113 uint32_t dcoc_init_reg_value_dcgain = 0x80802020; /* Used in 2nd & 3rd Generation DCOC Trims only. */
igor Stepura 0:bb6687c3a462 114 uint32_t bbf_dcoc_step;
igor Stepura 0:bb6687c3a462 115 uint32_t bbf_dcoc_step_rcp;
igor Stepura 0:bb6687c3a462 116 TZAdcocstep_t tza_dcoc_step[11];
igor Stepura 0:bb6687c3a462 117 uint8_t status = 0;
igor Stepura 0:bb6687c3a462 118
igor Stepura 0:bb6687c3a462 119 /* Save register values. */
igor Stepura 0:bb6687c3a462 120 uint32_t dcoc_ctrl_0_stack;
igor Stepura 0:bb6687c3a462 121 uint32_t dcoc_ctrl_1_stack;
igor Stepura 0:bb6687c3a462 122 uint32_t agc_ctrl_1_stack;
igor Stepura 0:bb6687c3a462 123 uint32_t rx_dig_ctrl_stack;
igor Stepura 0:bb6687c3a462 124 uint32_t dcoc_cal_gain_state;
igor Stepura 0:bb6687c3a462 125
igor Stepura 0:bb6687c3a462 126 XcvrCalDelay(1000);
igor Stepura 0:bb6687c3a462 127 dcoc_ctrl_0_stack = XCVR_RX_DIG->DCOC_CTRL_0; /* Save state of DCOC_CTRL_0 for later restore. */
igor Stepura 0:bb6687c3a462 128 dcoc_ctrl_1_stack = XCVR_RX_DIG->DCOC_CTRL_1; /* Save state of DCOC_CTRL_1 for later restore. */
igor Stepura 0:bb6687c3a462 129 rx_dig_ctrl_stack = XCVR_RX_DIG->RX_DIG_CTRL; /* Save state of RX_DIG_CTRL for later restore. */
igor Stepura 0:bb6687c3a462 130 agc_ctrl_1_stack = XCVR_RX_DIG->AGC_CTRL_1; /* Save state of RX_DIG_CTRL for later restore. */
igor Stepura 0:bb6687c3a462 131 dcoc_cal_gain_state = XCVR_RX_DIG->DCOC_CAL_GAIN; /* Save state of DCOC_CAL_GAIN for later restore. */
igor Stepura 0:bb6687c3a462 132
igor Stepura 0:bb6687c3a462 133 /* Ensure AGC, DCOC and RX_DIG_CTRL is in correct mode. */
igor Stepura 0:bb6687c3a462 134 XCVR_RX_DIG->RX_DIG_CTRL = (XCVR_RX_DIG->RX_DIG_CTRL & ~XCVR_RX_DIG_RX_DIG_CTRL_RX_AGC_EN_MASK) | XCVR_RX_DIG_RX_DIG_CTRL_RX_AGC_EN(0); /* Turn OFF AGC */
igor Stepura 0:bb6687c3a462 135
igor Stepura 0:bb6687c3a462 136 XCVR_RX_DIG->AGC_CTRL_1 = (XCVR_RX_DIG->AGC_CTRL_1 & ~XCVR_RX_DIG_AGC_CTRL_1_USER_LNA_GAIN_EN_MASK) | XCVR_RX_DIG_AGC_CTRL_1_USER_LNA_GAIN_EN(1) ; /* Set LNA Manual Gain */
igor Stepura 0:bb6687c3a462 137 XCVR_RX_DIG->AGC_CTRL_1 = (XCVR_RX_DIG->AGC_CTRL_1 & ~XCVR_RX_DIG_AGC_CTRL_1_USER_BBA_GAIN_EN_MASK) | XCVR_RX_DIG_AGC_CTRL_1_USER_BBA_GAIN_EN(1) ; /* Set BBA Manual Gain */
igor Stepura 0:bb6687c3a462 138
igor Stepura 0:bb6687c3a462 139 XCVR_RX_DIG->RX_DIG_CTRL = (XCVR_RX_DIG->RX_DIG_CTRL & ~XCVR_RX_DIG_RX_DIG_CTRL_RX_DCOC_CAL_EN_MASK) | XCVR_RX_DIG_RX_DIG_CTRL_RX_DCOC_CAL_EN(0); /* Enable HW DC Calibration -- Disable for SW-DCOC */
igor Stepura 0:bb6687c3a462 140 XCVR_RX_DIG->DCOC_CTRL_0 = (XCVR_RX_DIG->DCOC_CTRL_0 & ~XCVR_RX_DIG_DCOC_CTRL_0_DCOC_MAN_MASK) | XCVR_RX_DIG_DCOC_CTRL_0_DCOC_MAN(1); /* Enable Manual DCOC */
igor Stepura 0:bb6687c3a462 141 /* DCOC_CTRL_0 @ 4005_C02C -- Define default DCOC DAC settings in manual mode. */
igor Stepura 0:bb6687c3a462 142 XCVR_RX_DIG->DCOC_DAC_INIT = XCVR_RX_DIG_DCOC_DAC_INIT_BBA_DCOC_INIT_I(0x20) | XCVR_RX_DIG_DCOC_DAC_INIT_BBA_DCOC_INIT_Q(0x20) | XCVR_RX_DIG_DCOC_DAC_INIT_TZA_DCOC_INIT_I(0x80) | XCVR_RX_DIG_DCOC_DAC_INIT_TZA_DCOC_INIT_Q(0x80);
igor Stepura 0:bb6687c3a462 143 /* Set DCOC Tracking State. */
igor Stepura 0:bb6687c3a462 144 XCVR_RX_DIG->DCOC_CTRL_0 = (XCVR_RX_DIG->DCOC_CTRL_0 & ~XCVR_RX_DIG_DCOC_CTRL_0_DCOC_CORRECT_SRC_MASK) | XCVR_RX_DIG_DCOC_CTRL_0_DCOC_CORRECT_SRC(0); /* Disables DCOC Tracking when set to 0 */
igor Stepura 0:bb6687c3a462 145 /* Apply Manual Gain. */
igor Stepura 0:bb6687c3a462 146 XCVR_RX_DIG->AGC_CTRL_1 = XCVR_RX_DIG_AGC_CTRL_1_USER_LNA_GAIN_EN(1) | XCVR_RX_DIG_AGC_CTRL_1_USER_BBA_GAIN_EN(1) | XCVR_RX_DIG_AGC_CTRL_1_LNA_USER_GAIN(0x02) | XCVR_RX_DIG_AGC_CTRL_1_BBA_USER_GAIN(0x00) ;
igor Stepura 0:bb6687c3a462 147 XcvrCalDelay(TsettleCal);
igor Stepura 0:bb6687c3a462 148
igor Stepura 0:bb6687c3a462 149 dcoc_init_reg_value_dcgain = XCVR_RX_DIG->DCOC_DAC_INIT; /* Capture DC null setting. */
igor Stepura 0:bb6687c3a462 150
igor Stepura 0:bb6687c3a462 151 bbf_dacinit_i = (dcoc_init_reg_value_dcgain & 0x000000FFU);
igor Stepura 0:bb6687c3a462 152 bbf_dacinit_q = (dcoc_init_reg_value_dcgain & 0x0000FF00U) >> 8;
igor Stepura 0:bb6687c3a462 153
igor Stepura 0:bb6687c3a462 154 DC_Measure_short(I_CHANNEL, NOMINAL2);
igor Stepura 0:bb6687c3a462 155 DC_Measure_short(Q_CHANNEL, NOMINAL2);
igor Stepura 0:bb6687c3a462 156
igor Stepura 0:bb6687c3a462 157 /* SWEEP Q CHANNEL */
igor Stepura 0:bb6687c3a462 158 /* BBF NEG STEP */
igor Stepura 0:bb6687c3a462 159 XCVR_RX_DIG->DCOC_DAC_INIT = (XCVR_RX_DIG->DCOC_DAC_INIT & ~XCVR_RX_DIG_DCOC_DAC_INIT_BBA_DCOC_INIT_Q_MASK) | XCVR_RX_DIG_DCOC_DAC_INIT_BBA_DCOC_INIT_Q(bbf_dacinit_q - 16);
igor Stepura 0:bb6687c3a462 160 XcvrCalDelay(TsettleCal);
igor Stepura 0:bb6687c3a462 161 DC_Measure_short(Q_CHANNEL, BBF_NEG);
igor Stepura 0:bb6687c3a462 162
igor Stepura 0:bb6687c3a462 163 /* BBF POS STEP */
igor Stepura 0:bb6687c3a462 164 XCVR_RX_DIG->DCOC_DAC_INIT = (XCVR_RX_DIG->DCOC_DAC_INIT & ~XCVR_RX_DIG_DCOC_DAC_INIT_BBA_DCOC_INIT_Q_MASK) | XCVR_RX_DIG_DCOC_DAC_INIT_BBA_DCOC_INIT_Q(bbf_dacinit_q + 16);
igor Stepura 0:bb6687c3a462 165 XcvrCalDelay(TsettleCal);
igor Stepura 0:bb6687c3a462 166 DC_Measure_short(Q_CHANNEL, BBF_POS);
igor Stepura 0:bb6687c3a462 167
igor Stepura 0:bb6687c3a462 168 XCVR_RX_DIG->DCOC_DAC_INIT = dcoc_init_reg_value_dcgain; /* Return DAC setting to initial. */
igor Stepura 0:bb6687c3a462 169 XcvrCalDelay(TsettleCal);
igor Stepura 0:bb6687c3a462 170
igor Stepura 0:bb6687c3a462 171 /* SWEEP I CHANNEL */
igor Stepura 0:bb6687c3a462 172 /* BBF NEG STEP */
igor Stepura 0:bb6687c3a462 173 XCVR_RX_DIG->DCOC_DAC_INIT = (XCVR_RX_DIG->DCOC_DAC_INIT & ~XCVR_RX_DIG_DCOC_DAC_INIT_BBA_DCOC_INIT_I_MASK) | XCVR_RX_DIG_DCOC_DAC_INIT_BBA_DCOC_INIT_I(bbf_dacinit_i - 16);
igor Stepura 0:bb6687c3a462 174 XcvrCalDelay(TsettleCal);
igor Stepura 0:bb6687c3a462 175 DC_Measure_short(I_CHANNEL, BBF_NEG);
igor Stepura 0:bb6687c3a462 176 /* BBF POS STEP */
igor Stepura 0:bb6687c3a462 177 XCVR_RX_DIG->DCOC_DAC_INIT = (XCVR_RX_DIG->DCOC_DAC_INIT & ~XCVR_RX_DIG_DCOC_DAC_INIT_BBA_DCOC_INIT_I_MASK) | XCVR_RX_DIG_DCOC_DAC_INIT_BBA_DCOC_INIT_I(bbf_dacinit_i + 16);
igor Stepura 0:bb6687c3a462 178 XcvrCalDelay(TsettleCal);
igor Stepura 0:bb6687c3a462 179 DC_Measure_short(I_CHANNEL, BBF_POS);
igor Stepura 0:bb6687c3a462 180
igor Stepura 0:bb6687c3a462 181 XCVR_RX_DIG->DCOC_DAC_INIT = dcoc_init_reg_value_dcgain; /* Return DACs to initial. */
igor Stepura 0:bb6687c3a462 182 XcvrCalDelay(TsettleCal);
igor Stepura 0:bb6687c3a462 183
igor Stepura 0:bb6687c3a462 184 /* Calculate BBF DCOC STEPS, RECIPROCALS */
igor Stepura 0:bb6687c3a462 185 temp_mi = calc_dcoc_dac_step(&measurement_tbl2[I_CHANNEL][BBF_NEG], &measurement_tbl2[I_CHANNEL][NOMINAL2]);
igor Stepura 0:bb6687c3a462 186 temp_mq = calc_dcoc_dac_step(&measurement_tbl2[Q_CHANNEL][BBF_NEG], &measurement_tbl2[Q_CHANNEL][NOMINAL2]);
igor Stepura 0:bb6687c3a462 187 temp_pi = calc_dcoc_dac_step(&measurement_tbl2[I_CHANNEL][BBF_POS], &measurement_tbl2[I_CHANNEL][NOMINAL2]);
igor Stepura 0:bb6687c3a462 188 temp_pq = calc_dcoc_dac_step(&measurement_tbl2[Q_CHANNEL][BBF_POS], &measurement_tbl2[Q_CHANNEL][NOMINAL2]);
igor Stepura 0:bb6687c3a462 189
igor Stepura 0:bb6687c3a462 190 temp_step = (temp_mi+temp_pi + temp_mq+temp_pq) / 4;
igor Stepura 0:bb6687c3a462 191
igor Stepura 0:bb6687c3a462 192 bbf_dcoc_step = (uint32_t)roundf(temp_step * 8U);
igor Stepura 0:bb6687c3a462 193
igor Stepura 0:bb6687c3a462 194 if ((bbf_dcoc_step > 265) & (bbf_dcoc_step < 305))
igor Stepura 0:bb6687c3a462 195 {
igor Stepura 0:bb6687c3a462 196 bbf_dcoc_step_rcp = (uint32_t)roundf((float)0x8000U / temp_step);
igor Stepura 0:bb6687c3a462 197
igor Stepura 0:bb6687c3a462 198 /* Calculate TZA DCOC STEPS & RECIPROCALS and IQ_DC_GAIN_MISMATCH. */
igor Stepura 0:bb6687c3a462 199 for (i = TZA_STEP_N0; i <= TZA_STEP_N10; i++) /* Relying on enumeration ordering. */
igor Stepura 0:bb6687c3a462 200 {
igor Stepura 0:bb6687c3a462 201 /* Calculate TZA DCOC STEPSIZE & its RECIPROCAL. */
igor Stepura 0:bb6687c3a462 202 switch(i){
igor Stepura 0:bb6687c3a462 203 case TZA_STEP_N0:
igor Stepura 0:bb6687c3a462 204 temp_step = (bbf_dcoc_step >> 3U) / 3.6F;
igor Stepura 0:bb6687c3a462 205 break;
igor Stepura 0:bb6687c3a462 206 case TZA_STEP_N1:
igor Stepura 0:bb6687c3a462 207 temp_step = temp_step * (xcvr_common_config.dcoc_tza_step_01_init >> 16)/(xcvr_common_config.dcoc_tza_step_00_init >> 16);
igor Stepura 0:bb6687c3a462 208 break;
igor Stepura 0:bb6687c3a462 209 case TZA_STEP_N2:
igor Stepura 0:bb6687c3a462 210 temp_step = temp_step * (xcvr_common_config.dcoc_tza_step_02_init >> 16)/(xcvr_common_config.dcoc_tza_step_01_init >> 16);
igor Stepura 0:bb6687c3a462 211 break;
igor Stepura 0:bb6687c3a462 212 case TZA_STEP_N3:
igor Stepura 0:bb6687c3a462 213 temp_step = temp_step * (xcvr_common_config.dcoc_tza_step_03_init >> 16)/(xcvr_common_config.dcoc_tza_step_02_init >> 16);
igor Stepura 0:bb6687c3a462 214 break;
igor Stepura 0:bb6687c3a462 215 case TZA_STEP_N4:
igor Stepura 0:bb6687c3a462 216 temp_step = temp_step * (xcvr_common_config.dcoc_tza_step_04_init >> 16)/(xcvr_common_config.dcoc_tza_step_03_init >> 16);
igor Stepura 0:bb6687c3a462 217 break;
igor Stepura 0:bb6687c3a462 218 case TZA_STEP_N5:
igor Stepura 0:bb6687c3a462 219 temp_step = temp_step * (xcvr_common_config.dcoc_tza_step_05_init >> 16)/(xcvr_common_config.dcoc_tza_step_04_init >> 16);
igor Stepura 0:bb6687c3a462 220 break;
igor Stepura 0:bb6687c3a462 221 case TZA_STEP_N6:
igor Stepura 0:bb6687c3a462 222 temp_step = temp_step * (xcvr_common_config.dcoc_tza_step_06_init >> 16)/(xcvr_common_config.dcoc_tza_step_05_init >> 16);
igor Stepura 0:bb6687c3a462 223 break;
igor Stepura 0:bb6687c3a462 224 case TZA_STEP_N7:
igor Stepura 0:bb6687c3a462 225 temp_step = temp_step * (xcvr_common_config.dcoc_tza_step_07_init >> 16)/(xcvr_common_config.dcoc_tza_step_06_init >> 16);
igor Stepura 0:bb6687c3a462 226 break;
igor Stepura 0:bb6687c3a462 227 case TZA_STEP_N8:
igor Stepura 0:bb6687c3a462 228 temp_step = temp_step * (xcvr_common_config.dcoc_tza_step_08_init >> 16)/(xcvr_common_config.dcoc_tza_step_07_init >> 16);
igor Stepura 0:bb6687c3a462 229 break;
igor Stepura 0:bb6687c3a462 230 case TZA_STEP_N9:
igor Stepura 0:bb6687c3a462 231 temp_step = temp_step * (xcvr_common_config.dcoc_tza_step_09_init >> 16)/(xcvr_common_config.dcoc_tza_step_08_init >> 16);
igor Stepura 0:bb6687c3a462 232 break;
igor Stepura 0:bb6687c3a462 233 case TZA_STEP_N10:
igor Stepura 0:bb6687c3a462 234 temp_step = temp_step * (xcvr_common_config.dcoc_tza_step_10_init >> 16)/(xcvr_common_config.dcoc_tza_step_09_init >> 16);
igor Stepura 0:bb6687c3a462 235 break;
igor Stepura 0:bb6687c3a462 236 default:
igor Stepura 0:bb6687c3a462 237 break;
igor Stepura 0:bb6687c3a462 238 }
igor Stepura 0:bb6687c3a462 239
igor Stepura 0:bb6687c3a462 240 tza_dcoc_step[i-TZA_STEP_N0].dcoc_step = (uint32_t)roundf(temp_step * 8);
igor Stepura 0:bb6687c3a462 241 tza_dcoc_step[i-TZA_STEP_N0].dcoc_step_rcp = (uint32_t)roundf((float)0x8000 / temp_step);
igor Stepura 0:bb6687c3a462 242 }
igor Stepura 0:bb6687c3a462 243
igor Stepura 0:bb6687c3a462 244 /* Make the trims active. */
igor Stepura 0:bb6687c3a462 245 XCVR_RX_DIG->DCOC_BBA_STEP = XCVR_RX_DIG_DCOC_BBA_STEP_BBA_DCOC_STEP(bbf_dcoc_step) | XCVR_RX_DIG_DCOC_BBA_STEP_BBA_DCOC_STEP_RECIP(bbf_dcoc_step_rcp) ;
igor Stepura 0:bb6687c3a462 246 XCVR_RX_DIG->DCOC_TZA_STEP_0 = XCVR_RX_DIG_DCOC_TZA_STEP_0_DCOC_TZA_STEP_GAIN_0(tza_dcoc_step[0].dcoc_step) | XCVR_RX_DIG_DCOC_TZA_STEP_0_DCOC_TZA_STEP_RCP_0(tza_dcoc_step[0].dcoc_step_rcp) ;
igor Stepura 0:bb6687c3a462 247 XCVR_RX_DIG->DCOC_TZA_STEP_1 = XCVR_RX_DIG_DCOC_TZA_STEP_1_DCOC_TZA_STEP_GAIN_1(tza_dcoc_step[1].dcoc_step) | XCVR_RX_DIG_DCOC_TZA_STEP_1_DCOC_TZA_STEP_RCP_1(tza_dcoc_step[1].dcoc_step_rcp) ;
igor Stepura 0:bb6687c3a462 248 XCVR_RX_DIG->DCOC_TZA_STEP_2 = XCVR_RX_DIG_DCOC_TZA_STEP_2_DCOC_TZA_STEP_GAIN_2(tza_dcoc_step[2].dcoc_step) | XCVR_RX_DIG_DCOC_TZA_STEP_2_DCOC_TZA_STEP_RCP_2(tza_dcoc_step[2].dcoc_step_rcp) ;
igor Stepura 0:bb6687c3a462 249 XCVR_RX_DIG->DCOC_TZA_STEP_3 = XCVR_RX_DIG_DCOC_TZA_STEP_3_DCOC_TZA_STEP_GAIN_3(tza_dcoc_step[3].dcoc_step) | XCVR_RX_DIG_DCOC_TZA_STEP_3_DCOC_TZA_STEP_RCP_3(tza_dcoc_step[3].dcoc_step_rcp) ;
igor Stepura 0:bb6687c3a462 250 XCVR_RX_DIG->DCOC_TZA_STEP_4 = XCVR_RX_DIG_DCOC_TZA_STEP_4_DCOC_TZA_STEP_GAIN_4(tza_dcoc_step[4].dcoc_step) | XCVR_RX_DIG_DCOC_TZA_STEP_4_DCOC_TZA_STEP_RCP_4(tza_dcoc_step[4].dcoc_step_rcp) ;
igor Stepura 0:bb6687c3a462 251 XCVR_RX_DIG->DCOC_TZA_STEP_5 = XCVR_RX_DIG_DCOC_TZA_STEP_5_DCOC_TZA_STEP_GAIN_5(tza_dcoc_step[5].dcoc_step) | XCVR_RX_DIG_DCOC_TZA_STEP_5_DCOC_TZA_STEP_RCP_5(tza_dcoc_step[5].dcoc_step_rcp) ;
igor Stepura 0:bb6687c3a462 252 XCVR_RX_DIG->DCOC_TZA_STEP_6 = XCVR_RX_DIG_DCOC_TZA_STEP_6_DCOC_TZA_STEP_GAIN_6(tza_dcoc_step[6].dcoc_step) | XCVR_RX_DIG_DCOC_TZA_STEP_6_DCOC_TZA_STEP_RCP_6(tza_dcoc_step[6].dcoc_step_rcp) ;
igor Stepura 0:bb6687c3a462 253 XCVR_RX_DIG->DCOC_TZA_STEP_7 = XCVR_RX_DIG_DCOC_TZA_STEP_7_DCOC_TZA_STEP_GAIN_7(tza_dcoc_step[7].dcoc_step) | XCVR_RX_DIG_DCOC_TZA_STEP_7_DCOC_TZA_STEP_RCP_7(tza_dcoc_step[7].dcoc_step_rcp) ;
igor Stepura 0:bb6687c3a462 254 XCVR_RX_DIG->DCOC_TZA_STEP_8 = XCVR_RX_DIG_DCOC_TZA_STEP_8_DCOC_TZA_STEP_GAIN_8(tza_dcoc_step[8].dcoc_step) | XCVR_RX_DIG_DCOC_TZA_STEP_8_DCOC_TZA_STEP_RCP_8(tza_dcoc_step[8].dcoc_step_rcp) ;
igor Stepura 0:bb6687c3a462 255 XCVR_RX_DIG->DCOC_TZA_STEP_9 = XCVR_RX_DIG_DCOC_TZA_STEP_9_DCOC_TZA_STEP_GAIN_9(tza_dcoc_step[9].dcoc_step) | XCVR_RX_DIG_DCOC_TZA_STEP_9_DCOC_TZA_STEP_RCP_9(tza_dcoc_step[9].dcoc_step_rcp) ;
igor Stepura 0:bb6687c3a462 256 XCVR_RX_DIG->DCOC_TZA_STEP_10 = XCVR_RX_DIG_DCOC_TZA_STEP_10_DCOC_TZA_STEP_GAIN_10(tza_dcoc_step[10].dcoc_step) | XCVR_RX_DIG_DCOC_TZA_STEP_10_DCOC_TZA_STEP_RCP_10(tza_dcoc_step[10].dcoc_step_rcp) ;
igor Stepura 0:bb6687c3a462 257
igor Stepura 0:bb6687c3a462 258 status = 1; /* Success */
igor Stepura 0:bb6687c3a462 259 }
igor Stepura 0:bb6687c3a462 260 else
igor Stepura 0:bb6687c3a462 261 {
igor Stepura 0:bb6687c3a462 262 status = 0; /* Failure */
igor Stepura 0:bb6687c3a462 263 }
igor Stepura 0:bb6687c3a462 264
igor Stepura 0:bb6687c3a462 265 /* Restore Registers. */
igor Stepura 0:bb6687c3a462 266 XCVR_RX_DIG->DCOC_CTRL_0 = dcoc_ctrl_0_stack; /* Restore DCOC_CTRL_0 state to prior settings. */
igor Stepura 0:bb6687c3a462 267 XCVR_RX_DIG->DCOC_CTRL_1 = dcoc_ctrl_1_stack; /* Restore DCOC_CTRL_1 state to prior settings. */
igor Stepura 0:bb6687c3a462 268 XCVR_RX_DIG->RX_DIG_CTRL = rx_dig_ctrl_stack; /* Restore RX_DIG_CTRL state to prior settings. */
igor Stepura 0:bb6687c3a462 269 XCVR_RX_DIG->DCOC_CAL_GAIN = dcoc_cal_gain_state; /* Restore DCOC_CAL_GAIN state to prior setting. */
igor Stepura 0:bb6687c3a462 270 XCVR_RX_DIG->AGC_CTRL_1 = agc_ctrl_1_stack; /* Save state of RX_DIG_CTRL for later restore. */
igor Stepura 0:bb6687c3a462 271
igor Stepura 0:bb6687c3a462 272 return status;
igor Stepura 0:bb6687c3a462 273 }
igor Stepura 0:bb6687c3a462 274
igor Stepura 0:bb6687c3a462 275 /*! *********************************************************************************
igor Stepura 0:bb6687c3a462 276 * \brief This function performs one point of the DC GAIN calibration process on the DUT
igor Stepura 0:bb6687c3a462 277 *
igor Stepura 0:bb6687c3a462 278 * \param[in] chan - whether the I or Q channel is being tested.
igor Stepura 0:bb6687c3a462 279 * \param[in] stage - whether the BBF or TZA gain stage is being tested.
igor Stepura 0:bb6687c3a462 280 * \param[in] dcoc_init_val - the value being set in the ***DCOC_INIT_* register by the parent.
igor Stepura 0:bb6687c3a462 281 * \param[in] ext_measmt - the external measurement (in milliVolts) captured by the parent after the ***DCOC_INIT_* register was setup.
igor Stepura 0:bb6687c3a462 282 *
igor Stepura 0:bb6687c3a462 283 * \ingroup PublicAPIs
igor Stepura 0:bb6687c3a462 284 *
igor Stepura 0:bb6687c3a462 285 * \details
igor Stepura 0:bb6687c3a462 286 * Relies on a static array to store each point of data for later processing in ::DC_GainCalc().
igor Stepura 0:bb6687c3a462 287 *
igor Stepura 0:bb6687c3a462 288 ***********************************************************************************/
igor Stepura 0:bb6687c3a462 289 void DC_Measure_short(IQ_t chan, DAC_SWEEP_STEP2_t dcoc_init_val)
igor Stepura 0:bb6687c3a462 290 {
igor Stepura 0:bb6687c3a462 291 int16_t dc_meas_i = 0;
igor Stepura 0:bb6687c3a462 292 int16_t dc_meas_q = 0;
igor Stepura 0:bb6687c3a462 293 int16_t sum_dc_meas_i = 0;
igor Stepura 0:bb6687c3a462 294 int16_t sum_dc_meas_q = 0;
igor Stepura 0:bb6687c3a462 295
igor Stepura 0:bb6687c3a462 296 {
igor Stepura 0:bb6687c3a462 297 int8_t i;
igor Stepura 0:bb6687c3a462 298 const int8_t iterations = 1;
igor Stepura 0:bb6687c3a462 299 sum_dc_meas_i = 0;
igor Stepura 0:bb6687c3a462 300 sum_dc_meas_q = 0;
igor Stepura 0:bb6687c3a462 301
igor Stepura 0:bb6687c3a462 302 for (i = 0; i < iterations; i++)
igor Stepura 0:bb6687c3a462 303 {
igor Stepura 0:bb6687c3a462 304 rx_dc_sample_average(&dc_meas_i, &dc_meas_q);
igor Stepura 0:bb6687c3a462 305 sum_dc_meas_i = sum_dc_meas_i + dc_meas_i;
igor Stepura 0:bb6687c3a462 306 sum_dc_meas_q = sum_dc_meas_q + dc_meas_q;
igor Stepura 0:bb6687c3a462 307 }
igor Stepura 0:bb6687c3a462 308 sum_dc_meas_i = sum_dc_meas_i / iterations;
igor Stepura 0:bb6687c3a462 309 sum_dc_meas_q = sum_dc_meas_q / iterations;
igor Stepura 0:bb6687c3a462 310 }
igor Stepura 0:bb6687c3a462 311
igor Stepura 0:bb6687c3a462 312 measurement_tbl2[chan][dcoc_init_val].step_value = sweep_step_values2[dcoc_init_val];
igor Stepura 0:bb6687c3a462 313
igor Stepura 0:bb6687c3a462 314 if (chan == I_CHANNEL)
igor Stepura 0:bb6687c3a462 315 {
igor Stepura 0:bb6687c3a462 316 measurement_tbl2[chan][dcoc_init_val].internal_measurement = dc_meas_i;
igor Stepura 0:bb6687c3a462 317 }
igor Stepura 0:bb6687c3a462 318 else
igor Stepura 0:bb6687c3a462 319 {
igor Stepura 0:bb6687c3a462 320 measurement_tbl2[chan][dcoc_init_val].internal_measurement = dc_meas_q;
igor Stepura 0:bb6687c3a462 321 }
igor Stepura 0:bb6687c3a462 322 }
igor Stepura 0:bb6687c3a462 323
igor Stepura 0:bb6687c3a462 324 /*! *********************************************************************************
igor Stepura 0:bb6687c3a462 325 * \brief This function calculates one point of DC DAC step based on digital samples of I or Q.
igor Stepura 0:bb6687c3a462 326 *
igor Stepura 0:bb6687c3a462 327 * \param[in] meas_ptr - pointer to the structure containing the measured data from internal measurement.
igor Stepura 0:bb6687c3a462 328 * \param[in] baseline_meas_ptr - pointer to the structure containing the baseline measured data from internal measurement.
igor Stepura 0:bb6687c3a462 329 *
igor Stepura 0:bb6687c3a462 330 * \return result of the calculation, the measurement DCOC DAC step value for this measurement point.
igor Stepura 0:bb6687c3a462 331 *
igor Stepura 0:bb6687c3a462 332 ***********************************************************************************/
igor Stepura 0:bb6687c3a462 333 float calc_dcoc_dac_step(GAIN_CALC_TBL_ENTRY2_T * meas_ptr, GAIN_CALC_TBL_ENTRY2_T * baseline_meas_ptr )
igor Stepura 0:bb6687c3a462 334 {
igor Stepura 0:bb6687c3a462 335 static int16_t norm_dc_code;
igor Stepura 0:bb6687c3a462 336 static float dc_step;
igor Stepura 0:bb6687c3a462 337
igor Stepura 0:bb6687c3a462 338 /* Normalize internal measurement */
igor Stepura 0:bb6687c3a462 339 norm_dc_code = meas_ptr->internal_measurement - baseline_meas_ptr->internal_measurement;
igor Stepura 0:bb6687c3a462 340 dc_step = (float)(norm_dc_code) / (float)(meas_ptr->step_value);
igor Stepura 0:bb6687c3a462 341 dc_step = (dc_step < 0)? -dc_step: dc_step;
igor Stepura 0:bb6687c3a462 342
igor Stepura 0:bb6687c3a462 343 return dc_step;
igor Stepura 0:bb6687c3a462 344 }
igor Stepura 0:bb6687c3a462 345
igor Stepura 0:bb6687c3a462 346 /*! *********************************************************************************
igor Stepura 0:bb6687c3a462 347 * \brief Temporary delay function
igor Stepura 0:bb6687c3a462 348 *
igor Stepura 0:bb6687c3a462 349 * \param[in] none.
igor Stepura 0:bb6687c3a462 350 *
igor Stepura 0:bb6687c3a462 351 * \return none.
igor Stepura 0:bb6687c3a462 352 *
igor Stepura 0:bb6687c3a462 353 * \details
igor Stepura 0:bb6687c3a462 354 *
igor Stepura 0:bb6687c3a462 355 ***********************************************************************************/
igor Stepura 0:bb6687c3a462 356 void XcvrCalDelay(uint32_t time)
igor Stepura 0:bb6687c3a462 357 {
igor Stepura 0:bb6687c3a462 358 while(time * 32 > 0) /* Time delay is roughly in uSec. */
igor Stepura 0:bb6687c3a462 359 {
igor Stepura 0:bb6687c3a462 360 time--;
igor Stepura 0:bb6687c3a462 361 }
igor Stepura 0:bb6687c3a462 362 }
igor Stepura 0:bb6687c3a462 363
igor Stepura 0:bb6687c3a462 364 /*! *********************************************************************************
igor Stepura 0:bb6687c3a462 365 * \brief This function calculates the average (DC value) based on a smaller set of digital samples of I and Q.
igor Stepura 0:bb6687c3a462 366 *
igor Stepura 0:bb6687c3a462 367 * \param[in] i_avg - pointer to the location for storing the calculated average for I channel samples.
igor Stepura 0:bb6687c3a462 368 * \param[in] q_avg - pointer to the location for storing the calculated average for Q channel samples.
igor Stepura 0:bb6687c3a462 369 *
igor Stepura 0:bb6687c3a462 370 ***********************************************************************************/
igor Stepura 0:bb6687c3a462 371 void rx_dc_sample_average(int16_t * i_avg, int16_t * q_avg)
igor Stepura 0:bb6687c3a462 372 {
igor Stepura 0:bb6687c3a462 373 static uint32_t samples[128]; /* 544*2*2 (entire packet ram1/2 size) */
igor Stepura 0:bb6687c3a462 374 uint16_t i;
igor Stepura 0:bb6687c3a462 375 uint32_t rx_sample;
igor Stepura 0:bb6687c3a462 376 uint16_t * sample_ptr;
igor Stepura 0:bb6687c3a462 377 uint32_t temp, end_of_rx_wu;
igor Stepura 0:bb6687c3a462 378 uint32_t num_iq_samples;
igor Stepura 0:bb6687c3a462 379 float avg_i = 0;
igor Stepura 0:bb6687c3a462 380 float avg_q = 0;
igor Stepura 0:bb6687c3a462 381
igor Stepura 0:bb6687c3a462 382 num_iq_samples = 128;
igor Stepura 0:bb6687c3a462 383
igor Stepura 0:bb6687c3a462 384 /* Clear the entire allocated sample buffer */
igor Stepura 0:bb6687c3a462 385 for (i = 0; i < num_iq_samples; i++)
igor Stepura 0:bb6687c3a462 386 {
igor Stepura 0:bb6687c3a462 387 samples[i]=0;
igor Stepura 0:bb6687c3a462 388 }
igor Stepura 0:bb6687c3a462 389
igor Stepura 0:bb6687c3a462 390 /* Assume this has been called *AFTER* RxWu has completed. */
igor Stepura 0:bb6687c3a462 391 /* XCVR_ForceRxWu(); */
igor Stepura 0:bb6687c3a462 392
igor Stepura 0:bb6687c3a462 393 /* Wait for TSM to reach the end of warmup (unless you want to capture some samples during DCOC cal phase) */
igor Stepura 0:bb6687c3a462 394 temp = XCVR_TSM->END_OF_SEQ;
igor Stepura 0:bb6687c3a462 395 end_of_rx_wu = (temp & XCVR_TSM_END_OF_SEQ_END_OF_RX_WU_MASK) >> XCVR_TSM_END_OF_SEQ_END_OF_RX_WU_SHIFT;
igor Stepura 0:bb6687c3a462 396 while ((( XCVR_MISC->XCVR_STATUS & XCVR_CTRL_XCVR_STATUS_TSM_COUNT_MASK) >> XCVR_CTRL_XCVR_STATUS_TSM_COUNT_SHIFT ) != end_of_rx_wu) {};
igor Stepura 0:bb6687c3a462 397
igor Stepura 0:bb6687c3a462 398 dbg_ram_init();
igor Stepura 0:bb6687c3a462 399 /* Argument below is # of bytes, so *2 (I+Q) and *2 (2bytes/sample) */
igor Stepura 0:bb6687c3a462 400 #if RADIO_IS_GEN_3P0
igor Stepura 0:bb6687c3a462 401 dbg_ram_start_capture(DBG_PAGE_RXDIGIQ, NO_START_TRIG, NO_STOP_TRIG);
igor Stepura 0:bb6687c3a462 402 dbg_ram_wait_for_complete();
igor Stepura 0:bb6687c3a462 403 dbg_ram_postproc_capture(DBG_PAGE_RXDIGIQ, num_iq_samples * 2 * 2, &samples[0]);
igor Stepura 0:bb6687c3a462 404 dbg_ram_release();
igor Stepura 0:bb6687c3a462 405 #else
igor Stepura 0:bb6687c3a462 406 (void)dbg_ram_capture(DBG_PAGE_RXDIGIQ, num_iq_samples * 2 * 2, &samples[0]);
igor Stepura 0:bb6687c3a462 407 #endif /* RADIO_IS_GEN_3P0 */
igor Stepura 0:bb6687c3a462 408
igor Stepura 0:bb6687c3a462 409 /* Sign extend the IQ samples in place in the sample buffer. */
igor Stepura 0:bb6687c3a462 410 sample_ptr = (uint16_t *)(&samples[0]);
igor Stepura 0:bb6687c3a462 411 for (i = 0; i < num_iq_samples * 2; i++)
igor Stepura 0:bb6687c3a462 412 {
igor Stepura 0:bb6687c3a462 413 rx_sample = *sample_ptr;
igor Stepura 0:bb6687c3a462 414 rx_sample |= ((rx_sample & 0x800U) ? 0xF000U : 0x0U); /* Sign extend from 12 to 16 bits. */
igor Stepura 0:bb6687c3a462 415 *sample_ptr = rx_sample;
igor Stepura 0:bb6687c3a462 416 sample_ptr++;
igor Stepura 0:bb6687c3a462 417 }
igor Stepura 0:bb6687c3a462 418
igor Stepura 0:bb6687c3a462 419 sample_ptr = (uint16_t *)(&samples[0]);
igor Stepura 0:bb6687c3a462 420 for (i = 0; i < num_iq_samples * 2; i += 2)
igor Stepura 0:bb6687c3a462 421 {
igor Stepura 0:bb6687c3a462 422 static int16_t i_value;
igor Stepura 0:bb6687c3a462 423 static int16_t q_value;
igor Stepura 0:bb6687c3a462 424
igor Stepura 0:bb6687c3a462 425 /* Average I & Q channels separately. */
igor Stepura 0:bb6687c3a462 426 i_value = *(sample_ptr + i); /* Sign extend from 12 to 16 bits. */
igor Stepura 0:bb6687c3a462 427 q_value = *(sample_ptr + i + 1); /* Sign extend from 12 to 16 bits. */
igor Stepura 0:bb6687c3a462 428 avg_i += ((float)i_value - avg_i) / (float)(i + 1); /* Rolling average I */
igor Stepura 0:bb6687c3a462 429 avg_q += ((float)q_value - avg_q) / (float)(i + 1); /* Rolling average Q */
igor Stepura 0:bb6687c3a462 430 }
igor Stepura 0:bb6687c3a462 431 XcvrCalDelay(10);
igor Stepura 0:bb6687c3a462 432 *i_avg = (int16_t)avg_i;
igor Stepura 0:bb6687c3a462 433 *q_avg = (int16_t)avg_q;
igor Stepura 0:bb6687c3a462 434 }
igor Stepura 0:bb6687c3a462 435
igor Stepura 0:bb6687c3a462 436 /*! *********************************************************************************
igor Stepura 0:bb6687c3a462 437 * \brief This function calculates the average (DC value) based on a larger set of digital samples of I and Q.
igor Stepura 0:bb6687c3a462 438 *
igor Stepura 0:bb6687c3a462 439 * \param[in] i_avg - pointer to the location for storing the calculated average for I channel samples.
igor Stepura 0:bb6687c3a462 440 * \param[in] q_avg - pointer to the location for storing the calculated average for Q channel samples.
igor Stepura 0:bb6687c3a462 441 *
igor Stepura 0:bb6687c3a462 442 ***********************************************************************************/
igor Stepura 0:bb6687c3a462 443 void rx_dc_sample_average_long(int16_t * i_avg, int16_t * q_avg)
igor Stepura 0:bb6687c3a462 444 {
igor Stepura 0:bb6687c3a462 445 static uint32_t samples[512]; /* 544*2*2 (entire packet ram1/2 size) */
igor Stepura 0:bb6687c3a462 446 uint16_t i;
igor Stepura 0:bb6687c3a462 447 uint32_t rx_sample;
igor Stepura 0:bb6687c3a462 448 uint16_t * sample_ptr;
igor Stepura 0:bb6687c3a462 449 uint32_t temp, end_of_rx_wu;
igor Stepura 0:bb6687c3a462 450 uint32_t num_iq_samples;
igor Stepura 0:bb6687c3a462 451 float avg_i = 0;
igor Stepura 0:bb6687c3a462 452 float avg_q = 0;
igor Stepura 0:bb6687c3a462 453
igor Stepura 0:bb6687c3a462 454 num_iq_samples = 512;
igor Stepura 0:bb6687c3a462 455
igor Stepura 0:bb6687c3a462 456 /* Clear the entire allocated sample buffer. */
igor Stepura 0:bb6687c3a462 457 for (i = 0; i < num_iq_samples; i++)
igor Stepura 0:bb6687c3a462 458 {
igor Stepura 0:bb6687c3a462 459 samples[i]=0;
igor Stepura 0:bb6687c3a462 460 }
igor Stepura 0:bb6687c3a462 461
igor Stepura 0:bb6687c3a462 462 /* Assume this has been called *AFTER* RxWu has completed. */
igor Stepura 0:bb6687c3a462 463 /* XCVR_ForceRxWu(); */
igor Stepura 0:bb6687c3a462 464
igor Stepura 0:bb6687c3a462 465 /* Wait for TSM to reach the end of warmup (unless you want to capture some samples during DCOC cal phase). */
igor Stepura 0:bb6687c3a462 466 temp = XCVR_TSM->END_OF_SEQ;
igor Stepura 0:bb6687c3a462 467 end_of_rx_wu = (temp & XCVR_TSM_END_OF_SEQ_END_OF_RX_WU_MASK) >> XCVR_TSM_END_OF_SEQ_END_OF_RX_WU_SHIFT;
igor Stepura 0:bb6687c3a462 468 while ((( XCVR_MISC->XCVR_STATUS & XCVR_CTRL_XCVR_STATUS_TSM_COUNT_MASK) >> XCVR_CTRL_XCVR_STATUS_TSM_COUNT_SHIFT ) != end_of_rx_wu) {};
igor Stepura 0:bb6687c3a462 469
igor Stepura 0:bb6687c3a462 470 dbg_ram_init();
igor Stepura 0:bb6687c3a462 471 /* Argument below is # of bytes, so *2 (I+Q) and *2 (2bytes/sample) */
igor Stepura 0:bb6687c3a462 472 #if RADIO_IS_GEN_3P0
igor Stepura 0:bb6687c3a462 473 dbg_ram_start_capture(DBG_PAGE_RXDIGIQ, NO_START_TRIG, NO_STOP_TRIG);
igor Stepura 0:bb6687c3a462 474 dbg_ram_wait_for_complete();
igor Stepura 0:bb6687c3a462 475 dbg_ram_postproc_capture(DBG_PAGE_RXDIGIQ,num_iq_samples * 2 * 2, &samples[0]);
igor Stepura 0:bb6687c3a462 476 dbg_ram_release();
igor Stepura 0:bb6687c3a462 477 #else
igor Stepura 0:bb6687c3a462 478 (void)dbg_ram_capture(DBG_PAGE_RXDIGIQ, num_iq_samples * 2 * 2, &samples[0]);
igor Stepura 0:bb6687c3a462 479 #endif /* RADIO_IS_GEN_3P0 */
igor Stepura 0:bb6687c3a462 480
igor Stepura 0:bb6687c3a462 481 /* Sign extend the IQ samples in place in the sample buffer. */
igor Stepura 0:bb6687c3a462 482
igor Stepura 0:bb6687c3a462 483 sample_ptr = (uint16_t *)(&samples[0]);
igor Stepura 0:bb6687c3a462 484 for (i = 0; i < num_iq_samples * 2; i++)
igor Stepura 0:bb6687c3a462 485 {
igor Stepura 0:bb6687c3a462 486 rx_sample = *sample_ptr;
igor Stepura 0:bb6687c3a462 487 rx_sample |= ((rx_sample & 0x800U) ? 0xF000U : 0x0U); /* Sign extend from 12 to 16 bits. */
igor Stepura 0:bb6687c3a462 488 *sample_ptr = rx_sample;
igor Stepura 0:bb6687c3a462 489 sample_ptr++;
igor Stepura 0:bb6687c3a462 490 }
igor Stepura 0:bb6687c3a462 491
igor Stepura 0:bb6687c3a462 492 sample_ptr = (uint16_t *)(&samples[0]);
igor Stepura 0:bb6687c3a462 493 for (i = 0; i < num_iq_samples * 2; i += 2)
igor Stepura 0:bb6687c3a462 494 {
igor Stepura 0:bb6687c3a462 495 static int16_t i_value;
igor Stepura 0:bb6687c3a462 496 static int16_t q_value;
igor Stepura 0:bb6687c3a462 497
igor Stepura 0:bb6687c3a462 498 /* Average I & Q channels separately. */
igor Stepura 0:bb6687c3a462 499 i_value = *(sample_ptr + i); /* Sign extend from 12 to 16 bits */
igor Stepura 0:bb6687c3a462 500 q_value = *(sample_ptr + i + 1); /* Sign extend from 12 to 16 bits */
igor Stepura 0:bb6687c3a462 501 avg_i += ((float)i_value - avg_i) / (float)(i + 1); /* Rolling average I */
igor Stepura 0:bb6687c3a462 502 avg_q += ((float)q_value - avg_q) / (float)(i + 1); /* Rolling average Q */
igor Stepura 0:bb6687c3a462 503 }
igor Stepura 0:bb6687c3a462 504
igor Stepura 0:bb6687c3a462 505 XcvrCalDelay(10);
igor Stepura 0:bb6687c3a462 506 *i_avg = (int16_t)avg_i;
igor Stepura 0:bb6687c3a462 507 *q_avg = (int16_t)avg_q;
igor Stepura 0:bb6687c3a462 508 }
igor Stepura 0:bb6687c3a462 509
igor Stepura 0:bb6687c3a462 510 /*! *********************************************************************************
igor Stepura 0:bb6687c3a462 511 * rx_dc_est_average : Get DC EST values and return the Average
igor Stepura 0:bb6687c3a462 512 ***********************************************************************************/
igor Stepura 0:bb6687c3a462 513 void rx_dc_est_average(int16_t * i_avg, int16_t * q_avg, uint16_t SampleNumber)
igor Stepura 0:bb6687c3a462 514 {
igor Stepura 0:bb6687c3a462 515 float avg_i = 0;
igor Stepura 0:bb6687c3a462 516 float avg_q = 0;
igor Stepura 0:bb6687c3a462 517 uint16_t i = 0;
igor Stepura 0:bb6687c3a462 518 static uint32_t dc_temp, temp;
igor Stepura 0:bb6687c3a462 519 uint32_t end_of_rx_wu = 0;
igor Stepura 0:bb6687c3a462 520 static int16_t dc_meas_i;
igor Stepura 0:bb6687c3a462 521 static int16_t dc_meas_q;
igor Stepura 0:bb6687c3a462 522
igor Stepura 0:bb6687c3a462 523 /* Wait for TSM to reach the end of warmup (unless you want to capture some samples during DCOC cal phase). */
igor Stepura 0:bb6687c3a462 524 temp = XCVR_TSM->END_OF_SEQ;
igor Stepura 0:bb6687c3a462 525 end_of_rx_wu = (temp & XCVR_TSM_END_OF_SEQ_END_OF_RX_WU_MASK) >> XCVR_TSM_END_OF_SEQ_END_OF_RX_WU_SHIFT;
igor Stepura 0:bb6687c3a462 526 while ((( XCVR_MISC->XCVR_STATUS & XCVR_CTRL_XCVR_STATUS_TSM_COUNT_MASK) >> XCVR_CTRL_XCVR_STATUS_TSM_COUNT_SHIFT ) != end_of_rx_wu) {};
igor Stepura 0:bb6687c3a462 527
igor Stepura 0:bb6687c3a462 528 /* Read DCOC DC EST register. */
igor Stepura 0:bb6687c3a462 529 for (i = 0; i < SampleNumber; i++)
igor Stepura 0:bb6687c3a462 530 {
igor Stepura 0:bb6687c3a462 531 dc_temp = XCVR_RX_DIG->DCOC_DC_EST;
igor Stepura 0:bb6687c3a462 532 dc_meas_i = dc_temp & XCVR_RX_DIG_DCOC_DC_EST_DC_EST_I_MASK;
igor Stepura 0:bb6687c3a462 533 temp = dc_meas_i;
igor Stepura 0:bb6687c3a462 534 temp |= ((temp & 0x800U) ? 0xF000U : 0x0U); /* Sign extend from 12 to 16 bits. */
igor Stepura 0:bb6687c3a462 535 dc_meas_i = temp;
igor Stepura 0:bb6687c3a462 536 avg_i += (float) dc_meas_i;
igor Stepura 0:bb6687c3a462 537
igor Stepura 0:bb6687c3a462 538 dc_meas_q = (dc_temp & XCVR_RX_DIG_DCOC_DC_EST_DC_EST_Q_MASK) >> XCVR_RX_DIG_DCOC_DC_EST_DC_EST_Q_SHIFT;
igor Stepura 0:bb6687c3a462 539 temp = dc_meas_q;
igor Stepura 0:bb6687c3a462 540 temp |= ((temp & 0x800U) ? 0xF000U : 0x0U); /* Sign extend from 12 to 16 bits. */
igor Stepura 0:bb6687c3a462 541 dc_meas_q = temp;
igor Stepura 0:bb6687c3a462 542 avg_q += (float) dc_meas_q;
igor Stepura 0:bb6687c3a462 543 }
igor Stepura 0:bb6687c3a462 544
igor Stepura 0:bb6687c3a462 545 avg_i /= (float) SampleNumber;
igor Stepura 0:bb6687c3a462 546 avg_q /= (float) SampleNumber;
igor Stepura 0:bb6687c3a462 547
igor Stepura 0:bb6687c3a462 548 *i_avg = (int16_t)avg_i;
igor Stepura 0:bb6687c3a462 549 *q_avg = (int16_t)avg_q;
igor Stepura 0:bb6687c3a462 550 }
igor Stepura 0:bb6687c3a462 551
igor Stepura 0:bb6687c3a462 552 /*! *********************************************************************************
igor Stepura 0:bb6687c3a462 553 * \brief This function performs a trim of the BBA DCOC DAC on the DUT
igor Stepura 0:bb6687c3a462 554 *
igor Stepura 0:bb6687c3a462 555 * \return status - 1 if passed, 0 if failed.
igor Stepura 0:bb6687c3a462 556 *
igor Stepura 0:bb6687c3a462 557 * \ingroup PublicAPIs
igor Stepura 0:bb6687c3a462 558 *
igor Stepura 0:bb6687c3a462 559 * \details
igor Stepura 0:bb6687c3a462 560 * Requires the RX to be warmed up before this function is called.
igor Stepura 0:bb6687c3a462 561 *
igor Stepura 0:bb6687c3a462 562 ***********************************************************************************/
igor Stepura 0:bb6687c3a462 563 uint8_t rx_bba_dcoc_dac_trim_DCest(void)
igor Stepura 0:bb6687c3a462 564 {
igor Stepura 0:bb6687c3a462 565 uint8_t i;
igor Stepura 0:bb6687c3a462 566 float temp_mi = 0;
igor Stepura 0:bb6687c3a462 567 float temp_mq = 0;
igor Stepura 0:bb6687c3a462 568 float temp_pi = 0;
igor Stepura 0:bb6687c3a462 569 float temp_pq = 0;
igor Stepura 0:bb6687c3a462 570 float temp_step = 0;
igor Stepura 0:bb6687c3a462 571
igor Stepura 0:bb6687c3a462 572 uint32_t bbf_dcoc_step;
igor Stepura 0:bb6687c3a462 573 uint32_t bbf_dcoc_step_rcp;
igor Stepura 0:bb6687c3a462 574 TZAdcocstep_t tza_dcoc_step[11];
igor Stepura 0:bb6687c3a462 575 uint8_t status = 0;
igor Stepura 0:bb6687c3a462 576
igor Stepura 0:bb6687c3a462 577 uint8_t bbf_dacinit_i, bbf_dacinit_q;
igor Stepura 0:bb6687c3a462 578 uint8_t tza_dacinit_i, tza_dacinit_q;
igor Stepura 0:bb6687c3a462 579 int16_t dc_meas_i;
igor Stepura 0:bb6687c3a462 580 int16_t dc_meas_q;
igor Stepura 0:bb6687c3a462 581 uint32_t dcoc_init_reg_value_dcgain = 0x80802020; /* Used in 2nd & 3rd Generation DCOC Trims only */
igor Stepura 0:bb6687c3a462 582 uint32_t temp;
igor Stepura 0:bb6687c3a462 583
igor Stepura 0:bb6687c3a462 584 uint32_t dcoc_ctrl_0_stack;
igor Stepura 0:bb6687c3a462 585 uint32_t dcoc_ctrl_1_stack;
igor Stepura 0:bb6687c3a462 586 uint32_t agc_ctrl_1_stack;
igor Stepura 0:bb6687c3a462 587 uint32_t rx_dig_ctrl_stack;
igor Stepura 0:bb6687c3a462 588 uint32_t dcoc_cal_gain_state;
igor Stepura 0:bb6687c3a462 589
igor Stepura 0:bb6687c3a462 590 /* Save register */
igor Stepura 0:bb6687c3a462 591 dcoc_ctrl_0_stack = XCVR_RX_DIG->DCOC_CTRL_0; /* Save state of DCOC_CTRL_0 for later restore */
igor Stepura 0:bb6687c3a462 592 dcoc_ctrl_1_stack = XCVR_RX_DIG->DCOC_CTRL_1; /* Save state of DCOC_CTRL_1 for later restore */
igor Stepura 0:bb6687c3a462 593 rx_dig_ctrl_stack = XCVR_RX_DIG->RX_DIG_CTRL; /* Save state of RX_DIG_CTRL for later restore */
igor Stepura 0:bb6687c3a462 594 agc_ctrl_1_stack = XCVR_RX_DIG->AGC_CTRL_1; /* Save state of RX_DIG_CTRL for later restore */
igor Stepura 0:bb6687c3a462 595 dcoc_cal_gain_state = XCVR_RX_DIG->DCOC_CAL_GAIN; /* Save state of DCOC_CAL_GAIN for later restore */
igor Stepura 0:bb6687c3a462 596
igor Stepura 0:bb6687c3a462 597 /* Register config */
igor Stepura 0:bb6687c3a462 598 /* Ensure AGC, DCOC and RX_DIG_CTRL is in correct mode */
igor Stepura 0:bb6687c3a462 599 temp = XCVR_RX_DIG->RX_DIG_CTRL;
igor Stepura 0:bb6687c3a462 600 temp &= ~XCVR_RX_DIG_RX_DIG_CTRL_RX_AGC_EN_MASK; /* Turn OFF AGC */
igor Stepura 0:bb6687c3a462 601 temp &= ~XCVR_RX_DIG_RX_DIG_CTRL_RX_DCOC_CAL_EN_MASK; /* Disable for SW control of DCOC */
igor Stepura 0:bb6687c3a462 602 temp &= ~XCVR_RX_DIG_RX_DIG_CTRL_RX_DC_RESID_EN_MASK; /* Disable for SW control of DCOC */
igor Stepura 0:bb6687c3a462 603 XCVR_RX_DIG->RX_DIG_CTRL = temp;
igor Stepura 0:bb6687c3a462 604
igor Stepura 0:bb6687c3a462 605 XCVR_RX_DIG->AGC_CTRL_1 = XCVR_RX_DIG_AGC_CTRL_1_USER_LNA_GAIN_EN(1) | /* Enable LNA Manual Gain */
igor Stepura 0:bb6687c3a462 606 XCVR_RX_DIG_AGC_CTRL_1_USER_BBA_GAIN_EN(1) | /* Enable BBA Manual Gain */
igor Stepura 0:bb6687c3a462 607 XCVR_RX_DIG_AGC_CTRL_1_LNA_USER_GAIN(0x0) | /* Set LNA Manual Gain */
igor Stepura 0:bb6687c3a462 608 XCVR_RX_DIG_AGC_CTRL_1_BBA_USER_GAIN(0x0); /* Set BBA Manual Gain */
igor Stepura 0:bb6687c3a462 609
igor Stepura 0:bb6687c3a462 610 /* DCOC_CTRL_0 @ 4005_C02C -- Define default DCOC DAC settings in manual mode */
igor Stepura 0:bb6687c3a462 611 temp = XCVR_RX_DIG->DCOC_CTRL_0;
igor Stepura 0:bb6687c3a462 612 temp |= XCVR_RX_DIG_DCOC_CTRL_0_DCOC_MAN(1); /* Enable Manual DCOC */
igor Stepura 0:bb6687c3a462 613 temp |= XCVR_RX_DIG_DCOC_CTRL_0_DCOC_CORRECT_SRC(1); /* Ensure DCOC Tracking is enabled */
igor Stepura 0:bb6687c3a462 614 temp |= XCVR_RX_DIG_DCOC_CTRL_0_DCOC_TRK_EST_OVR(1); /* Enable DC Estimator */
igor Stepura 0:bb6687c3a462 615 temp |= XCVR_RX_DIG_DCOC_CTRL_0_DCOC_CORRECT_EN(1); /* Ensure DC correction is enabled */
igor Stepura 0:bb6687c3a462 616 XCVR_RX_DIG->DCOC_CTRL_0 = temp;
igor Stepura 0:bb6687c3a462 617
igor Stepura 0:bb6687c3a462 618 XCVR_RX_DIG->DCOC_DAC_INIT = XCVR_RX_DIG_DCOC_DAC_INIT_BBA_DCOC_INIT_I(0x20) |
igor Stepura 0:bb6687c3a462 619 XCVR_RX_DIG_DCOC_DAC_INIT_BBA_DCOC_INIT_Q(0x20) |
igor Stepura 0:bb6687c3a462 620 XCVR_RX_DIG_DCOC_DAC_INIT_TZA_DCOC_INIT_I(0x80) |
igor Stepura 0:bb6687c3a462 621 XCVR_RX_DIG_DCOC_DAC_INIT_TZA_DCOC_INIT_Q(0x80);
igor Stepura 0:bb6687c3a462 622
igor Stepura 0:bb6687c3a462 623 XcvrCalDelay(TsettleCal);
igor Stepura 0:bb6687c3a462 624
igor Stepura 0:bb6687c3a462 625 /* Set default DCOC DAC INIT Value */
igor Stepura 0:bb6687c3a462 626 dcoc_init_reg_value_dcgain = XCVR_RX_DIG->DCOC_DAC_INIT; /* Store DCOC DAC INIT values */
igor Stepura 0:bb6687c3a462 627 bbf_dacinit_i = (dcoc_init_reg_value_dcgain & 0x000000FFU);
igor Stepura 0:bb6687c3a462 628 bbf_dacinit_q = (dcoc_init_reg_value_dcgain & 0x0000FF00U)>>8;
igor Stepura 0:bb6687c3a462 629 tza_dacinit_i = (dcoc_init_reg_value_dcgain & 0x00FF0000U)>>16;
igor Stepura 0:bb6687c3a462 630 tza_dacinit_q = dcoc_init_reg_value_dcgain >> 24;
igor Stepura 0:bb6687c3a462 631
igor Stepura 0:bb6687c3a462 632 XcvrCalDelay(TsettleCal * 4);
igor Stepura 0:bb6687c3a462 633 rx_dc_est_average(&dc_meas_i, &dc_meas_q, 64);
igor Stepura 0:bb6687c3a462 634 measurement_tbl2[I_CHANNEL][NOMINAL2].step_value = sweep_step_values2[NOMINAL2];
igor Stepura 0:bb6687c3a462 635 measurement_tbl2[Q_CHANNEL][NOMINAL2].step_value = sweep_step_values2[NOMINAL2];
igor Stepura 0:bb6687c3a462 636 measurement_tbl2[I_CHANNEL][NOMINAL2].internal_measurement = dc_meas_i;
igor Stepura 0:bb6687c3a462 637 measurement_tbl2[Q_CHANNEL][NOMINAL2].internal_measurement = dc_meas_q;
igor Stepura 0:bb6687c3a462 638
igor Stepura 0:bb6687c3a462 639 /* SWEEP I/Q CHANNEL */
igor Stepura 0:bb6687c3a462 640 /* BBF NEG STEP */
igor Stepura 0:bb6687c3a462 641 XCVR_RX_DIG->DCOC_DAC_INIT = XCVR_RX_DIG_DCOC_DAC_INIT_BBA_DCOC_INIT_I(bbf_dacinit_i - 16) |
igor Stepura 0:bb6687c3a462 642 XCVR_RX_DIG_DCOC_DAC_INIT_BBA_DCOC_INIT_Q(bbf_dacinit_q - 16) |
igor Stepura 0:bb6687c3a462 643 XCVR_RX_DIG_DCOC_DAC_INIT_TZA_DCOC_INIT_I(tza_dacinit_i) |
igor Stepura 0:bb6687c3a462 644 XCVR_RX_DIG_DCOC_DAC_INIT_TZA_DCOC_INIT_Q(tza_dacinit_q);
igor Stepura 0:bb6687c3a462 645 XcvrCalDelay(TsettleCal * 2);
igor Stepura 0:bb6687c3a462 646
igor Stepura 0:bb6687c3a462 647 rx_dc_est_average(&dc_meas_i, &dc_meas_q, 64);
igor Stepura 0:bb6687c3a462 648 measurement_tbl2[I_CHANNEL][BBF_NEG].step_value = -16;
igor Stepura 0:bb6687c3a462 649 measurement_tbl2[Q_CHANNEL][BBF_NEG].step_value = -16;
igor Stepura 0:bb6687c3a462 650 measurement_tbl2[I_CHANNEL][BBF_NEG].internal_measurement = dc_meas_i;
igor Stepura 0:bb6687c3a462 651 measurement_tbl2[Q_CHANNEL][BBF_NEG].internal_measurement = dc_meas_q;
igor Stepura 0:bb6687c3a462 652
igor Stepura 0:bb6687c3a462 653
igor Stepura 0:bb6687c3a462 654 /* BBF POS STEP */
igor Stepura 0:bb6687c3a462 655 XCVR_RX_DIG->DCOC_DAC_INIT = XCVR_RX_DIG_DCOC_DAC_INIT_BBA_DCOC_INIT_I(bbf_dacinit_i + 16) |
igor Stepura 0:bb6687c3a462 656 XCVR_RX_DIG_DCOC_DAC_INIT_BBA_DCOC_INIT_Q(bbf_dacinit_q + 16) |
igor Stepura 0:bb6687c3a462 657 XCVR_RX_DIG_DCOC_DAC_INIT_TZA_DCOC_INIT_I(tza_dacinit_i) |
igor Stepura 0:bb6687c3a462 658 XCVR_RX_DIG_DCOC_DAC_INIT_TZA_DCOC_INIT_Q(tza_dacinit_q);
igor Stepura 0:bb6687c3a462 659 XcvrCalDelay(TsettleCal * 2);
igor Stepura 0:bb6687c3a462 660 rx_dc_est_average(&dc_meas_i, &dc_meas_q, 64);
igor Stepura 0:bb6687c3a462 661 measurement_tbl2[I_CHANNEL][BBF_POS].step_value = +16;
igor Stepura 0:bb6687c3a462 662 measurement_tbl2[Q_CHANNEL][BBF_POS].step_value = +16;
igor Stepura 0:bb6687c3a462 663 measurement_tbl2[I_CHANNEL][BBF_POS].internal_measurement = dc_meas_i;
igor Stepura 0:bb6687c3a462 664 measurement_tbl2[Q_CHANNEL][BBF_POS].internal_measurement = dc_meas_q;
igor Stepura 0:bb6687c3a462 665
igor Stepura 0:bb6687c3a462 666 XCVR_RX_DIG->DCOC_DAC_INIT = dcoc_init_reg_value_dcgain; /* Return DAC setting to initial */
igor Stepura 0:bb6687c3a462 667
igor Stepura 0:bb6687c3a462 668 /* Calculate BBF DCOC STEPS, RECIPROCALS */
igor Stepura 0:bb6687c3a462 669 temp_mi = calc_dcoc_dac_step(&measurement_tbl2[I_CHANNEL][BBF_NEG], &measurement_tbl2[I_CHANNEL][NOMINAL2]);
igor Stepura 0:bb6687c3a462 670 temp_mq = calc_dcoc_dac_step(&measurement_tbl2[Q_CHANNEL][BBF_NEG], &measurement_tbl2[Q_CHANNEL][NOMINAL2]);
igor Stepura 0:bb6687c3a462 671 temp_pi = calc_dcoc_dac_step(&measurement_tbl2[I_CHANNEL][BBF_POS], &measurement_tbl2[I_CHANNEL][NOMINAL2]);
igor Stepura 0:bb6687c3a462 672 temp_pq = calc_dcoc_dac_step(&measurement_tbl2[Q_CHANNEL][BBF_POS], &measurement_tbl2[Q_CHANNEL][NOMINAL2]);
igor Stepura 0:bb6687c3a462 673
igor Stepura 0:bb6687c3a462 674 temp_step = (temp_mi + temp_pi + temp_mq + temp_pq) / 4;
igor Stepura 0:bb6687c3a462 675 bbf_dcoc_step = (uint32_t)roundf(temp_step * 8U);
igor Stepura 0:bb6687c3a462 676
igor Stepura 0:bb6687c3a462 677 if ((bbf_dcoc_step > 265) & (bbf_dcoc_step < 305))
igor Stepura 0:bb6687c3a462 678 {
igor Stepura 0:bb6687c3a462 679 bbf_dcoc_step_rcp = (uint32_t)roundf((float)0x8000U / temp_step);
igor Stepura 0:bb6687c3a462 680
igor Stepura 0:bb6687c3a462 681 /* Calculate TZA DCOC STEPS & RECIPROCALS and IQ_DC_GAIN_MISMATCH */
igor Stepura 0:bb6687c3a462 682 for (i = TZA_STEP_N0; i <= TZA_STEP_N10; i++)
igor Stepura 0:bb6687c3a462 683 {
igor Stepura 0:bb6687c3a462 684 /* Calculate TZA DCOC STEPSIZE & its RECIPROCAL */
igor Stepura 0:bb6687c3a462 685 switch(i){
igor Stepura 0:bb6687c3a462 686 case TZA_STEP_N0:
igor Stepura 0:bb6687c3a462 687 temp_step = (bbf_dcoc_step>>3U) / 3.6F;
igor Stepura 0:bb6687c3a462 688 break;
igor Stepura 0:bb6687c3a462 689 case TZA_STEP_N1:
igor Stepura 0:bb6687c3a462 690 temp_step = temp_step * (xcvr_common_config.dcoc_tza_step_01_init >> 16) / (xcvr_common_config.dcoc_tza_step_00_init >> 16);
igor Stepura 0:bb6687c3a462 691 break;
igor Stepura 0:bb6687c3a462 692 case TZA_STEP_N2:
igor Stepura 0:bb6687c3a462 693 temp_step = temp_step * (xcvr_common_config.dcoc_tza_step_02_init >> 16) / (xcvr_common_config.dcoc_tza_step_01_init >> 16);
igor Stepura 0:bb6687c3a462 694 break;
igor Stepura 0:bb6687c3a462 695 case TZA_STEP_N3:
igor Stepura 0:bb6687c3a462 696 temp_step = temp_step * (xcvr_common_config.dcoc_tza_step_03_init >> 16) / (xcvr_common_config.dcoc_tza_step_02_init >> 16);
igor Stepura 0:bb6687c3a462 697 break;
igor Stepura 0:bb6687c3a462 698 case TZA_STEP_N4:
igor Stepura 0:bb6687c3a462 699 temp_step = temp_step * (xcvr_common_config.dcoc_tza_step_04_init >> 16) / (xcvr_common_config.dcoc_tza_step_03_init >> 16);
igor Stepura 0:bb6687c3a462 700 break;
igor Stepura 0:bb6687c3a462 701 case TZA_STEP_N5:
igor Stepura 0:bb6687c3a462 702 temp_step = temp_step * (xcvr_common_config.dcoc_tza_step_05_init >> 16) / (xcvr_common_config.dcoc_tza_step_04_init >> 16);
igor Stepura 0:bb6687c3a462 703 break;
igor Stepura 0:bb6687c3a462 704 case TZA_STEP_N6:
igor Stepura 0:bb6687c3a462 705 temp_step = temp_step * (xcvr_common_config.dcoc_tza_step_06_init >> 16) / (xcvr_common_config.dcoc_tza_step_05_init >> 16);
igor Stepura 0:bb6687c3a462 706 break;
igor Stepura 0:bb6687c3a462 707 case TZA_STEP_N7:
igor Stepura 0:bb6687c3a462 708 temp_step = temp_step * (xcvr_common_config.dcoc_tza_step_07_init >> 16) / (xcvr_common_config.dcoc_tza_step_06_init >> 16);
igor Stepura 0:bb6687c3a462 709 break;
igor Stepura 0:bb6687c3a462 710 case TZA_STEP_N8:
igor Stepura 0:bb6687c3a462 711 temp_step = temp_step * (xcvr_common_config.dcoc_tza_step_08_init >> 16) / (xcvr_common_config.dcoc_tza_step_07_init >> 16);
igor Stepura 0:bb6687c3a462 712 break;
igor Stepura 0:bb6687c3a462 713 case TZA_STEP_N9:
igor Stepura 0:bb6687c3a462 714 temp_step = temp_step * (xcvr_common_config.dcoc_tza_step_09_init >> 16) / (xcvr_common_config.dcoc_tza_step_08_init >> 16);
igor Stepura 0:bb6687c3a462 715 break;
igor Stepura 0:bb6687c3a462 716 case TZA_STEP_N10:
igor Stepura 0:bb6687c3a462 717 temp_step = temp_step * (xcvr_common_config.dcoc_tza_step_10_init >> 16) / (xcvr_common_config.dcoc_tza_step_09_init >> 16);
igor Stepura 0:bb6687c3a462 718 break;
igor Stepura 0:bb6687c3a462 719 default:
igor Stepura 0:bb6687c3a462 720 break;
igor Stepura 0:bb6687c3a462 721 }
igor Stepura 0:bb6687c3a462 722
igor Stepura 0:bb6687c3a462 723 tza_dcoc_step[i-TZA_STEP_N0].dcoc_step = (uint32_t)roundf(temp_step * 8);
igor Stepura 0:bb6687c3a462 724 tza_dcoc_step[i-TZA_STEP_N0].dcoc_step_rcp = (uint32_t)roundf((float)0x8000 / temp_step);
igor Stepura 0:bb6687c3a462 725 }
igor Stepura 0:bb6687c3a462 726
igor Stepura 0:bb6687c3a462 727 /* Make the trims active */
igor Stepura 0:bb6687c3a462 728 XCVR_RX_DIG->DCOC_BBA_STEP = XCVR_RX_DIG_DCOC_BBA_STEP_BBA_DCOC_STEP(bbf_dcoc_step) | XCVR_RX_DIG_DCOC_BBA_STEP_BBA_DCOC_STEP_RECIP(bbf_dcoc_step_rcp);
igor Stepura 0:bb6687c3a462 729 XCVR_RX_DIG->DCOC_TZA_STEP_0 = XCVR_RX_DIG_DCOC_TZA_STEP_0_DCOC_TZA_STEP_GAIN_0(tza_dcoc_step[0].dcoc_step) | XCVR_RX_DIG_DCOC_TZA_STEP_0_DCOC_TZA_STEP_RCP_0(tza_dcoc_step[0].dcoc_step_rcp);
igor Stepura 0:bb6687c3a462 730 XCVR_RX_DIG->DCOC_TZA_STEP_1 = XCVR_RX_DIG_DCOC_TZA_STEP_1_DCOC_TZA_STEP_GAIN_1(tza_dcoc_step[1].dcoc_step) | XCVR_RX_DIG_DCOC_TZA_STEP_1_DCOC_TZA_STEP_RCP_1(tza_dcoc_step[1].dcoc_step_rcp);
igor Stepura 0:bb6687c3a462 731 XCVR_RX_DIG->DCOC_TZA_STEP_2 = XCVR_RX_DIG_DCOC_TZA_STEP_2_DCOC_TZA_STEP_GAIN_2(tza_dcoc_step[2].dcoc_step) | XCVR_RX_DIG_DCOC_TZA_STEP_2_DCOC_TZA_STEP_RCP_2(tza_dcoc_step[2].dcoc_step_rcp);
igor Stepura 0:bb6687c3a462 732 XCVR_RX_DIG->DCOC_TZA_STEP_3 = XCVR_RX_DIG_DCOC_TZA_STEP_3_DCOC_TZA_STEP_GAIN_3(tza_dcoc_step[3].dcoc_step) | XCVR_RX_DIG_DCOC_TZA_STEP_3_DCOC_TZA_STEP_RCP_3(tza_dcoc_step[3].dcoc_step_rcp);
igor Stepura 0:bb6687c3a462 733 XCVR_RX_DIG->DCOC_TZA_STEP_4 = XCVR_RX_DIG_DCOC_TZA_STEP_4_DCOC_TZA_STEP_GAIN_4(tza_dcoc_step[4].dcoc_step) | XCVR_RX_DIG_DCOC_TZA_STEP_4_DCOC_TZA_STEP_RCP_4(tza_dcoc_step[4].dcoc_step_rcp);
igor Stepura 0:bb6687c3a462 734 XCVR_RX_DIG->DCOC_TZA_STEP_5 = XCVR_RX_DIG_DCOC_TZA_STEP_5_DCOC_TZA_STEP_GAIN_5(tza_dcoc_step[5].dcoc_step) | XCVR_RX_DIG_DCOC_TZA_STEP_5_DCOC_TZA_STEP_RCP_5(tza_dcoc_step[5].dcoc_step_rcp);
igor Stepura 0:bb6687c3a462 735 XCVR_RX_DIG->DCOC_TZA_STEP_6 = XCVR_RX_DIG_DCOC_TZA_STEP_6_DCOC_TZA_STEP_GAIN_6(tza_dcoc_step[6].dcoc_step) | XCVR_RX_DIG_DCOC_TZA_STEP_6_DCOC_TZA_STEP_RCP_6(tza_dcoc_step[6].dcoc_step_rcp);
igor Stepura 0:bb6687c3a462 736 XCVR_RX_DIG->DCOC_TZA_STEP_7 = XCVR_RX_DIG_DCOC_TZA_STEP_7_DCOC_TZA_STEP_GAIN_7(tza_dcoc_step[7].dcoc_step) | XCVR_RX_DIG_DCOC_TZA_STEP_7_DCOC_TZA_STEP_RCP_7(tza_dcoc_step[7].dcoc_step_rcp);
igor Stepura 0:bb6687c3a462 737 XCVR_RX_DIG->DCOC_TZA_STEP_8 = XCVR_RX_DIG_DCOC_TZA_STEP_8_DCOC_TZA_STEP_GAIN_8(tza_dcoc_step[8].dcoc_step) | XCVR_RX_DIG_DCOC_TZA_STEP_8_DCOC_TZA_STEP_RCP_8(tza_dcoc_step[8].dcoc_step_rcp);
igor Stepura 0:bb6687c3a462 738 XCVR_RX_DIG->DCOC_TZA_STEP_9 = XCVR_RX_DIG_DCOC_TZA_STEP_9_DCOC_TZA_STEP_GAIN_9(tza_dcoc_step[9].dcoc_step) | XCVR_RX_DIG_DCOC_TZA_STEP_9_DCOC_TZA_STEP_RCP_9(tza_dcoc_step[9].dcoc_step_rcp);
igor Stepura 0:bb6687c3a462 739 XCVR_RX_DIG->DCOC_TZA_STEP_10 = XCVR_RX_DIG_DCOC_TZA_STEP_10_DCOC_TZA_STEP_GAIN_10(tza_dcoc_step[10].dcoc_step) | XCVR_RX_DIG_DCOC_TZA_STEP_10_DCOC_TZA_STEP_RCP_10(tza_dcoc_step[10].dcoc_step_rcp);
igor Stepura 0:bb6687c3a462 740
igor Stepura 0:bb6687c3a462 741 status = 1; /* Success */
igor Stepura 0:bb6687c3a462 742 }
igor Stepura 0:bb6687c3a462 743 else
igor Stepura 0:bb6687c3a462 744 {
igor Stepura 0:bb6687c3a462 745 status = 0; /* Failure */
igor Stepura 0:bb6687c3a462 746 }
igor Stepura 0:bb6687c3a462 747
igor Stepura 0:bb6687c3a462 748 /* Restore Registers */
igor Stepura 0:bb6687c3a462 749 XCVR_RX_DIG->DCOC_CTRL_0 = dcoc_ctrl_0_stack; /* Restore DCOC_CTRL_0 state to prior settings */
igor Stepura 0:bb6687c3a462 750 XCVR_RX_DIG->DCOC_CTRL_1 = dcoc_ctrl_1_stack; /* Restore DCOC_CTRL_1 state to prior settings */
igor Stepura 0:bb6687c3a462 751 XCVR_RX_DIG->RX_DIG_CTRL = rx_dig_ctrl_stack; /* Restore RX_DIG_CTRL state to prior settings */
igor Stepura 0:bb6687c3a462 752 XCVR_RX_DIG->DCOC_CAL_GAIN = dcoc_cal_gain_state; /* Restore DCOC_CAL_GAIN state to prior setting */
igor Stepura 0:bb6687c3a462 753 XCVR_RX_DIG->AGC_CTRL_1 = agc_ctrl_1_stack; /* Save state of RX_DIG_CTRL for later restore */
igor Stepura 0:bb6687c3a462 754
igor Stepura 0:bb6687c3a462 755 return status;
igor Stepura 0:bb6687c3a462 756 }
igor Stepura 0:bb6687c3a462 757
igor Stepura 0:bb6687c3a462 758 /*! *********************************************************************************
igor Stepura 0:bb6687c3a462 759 * DCOC_DAC_INIT_Cal : slope sign seek depending on measure's sign
igor Stepura 0:bb6687c3a462 760 ***********************************************************************************/
igor Stepura 0:bb6687c3a462 761 void DCOC_DAC_INIT_Cal(uint8_t standalone_operation)
igor Stepura 0:bb6687c3a462 762 {
igor Stepura 0:bb6687c3a462 763 int16_t dc_meas_i = 2000, dc_meas_i_p = 2000;
igor Stepura 0:bb6687c3a462 764 int16_t dc_meas_q = 2000, dc_meas_q_p = 2000;
igor Stepura 0:bb6687c3a462 765 uint8_t curr_tza_dac_i, curr_tza_dac_q;
igor Stepura 0:bb6687c3a462 766 uint8_t curr_bba_dac_i, curr_bba_dac_q;
igor Stepura 0:bb6687c3a462 767 uint8_t p_tza_dac_i = 0, p_tza_dac_q = 0;
igor Stepura 0:bb6687c3a462 768 uint8_t p_bba_dac_i = 0, p_bba_dac_q = 0;
igor Stepura 0:bb6687c3a462 769 uint8_t i = 0;
igor Stepura 0:bb6687c3a462 770 uint8_t bba_gain = 11;
igor Stepura 0:bb6687c3a462 771 bool TZA_I_OK = 0, TZA_Q_OK = 0, BBA_I_OK = 0, BBA_Q_OK = 0;
igor Stepura 0:bb6687c3a462 772
igor Stepura 0:bb6687c3a462 773 uint32_t dcoc_ctrl_0_stack;
igor Stepura 0:bb6687c3a462 774 uint32_t dcoc_ctrl_1_stack;
igor Stepura 0:bb6687c3a462 775 uint32_t agc_ctrl_1_stack;
igor Stepura 0:bb6687c3a462 776 uint32_t rx_dig_ctrl_stack;
igor Stepura 0:bb6687c3a462 777 uint32_t dcoc_cal_gain_state;
igor Stepura 0:bb6687c3a462 778 uint32_t xcvr_ctrl_stack = 0;
igor Stepura 0:bb6687c3a462 779
igor Stepura 0:bb6687c3a462 780 uint32_t temp;
igor Stepura 0:bb6687c3a462 781
igor Stepura 0:bb6687c3a462 782 /* Save registers */
igor Stepura 0:bb6687c3a462 783 dcoc_ctrl_0_stack = XCVR_RX_DIG->DCOC_CTRL_0; /* Save state of DCOC_CTRL_0 for later restore */
igor Stepura 0:bb6687c3a462 784 dcoc_ctrl_1_stack = XCVR_RX_DIG->DCOC_CTRL_1; /* Save state of DCOC_CTRL_1 for later restore */
igor Stepura 0:bb6687c3a462 785 rx_dig_ctrl_stack = XCVR_RX_DIG->RX_DIG_CTRL; /* Save state of RX_DIG_CTRL for later restore */
igor Stepura 0:bb6687c3a462 786 agc_ctrl_1_stack = XCVR_RX_DIG->AGC_CTRL_1; /* Save state of RX_DIG_CTRL for later restore */
igor Stepura 0:bb6687c3a462 787 dcoc_cal_gain_state = XCVR_RX_DIG->DCOC_CAL_GAIN; /* Save state of DCOC_CAL_GAIN for later restore */
igor Stepura 0:bb6687c3a462 788
igor Stepura 0:bb6687c3a462 789 /* WarmUp */
igor Stepura 0:bb6687c3a462 790 if (standalone_operation)
igor Stepura 0:bb6687c3a462 791 {
igor Stepura 0:bb6687c3a462 792 temp = XCVR_MISC->XCVR_CTRL;
igor Stepura 0:bb6687c3a462 793 xcvr_ctrl_stack = temp;
igor Stepura 0:bb6687c3a462 794 temp &= ~(XCVR_CTRL_XCVR_CTRL_PROTOCOL_MASK);
igor Stepura 0:bb6687c3a462 795 temp |= XCVR_CTRL_XCVR_CTRL_PROTOCOL(0);
igor Stepura 0:bb6687c3a462 796 XCVR_MISC->XCVR_CTRL = temp;
igor Stepura 0:bb6687c3a462 797 XCVR_OverrideChannel(12, 1); /* Calibrate on channel #12, 2.426 GHz in BLE map */
igor Stepura 0:bb6687c3a462 798 XCVR_ForceRxWu();
igor Stepura 0:bb6687c3a462 799 XcvrCalDelay(2000);
igor Stepura 0:bb6687c3a462 800 }
igor Stepura 0:bb6687c3a462 801
igor Stepura 0:bb6687c3a462 802 /* Register config */
igor Stepura 0:bb6687c3a462 803 /* Ensure AGC, DCOC and RX_DIG_CTRL is in correct mode */
igor Stepura 0:bb6687c3a462 804 temp = XCVR_RX_DIG->RX_DIG_CTRL;
igor Stepura 0:bb6687c3a462 805 temp &= ~XCVR_RX_DIG_RX_DIG_CTRL_RX_AGC_EN_MASK; /* Turn OFF AGC */
igor Stepura 0:bb6687c3a462 806 temp &= ~XCVR_RX_DIG_RX_DIG_CTRL_RX_DCOC_CAL_EN_MASK; /* Disable for SW control of DCOC */
igor Stepura 0:bb6687c3a462 807 temp &= ~XCVR_RX_DIG_RX_DIG_CTRL_RX_DC_RESID_EN_MASK; /* Disable for SW control of DCOC */
igor Stepura 0:bb6687c3a462 808 XCVR_RX_DIG->RX_DIG_CTRL = temp;
igor Stepura 0:bb6687c3a462 809
igor Stepura 0:bb6687c3a462 810 XCVR_RX_DIG->AGC_CTRL_1 = XCVR_RX_DIG_AGC_CTRL_1_USER_LNA_GAIN_EN(1) | /* Enable LNA Manual Gain */
igor Stepura 0:bb6687c3a462 811 XCVR_RX_DIG_AGC_CTRL_1_USER_BBA_GAIN_EN(1) | /* Enable BBA Manual Gain */
igor Stepura 0:bb6687c3a462 812 XCVR_RX_DIG_AGC_CTRL_1_LNA_USER_GAIN(0x0) | /* Set LNA Manual Gain */
igor Stepura 0:bb6687c3a462 813 XCVR_RX_DIG_AGC_CTRL_1_BBA_USER_GAIN(0x0); /* Set BBA Manual Gain */
igor Stepura 0:bb6687c3a462 814
igor Stepura 0:bb6687c3a462 815 /* DCOC_CTRL_0 @ 4005_C02C -- Define default DCOC DAC settings in manual mode */
igor Stepura 0:bb6687c3a462 816 temp = XCVR_RX_DIG->DCOC_CTRL_0;
igor Stepura 0:bb6687c3a462 817 temp |= XCVR_RX_DIG_DCOC_CTRL_0_DCOC_MAN(1); /* Enable Manual DCOC */
igor Stepura 0:bb6687c3a462 818 temp |= XCVR_RX_DIG_DCOC_CTRL_0_DCOC_CORRECT_SRC(1); /* Ensure DCOC Tracking is enabled */
igor Stepura 0:bb6687c3a462 819 temp |= XCVR_RX_DIG_DCOC_CTRL_0_DCOC_TRK_EST_OVR(1); /* Enable DC Estimator */
igor Stepura 0:bb6687c3a462 820 temp |= XCVR_RX_DIG_DCOC_CTRL_0_DCOC_CORRECT_EN(1); /* Ensure DC correction is enabled */
igor Stepura 0:bb6687c3a462 821 XCVR_RX_DIG->DCOC_CTRL_0 = temp;
igor Stepura 0:bb6687c3a462 822
igor Stepura 0:bb6687c3a462 823 XcvrCalDelay(TsettleCal);
igor Stepura 0:bb6687c3a462 824
igor Stepura 0:bb6687c3a462 825 /* Set default DCOC DAC INIT Value */
igor Stepura 0:bb6687c3a462 826 /* LNA and BBA DAC Sweep */
igor Stepura 0:bb6687c3a462 827 curr_bba_dac_i = 0x20;
igor Stepura 0:bb6687c3a462 828 curr_bba_dac_q = 0x20;
igor Stepura 0:bb6687c3a462 829 curr_tza_dac_i = 0x80;
igor Stepura 0:bb6687c3a462 830 curr_tza_dac_q = 0x80;
igor Stepura 0:bb6687c3a462 831
igor Stepura 0:bb6687c3a462 832 /* Perform a first DC measurement to ensure that measurement is not clipping */
igor Stepura 0:bb6687c3a462 833 XCVR_RX_DIG->DCOC_DAC_INIT = XCVR_RX_DIG_DCOC_DAC_INIT_BBA_DCOC_INIT_I(curr_bba_dac_i) |
igor Stepura 0:bb6687c3a462 834 XCVR_RX_DIG_DCOC_DAC_INIT_BBA_DCOC_INIT_Q(curr_bba_dac_q) |
igor Stepura 0:bb6687c3a462 835 XCVR_RX_DIG_DCOC_DAC_INIT_TZA_DCOC_INIT_I(curr_tza_dac_i) |
igor Stepura 0:bb6687c3a462 836 XCVR_RX_DIG_DCOC_DAC_INIT_TZA_DCOC_INIT_Q(curr_tza_dac_q);
igor Stepura 0:bb6687c3a462 837
igor Stepura 0:bb6687c3a462 838 do
igor Stepura 0:bb6687c3a462 839 {
igor Stepura 0:bb6687c3a462 840 bba_gain--;
igor Stepura 0:bb6687c3a462 841 /* Set DAC user gain */
igor Stepura 0:bb6687c3a462 842 XCVR_RX_DIG->AGC_CTRL_1 = XCVR_RX_DIG_AGC_CTRL_1_USER_LNA_GAIN_EN(1) |
igor Stepura 0:bb6687c3a462 843 XCVR_RX_DIG_AGC_CTRL_1_LNA_USER_GAIN(0) | /* 2 */
igor Stepura 0:bb6687c3a462 844 XCVR_RX_DIG_AGC_CTRL_1_USER_BBA_GAIN_EN(1) |
igor Stepura 0:bb6687c3a462 845 XCVR_RX_DIG_AGC_CTRL_1_BBA_USER_GAIN(bba_gain) ; /* 10 */
igor Stepura 0:bb6687c3a462 846 XcvrCalDelay(TsettleCal * 2);
igor Stepura 0:bb6687c3a462 847 rx_dc_est_average(&dc_meas_i, &dc_meas_q, 64);
igor Stepura 0:bb6687c3a462 848 } while ((ABS(dc_meas_i) > 1900) | (ABS(dc_meas_q) > 1900));
igor Stepura 0:bb6687c3a462 849
igor Stepura 0:bb6687c3a462 850 for (i = 0; i < 0x0F; i++)
igor Stepura 0:bb6687c3a462 851 {
igor Stepura 0:bb6687c3a462 852 /* I channel : */
igor Stepura 0:bb6687c3a462 853 if (!TZA_I_OK)
igor Stepura 0:bb6687c3a462 854 {
igor Stepura 0:bb6687c3a462 855 if ((ISIGN(dc_meas_i) != ISIGN(dc_meas_i_p)) && (i > 0))
igor Stepura 0:bb6687c3a462 856 {
igor Stepura 0:bb6687c3a462 857 if (ABS(dc_meas_i) != MIN(ABS(dc_meas_i), ABS(dc_meas_i_p)))
igor Stepura 0:bb6687c3a462 858 {
igor Stepura 0:bb6687c3a462 859 curr_tza_dac_i = p_tza_dac_i;
igor Stepura 0:bb6687c3a462 860 }
igor Stepura 0:bb6687c3a462 861
igor Stepura 0:bb6687c3a462 862 TZA_I_OK = 1;
igor Stepura 0:bb6687c3a462 863 }
igor Stepura 0:bb6687c3a462 864 else
igor Stepura 0:bb6687c3a462 865 {
igor Stepura 0:bb6687c3a462 866 p_tza_dac_i = curr_tza_dac_i;
igor Stepura 0:bb6687c3a462 867
igor Stepura 0:bb6687c3a462 868 if (ISIGN(dc_meas_i)) /* If positif */
igor Stepura 0:bb6687c3a462 869 {
igor Stepura 0:bb6687c3a462 870 curr_tza_dac_i--;
igor Stepura 0:bb6687c3a462 871 }
igor Stepura 0:bb6687c3a462 872 else
igor Stepura 0:bb6687c3a462 873 {
igor Stepura 0:bb6687c3a462 874 curr_tza_dac_i++;
igor Stepura 0:bb6687c3a462 875 }
igor Stepura 0:bb6687c3a462 876 }
igor Stepura 0:bb6687c3a462 877 }
igor Stepura 0:bb6687c3a462 878 else /* Sweep BBA I */
igor Stepura 0:bb6687c3a462 879 {
igor Stepura 0:bb6687c3a462 880 if (!BBA_I_OK)
igor Stepura 0:bb6687c3a462 881 {
igor Stepura 0:bb6687c3a462 882 if ((ISIGN(dc_meas_i) != ISIGN(dc_meas_i_p)) && (curr_bba_dac_i != 0x20))
igor Stepura 0:bb6687c3a462 883 {
igor Stepura 0:bb6687c3a462 884 if (ABS(dc_meas_i) != MIN(ABS(dc_meas_i), ABS(dc_meas_i_p)))
igor Stepura 0:bb6687c3a462 885 {
igor Stepura 0:bb6687c3a462 886 curr_bba_dac_i = p_bba_dac_i;
igor Stepura 0:bb6687c3a462 887 }
igor Stepura 0:bb6687c3a462 888
igor Stepura 0:bb6687c3a462 889 BBA_I_OK = 1;
igor Stepura 0:bb6687c3a462 890 }
igor Stepura 0:bb6687c3a462 891 else
igor Stepura 0:bb6687c3a462 892 {
igor Stepura 0:bb6687c3a462 893 p_bba_dac_i = curr_bba_dac_i;
igor Stepura 0:bb6687c3a462 894 if (ISIGN(dc_meas_i)) /* If positif */
igor Stepura 0:bb6687c3a462 895 {
igor Stepura 0:bb6687c3a462 896 curr_bba_dac_i--;
igor Stepura 0:bb6687c3a462 897 }
igor Stepura 0:bb6687c3a462 898 else
igor Stepura 0:bb6687c3a462 899 {
igor Stepura 0:bb6687c3a462 900 curr_bba_dac_i++;
igor Stepura 0:bb6687c3a462 901 }
igor Stepura 0:bb6687c3a462 902 }
igor Stepura 0:bb6687c3a462 903 }
igor Stepura 0:bb6687c3a462 904 }
igor Stepura 0:bb6687c3a462 905
igor Stepura 0:bb6687c3a462 906 /* Q channel : */
igor Stepura 0:bb6687c3a462 907 if (!TZA_Q_OK)
igor Stepura 0:bb6687c3a462 908 {
igor Stepura 0:bb6687c3a462 909 if ((ISIGN(dc_meas_q) != ISIGN(dc_meas_q_p)) && (i > 0))
igor Stepura 0:bb6687c3a462 910 {
igor Stepura 0:bb6687c3a462 911 if (ABS(dc_meas_q) != MIN(ABS(dc_meas_q), ABS(dc_meas_q_p)))
igor Stepura 0:bb6687c3a462 912 {
igor Stepura 0:bb6687c3a462 913 curr_tza_dac_q = p_tza_dac_q;
igor Stepura 0:bb6687c3a462 914 }
igor Stepura 0:bb6687c3a462 915 TZA_Q_OK = 1;
igor Stepura 0:bb6687c3a462 916 }
igor Stepura 0:bb6687c3a462 917 else
igor Stepura 0:bb6687c3a462 918 {
igor Stepura 0:bb6687c3a462 919 p_tza_dac_q = curr_tza_dac_q;
igor Stepura 0:bb6687c3a462 920 if (ISIGN(dc_meas_q)) /* If positif */
igor Stepura 0:bb6687c3a462 921 {
igor Stepura 0:bb6687c3a462 922 curr_tza_dac_q--;
igor Stepura 0:bb6687c3a462 923 }
igor Stepura 0:bb6687c3a462 924 else
igor Stepura 0:bb6687c3a462 925 {
igor Stepura 0:bb6687c3a462 926 curr_tza_dac_q++;
igor Stepura 0:bb6687c3a462 927 }
igor Stepura 0:bb6687c3a462 928 }
igor Stepura 0:bb6687c3a462 929 }
igor Stepura 0:bb6687c3a462 930 else /* Sweep BBA Q */
igor Stepura 0:bb6687c3a462 931 {
igor Stepura 0:bb6687c3a462 932 if (!BBA_Q_OK)
igor Stepura 0:bb6687c3a462 933 {
igor Stepura 0:bb6687c3a462 934 if ((ISIGN(dc_meas_q) != ISIGN(dc_meas_q_p)) && (curr_bba_dac_q != 0x20))
igor Stepura 0:bb6687c3a462 935 {
igor Stepura 0:bb6687c3a462 936 if (ABS(dc_meas_q) != MIN(ABS(dc_meas_q), ABS(dc_meas_q_p)))
igor Stepura 0:bb6687c3a462 937 {
igor Stepura 0:bb6687c3a462 938 curr_bba_dac_q = p_bba_dac_q;
igor Stepura 0:bb6687c3a462 939 }
igor Stepura 0:bb6687c3a462 940 BBA_Q_OK = 1;
igor Stepura 0:bb6687c3a462 941 }
igor Stepura 0:bb6687c3a462 942 else
igor Stepura 0:bb6687c3a462 943 {
igor Stepura 0:bb6687c3a462 944 p_bba_dac_q = curr_bba_dac_q;
igor Stepura 0:bb6687c3a462 945 if (ISIGN(dc_meas_q)) /* If positif */
igor Stepura 0:bb6687c3a462 946 {
igor Stepura 0:bb6687c3a462 947 curr_bba_dac_q--;
igor Stepura 0:bb6687c3a462 948 }
igor Stepura 0:bb6687c3a462 949 else
igor Stepura 0:bb6687c3a462 950 {
igor Stepura 0:bb6687c3a462 951 curr_bba_dac_q++;
igor Stepura 0:bb6687c3a462 952 }
igor Stepura 0:bb6687c3a462 953 }
igor Stepura 0:bb6687c3a462 954 }
igor Stepura 0:bb6687c3a462 955 }
igor Stepura 0:bb6687c3a462 956
igor Stepura 0:bb6687c3a462 957 /* DC OK break : */
igor Stepura 0:bb6687c3a462 958 if (TZA_I_OK && TZA_Q_OK && BBA_I_OK && BBA_Q_OK)
igor Stepura 0:bb6687c3a462 959 {
igor Stepura 0:bb6687c3a462 960 break;
igor Stepura 0:bb6687c3a462 961 }
igor Stepura 0:bb6687c3a462 962
igor Stepura 0:bb6687c3a462 963 dc_meas_i_p = dc_meas_i; /* Store as previous value */
igor Stepura 0:bb6687c3a462 964 dc_meas_q_p = dc_meas_q; /* Store as previous value */
igor Stepura 0:bb6687c3a462 965 XCVR_RX_DIG->DCOC_DAC_INIT = XCVR_RX_DIG_DCOC_DAC_INIT_BBA_DCOC_INIT_I(curr_bba_dac_i) |
igor Stepura 0:bb6687c3a462 966 XCVR_RX_DIG_DCOC_DAC_INIT_BBA_DCOC_INIT_Q(curr_bba_dac_q) |
igor Stepura 0:bb6687c3a462 967 XCVR_RX_DIG_DCOC_DAC_INIT_TZA_DCOC_INIT_I(curr_tza_dac_i) |
igor Stepura 0:bb6687c3a462 968 XCVR_RX_DIG_DCOC_DAC_INIT_TZA_DCOC_INIT_Q(curr_tza_dac_q);
igor Stepura 0:bb6687c3a462 969 XcvrCalDelay(TsettleCal * 2);
igor Stepura 0:bb6687c3a462 970 rx_dc_est_average(&dc_meas_i, &dc_meas_q, 64);
igor Stepura 0:bb6687c3a462 971 }
igor Stepura 0:bb6687c3a462 972
igor Stepura 0:bb6687c3a462 973 /* Apply optimized DCOC DAC INIT : */
igor Stepura 0:bb6687c3a462 974 XCVR_RX_DIG->DCOC_DAC_INIT = XCVR_RX_DIG_DCOC_DAC_INIT_BBA_DCOC_INIT_I(curr_bba_dac_i) |
igor Stepura 0:bb6687c3a462 975 XCVR_RX_DIG_DCOC_DAC_INIT_BBA_DCOC_INIT_Q(curr_bba_dac_q) |
igor Stepura 0:bb6687c3a462 976 XCVR_RX_DIG_DCOC_DAC_INIT_TZA_DCOC_INIT_I(curr_tza_dac_i) |
igor Stepura 0:bb6687c3a462 977 XCVR_RX_DIG_DCOC_DAC_INIT_TZA_DCOC_INIT_Q(curr_tza_dac_q);
igor Stepura 0:bb6687c3a462 978
igor Stepura 0:bb6687c3a462 979 /* WarmDown */
igor Stepura 0:bb6687c3a462 980 if (standalone_operation)
igor Stepura 0:bb6687c3a462 981 {
igor Stepura 0:bb6687c3a462 982 XCVR_ForceRxWd(); /* Don't leave the receiver running. */
igor Stepura 0:bb6687c3a462 983 XcvrCalDelay(200);
igor Stepura 0:bb6687c3a462 984 XCVR_OverrideChannel(0xFF,1); /* Release channel overrides */
igor Stepura 0:bb6687c3a462 985 XCVR_MISC->XCVR_CTRL = xcvr_ctrl_stack;
igor Stepura 0:bb6687c3a462 986 }
igor Stepura 0:bb6687c3a462 987
igor Stepura 0:bb6687c3a462 988 /* Restore register */
igor Stepura 0:bb6687c3a462 989 XCVR_RX_DIG->DCOC_CTRL_0 = dcoc_ctrl_0_stack; /* Restore DCOC_CTRL_0 state to prior settings */
igor Stepura 0:bb6687c3a462 990 XCVR_RX_DIG->DCOC_CTRL_1 = dcoc_ctrl_1_stack; /* Restore DCOC_CTRL_1 state to prior settings */
igor Stepura 0:bb6687c3a462 991 XCVR_RX_DIG->RX_DIG_CTRL = rx_dig_ctrl_stack; /* Restore RX_DIG_CTRL state to prior settings */
igor Stepura 0:bb6687c3a462 992 XCVR_RX_DIG->DCOC_CAL_GAIN = dcoc_cal_gain_state; /* Restore DCOC_CAL_GAIN state to prior setting */
igor Stepura 0:bb6687c3a462 993 XCVR_RX_DIG->AGC_CTRL_1 = agc_ctrl_1_stack; /* Save state of RX_DIG_CTRL for later restore */
igor Stepura 0:bb6687c3a462 994 }
igor Stepura 0:bb6687c3a462 995