Post Go back to editing

AGC support in ADRV9025

Hi Team,

I want to implement the AGC feature in ADRV9025.

Before that, I have some queries, please help out me with this. By default, we are using MGC mode.

1. There are 4 options available in AGC (MGC, AGCFAST, AGCSLOW, HYBRID mode).

    In Hybrid mode, let us say, the Index is changing in one direction only, say from 255 to 183. (Vice-versa is not happening)

    In AGCFAST mode, the Index is not at all changing.

    In AGCSLOW mode, I can able to see the Index variations as per the input signal power (In both directions)

2. By default the step size is 0.5dB, so for each digit index change, I'm assuming that there is a 0.5dB attenuation added by ADRV. (I haven't seen much linearity wrt step size)

    Is my understanding correct?

3. I want to change the Max and Min limits of the GainIndex, so we implemented the user menu using API adi_adrv9025_AgcCfg_t to change the minimum value.

    But after changing the MinIndex value from 183 to 170, I'm not seeing any variation in RxGainIndex values. (My gain Table is having the values till 183 only, is it limiting this)

    If yes, pls provide the Gain table to 170 values. I have attached the GainTable which was used by me. (I want to understand how this gain table is calculatedd based on the profile selection)

Can you briefly explain all these effects?

Gain Index,FE Control Word,TIA Control,ADC Control,Ext Control,Phase Offset,Digital Gain
0,0,0,0,0,0,0
1,0,0,0,0,0,0
2,0,0,0,0,0,0
3,0,0,0,0,0,0
4,0,0,0,0,0,0
5,0,0,0,0,0,0
6,0,0,0,0,0,0
7,0,0,0,0,0,0
8,0,0,0,0,0,0
9,0,0,0,0,0,0
10,0,0,0,0,0,0
11,0,0,0,0,0,0
12,0,0,0,0,0,0
13,0,0,0,0,0,0
14,0,0,0,0,0,0
15,0,0,0,0,0,0
16,0,0,0,0,0,0
17,0,0,0,0,0,0
18,0,0,0,0,0,0
19,0,0,0,0,0,0
20,0,0,0,0,0,0
21,0,0,0,0,0,0
22,0,0,0,0,0,0
23,0,0,0,0,0,0
24,0,0,0,0,0,0
25,0,0,0,0,0,0
26,0,0,0,0,0,0
27,0,0,0,0,0,0
28,0,0,0,0,0,0
29,0,0,0,0,0,0
30,0,0,0,0,0,0
31,0,0,0,0,0,0
32,0,0,0,0,0,0
33,0,0,0,0,0,0
34,0,0,0,0,0,0
35,0,0,0,0,0,0
36,0,0,0,0,0,0
37,0,0,0,0,0,0
38,0,0,0,0,0,0
39,0,0,0,0,0,0
40,0,0,0,0,0,0
41,0,0,0,0,0,0
42,0,0,0,0,0,0
43,0,0,0,0,0,0
44,0,0,0,0,0,0
45,0,0,0,0,0,0
46,0,0,0,0,0,0
47,0,0,0,0,0,0
48,0,0,0,0,0,0
49,0,0,0,0,0,0
50,0,0,0,0,0,0
51,0,0,0,0,0,0
52,0,0,0,0,0,0
53,0,0,0,0,0,0
54,0,0,0,0,0,0
55,0,0,0,0,0,0
56,0,0,0,0,0,0
57,0,0,0,0,0,0
58,0,0,0,0,0,0
59,0,0,0,0,0,0
60,0,0,0,0,0,0
61,0,0,0,0,0,0
62,0,0,0,0,0,0
63,0,0,0,0,0,0
64,0,0,0,0,0,0
65,0,0,0,0,0,0
66,0,0,0,0,0,0
67,0,0,0,0,0,0
68,0,0,0,0,0,0
69,0,0,0,0,0,0
70,0,0,0,0,0,0
71,0,0,0,0,0,0
72,0,0,0,0,0,0
73,0,0,0,0,0,0
74,0,0,0,0,0,0
75,0,0,0,0,0,0
76,0,0,0,0,0,0
77,0,0,0,0,0,0
78,0,0,0,0,0,0
79,0,0,0,0,0,0
80,0,0,0,0,0,0
81,0,0,0,0,0,0
82,0,0,0,0,0,0
83,0,0,0,0,0,0
84,0,0,0,0,0,0
85,0,0,0,0,0,0
86,0,0,0,0,0,0
87,0,0,0,0,0,0
88,0,0,0,0,0,0
89,0,0,0,0,0,0
90,0,0,0,0,0,0
91,0,0,0,0,0,0
92,0,0,0,0,0,0
93,0,0,0,0,0,0
94,0,0,0,0,0,0
95,0,0,0,0,0,0
96,0,0,0,0,0,0
97,0,0,0,0,0,0
98,0,0,0,0,0,0
99,0,0,0,0,0,0
100,0,0,0,0,0,0
101,0,0,0,0,0,0
102,0,0,0,0,0,0
103,0,0,0,0,0,0
104,0,0,0,0,0,0
105,0,0,0,0,0,0
106,0,0,0,0,0,0
107,0,0,0,0,0,0
108,0,0,0,0,0,0
109,0,0,0,0,0,0
110,0,0,0,0,0,0
111,0,0,0,0,0,0
112,0,0,0,0,0,0
113,0,0,0,0,0,0
114,0,0,0,0,0,0
115,0,0,0,0,0,0
116,0,0,0,0,0,0
117,0,0,0,0,0,0
118,0,0,0,0,0,0
119,0,0,0,0,0,0
120,0,0,0,0,0,0
121,0,0,0,0,0,0
122,0,0,0,0,0,0
123,0,0,0,0,0,0
124,0,0,0,0,0,0
125,0,0,0,0,0,0
126,0,0,0,0,0,0
127,0,0,0,0,0,0
128,0,0,0,0,0,0
129,0,0,0,0,0,0
130,0,0,0,0,0,0
131,0,0,0,0,0,0
132,0,0,0,0,0,0
133,0,0,0,0,0,0
134,0,0,0,0,0,0
135,0,0,0,0,0,0
136,0,0,0,0,0,0
137,0,0,0,0,0,0
138,0,0,0,0,0,0
139,0,0,0,0,0,0
140,0,0,0,0,0,0
141,0,0,0,0,0,0
142,0,0,0,0,0,0
143,0,0,0,0,0,0
144,0,0,0,0,0,0
145,0,0,0,0,0,0
146,0,0,0,0,0,0
147,0,0,0,0,0,0
148,0,0,0,0,0,0
149,0,0,0,0,0,0
150,0,0,0,0,0,0
151,0,0,0,0,0,0
152,0,0,0,0,0,0
153,0,0,0,0,0,0
154,0,0,0,0,0,0
155,0,0,0,0,0,0
156,0,0,0,0,0,0
157,0,0,0,0,0,0
158,0,0,0,0,0,0
159,0,0,0,0,0,0
160,0,0,0,0,0,0
161,0,0,0,0,0,0
162,0,0,0,0,0,0
163,0,0,0,0,0,0
164,0,0,0,0,0,0
165,0,0,0,0,0,0
166,0,0,0,0,0,0
167,0,0,0,0,0,0
168,0,0,0,0,0,0
169,0,0,0,0,0,0
170,0,0,0,0,0,0
171,0,0,0,0,0,0
172,0,0,0,0,0,0
173,0,0,0,0,0,0
174,0,0,0,0,0,0
175,0,0,0,0,0,0
176,0,0,0,0,0,0
177,0,0,0,0,0,0
178,0,0,0,0,0,0
179,0,0,0,0,0,0
180,0,0,0,0,0,0
181,0,0,0,0,0,0
182,0,0,0,0,0,0
183,252,0,0,0,0,0
184,251,0,0,0,0,-29
185,251,0,0,0,0,-19
186,251,0,0,0,0,-9
187,251,0,0,0,0,1
188,251,0,0,0,0,11
189,250,0,0,0,0,-11
190,250,0,0,0,0,-1
191,250,0,0,0,0,9
192,249,0,0,0,0,-10
193,249,0,0,0,0,0
194,248,0,0,0,0,-14
195,248,0,0,0,0,-4
196,248,0,0,0,0,6
197,247,0,0,0,0,-9
198,247,0,0,0,0,1
199,247,0,0,0,0,11
200,246,0,0,0,0,3
201,245,0,0,0,0,-5
202,245,0,0,0,0,5
203,244,0,0,0,0,0
204,243,0,0,0,0,-5
205,243,0,0,0,0,5
206,242,0,0,0,0,2
207,241,0,0,0,0,-1
208,240,0,0,0,0,-2
209,239,0,0,0,0,-4
210,238,0,0,0,0,-4
211,237,0,0,0,0,-4
212,236,0,0,0,0,-2
213,235,0,0,0,0,-2
214,234,0,0,0,0,0
215,233,0,0,0,0,2
216,231,0,0,0,0,-3
217,230,0,0,0,0,0
218,228,0,0,0,0,-3
219,227,0,0,0,0,1
220,225,0,0,0,0,-1
221,223,0,0,0,0,-1
222,221,0,0,0,0,-1
223,219,0,0,0,0,-1
224,217,0,0,0,0,0
225,215,0,0,0,0,0
226,213,0,0,0,0,2
227,210,0,0,0,0,0
228,207,0,0,0,0,-1
229,204,0,0,0,0,-1
230,201,0,0,0,0,-1
231,198,0,0,0,0,0
232,194,0,0,0,0,-1
233,190,0,0,0,0,-1
234,187,0,0,0,0,1
235,183,0,0,0,0,1
236,178,0,0,0,0,0
237,173,0,0,0,0,0
238,168,0,0,0,0,0
239,163,0,0,0,0,0
240,157,0,0,0,0,0
241,151,0,0,0,0,0
242,144,0,0,0,0,0
243,137,0,0,0,0,0
244,129,0,0,0,0,-1
245,121,0,0,0,0,0
246,113,0,0,0,0,0
247,104,0,0,0,0,0
248,94,0,0,0,0,0
249,83,0,0,0,0,0
250,72,0,0,0,0,0
251,59,0,0,0,0,0
252,45,0,0,0,0,0
253,30,0,0,0,0,0
254,15,0,0,0,0,0
255,0,0,0,0,0,0

Parents
  • Hi, 

    When I'm trying to set the default values itself, the AGC state machine looks like in RESET.

    No change in the RxGainIndex values by varying the Input signal after setting the values using API adi_adrv9025_AgcCfgSet.

    But I'm able to read the va;ues properly after setting it.

    Thanks,

    Srinivas

  • Thanks for the update.

    I would like to clarify few things:

    Hybrid mode is not supported by the chip.

    Also, we use min.gain index of 190 only and the other gain index below this are used for our internal calibrations and are not suggested for the users.

  • Hi Ramarao,

    I have a Python script for the AGC setup.

    When I'm running the script in the Evaluation Board, the following error is coming.

    Starts at 07/19/2023  11:26:33
    [Programming Device]
    System.Exception: ERROR while attempting to init board : ERROR: Product Name:9029CE01C; : ; : ; : ; : ;  Error number 7, Recovery action -6. In file ../../../../c_src/boards/daughterboards/adrv9025/src/adi_adrv9025_daughter_board.c, in function adi_adrv9025Board_Dispatch, in line 2037, variable name __null. Error message ERROR-Phase1 fail: DaughterBoard Error - 7, ERROR-Phase1 fail: DaughterBoard Error - 7, 
    .
    ERROR: ad9528Device Error number 8193, Recovery action -5. In file ../../../../c_src/devices/ad9528/public/src/adi_ad9528.c, in function adi_ad9528_PllLockDebounce, in line 773, variable name __null. Error message Ad9528 PLL Not locked.

     

       at adrv9010_dll.TopLevelClasses.AdrvDaughterCard.Program()
       at Microsoft.Scripting.Interpreter.ActionCallInstruction`1.Run(InterpretedFrame frame)
       at Microsoft.Scripting.Interpreter.Interpreter.Run(InterpretedFrame frame)
       at Microsoft.Scripting.Interpreter.LightLambda.Run3[T0,T1,T2,TRet](T0 arg0, T1 arg1, T2 arg2)
       at System.Dynamic.UpdateDelegates.UpdateAndExecute2[T0,T1,TRet](CallSite site, T0 arg0, T1 arg1)
       at Microsoft.Scripting.Interpreter.DynamicInstruction`3.Run(InterpretedFrame frame)
       at Microsoft.Scripting.Interpreter.Interpreter.Run(InterpretedFrame frame)
       at Microsoft.Scripting.Interpreter.LightLambda.Run2[T0,T1,TRet](T0 arg0, T1 arg1)
       at IronPython.Compiler.PythonScriptCode.RunWorker(CodeContext ctx)
       at Adi.Tpg.IronPythonWindow.ScriptHost.Execute(String expression)

    Please have a look at it.

    #################################################################################
    #GUI Version: 6.4.0.17
    #DLL Version: 6.4.0.14
    #Cmd Server Version: 6.4.0.14
    #FPGA Version: 0xD900000A
    #ARM Version: 6.4.0.6(ADI_ADRV9025_ARMBUILD_RELEASE)
    #StreamVersion: 9.4.0.1
    
    #Albert Chang.
    #Oct.2022
    #AGC function code.
    #starts from connection in GUI (TES)  
    #################################################################################
    
    #Import Reference to the DLL
    import System
    import clr
    import time
    from System import Array
    clr.AddReferenceToFileAndPath("C:\\Program Files\\Analog Devices\\ADRV9025 Transceiver Evaluation Software_x64_FULL\\adrvtrx_dll.dll")
    from adrv9010_dll import AdiEvaluationSystem
    from adrv9010_dll import Types
    from adrv9010_dll import Ad9528Types
    
    def spiRead(address):
        data = adrv9010.Hal.SpiByteRead(address, 0)
        print "SPI Read Address " + hex(address) + ": " + hex(data[1])
    
    def spiWrite(address, data):
        adrv9010.Hal.SpiByteWrite(address, data)
        print "SPI Write Address " + hex(address) + ": " + hex(data)
    
    def runTxQECInitCal(txChannel):
        errorFlag = 0
        txCals = Types.adi_adrv9010_InitCals_t()
        txCals.calMask = int(Types.adi_adrv9010_InitCalibrations_e.ADI_ADRV9010_TX_QEC_INIT)
        txCals.channelMask = txChannel
        txCals.warmBoot = 0
        link.platform.board.Adrv9010Device.Cals.InitCalsRun(txCals)
        link.platform.board.Adrv9010Device.Cals.InitCalsWait(1000, errorFlag)
    
    def rxGainSet(gain, rxChannelMask):                                             # manual gain set, Rx1=bit[0]=0x1, Rx1~ORx4=bit[0~7]=0xF
        adrv9010RxGain = Array.CreateInstance(Types.adi_adrv9010_RxGain_t, 1)
        adrv9010RxGain[0] = Types.adi_adrv9010_RxGain_t()    
        adrv9010RxGain[0].gainIndex = gain;
        adrv9010RxGain[0].rxChannelMask = rxChannelMask;
        link.platform.board.Adrv9010Device.Rx.RxGainSet(adrv9010RxGain, 1);
    
    def rxGainCtrlModeSet(agcMode_user, rxChannelMask_user):                                              
        adrv9010RxGainCtrlMode = Array.CreateInstance(Types.adi_adrv9010_RxAgcMode_t, 1)       
        adrv9010RxGainCtrlMode[0] = Types.adi_adrv9010_RxAgcMode_t()    
        adrv9010RxGainCtrlMode[0].agcMode = agcMode_user;                         # Types.adi_adrv9010_RxAgcMode_e. ...
        adrv9010RxGainCtrlMode[0].rxChannelMask = rxChannelMask_user;
        link.platform.board.Adrv9010Device.Rx.RxGainCtrlModeSet(adrv9010RxGainCtrlMode, 1); 
    
    def txAttenSet(atten, txChannelMask): 
        adrv9010TxAtten = Array.CreateInstance(Types.adi_adrv9010_TxAtten_t, 1)
        adrv9010TxAtten[0] = Types.adi_adrv9010_TxAtten_t()    
        adrv9010TxAtten[0].txAttenuation_mdB = atten * 1000.0;
        adrv9010TxAtten[0].txChannelMask = txChannelMask;
        link.platform.board.Adrv9010Device.Tx.TxAttenSet(adrv9010TxAtten, 1);
    
    
    #Create an Instance of the Class
    link = AdiEvaluationSystem.Instance	
    connect = False
    
    if (link.IsConnected() == False):
        connect = True
        link.platform.board.Client.Connect("192.168.1.10", 55556)
        print "Connecting"
    
    if (link.IsConnected()):
        localtime = time.localtime() 
        print "Starts at " + time.strftime("%m/%d/%Y  %H:%M:%S", localtime) + "\n[Programming Device]"
        link.platform.board.Adrv9010Device.ConfigFileLoad("C:\\Program Files\\Analog Devices\\ADRV9025 Transceiver Evaluation Software_x64_FULL\\Resources\\Adi.ADRV9025.Profiles\\public\\ADRV9025Init_StdUseCase102_LinkSharing.profile")
        initStruct = link.platform.board.Adrv9010Device.InitStructGet()
    
        initStruct.clocks.deviceClock_kHz = 245760
        initStruct.rx.rxInitChannelMask = 0x3FF
        initStruct.tx.txInitChannelMask = 0xF
        initStruct.clocks.rx12LoSelect = Types.adi_adrv9010_LoSel_e.ADI_ADRV9010_LOSEL_LO1
        initStruct.clocks.rx34LoSelect = Types.adi_adrv9010_LoSel_e.ADI_ADRV9010_LOSEL_LO1
        initStruct.clocks.tx12LoSelect = Types.adi_adrv9010_LoSel_e.ADI_ADRV9010_LOSEL_LO2
        initStruct.clocks.tx34LoSelect = Types.adi_adrv9010_LoSel_e.ADI_ADRV9010_LOSEL_LO2
        initStruct.clocks.orx12LoSelect = Types.adi_adrv9010_OrxLoSel_e.ADI_ADRV9010_ORXLOSEL_TXLO
        initStruct.clocks.orx34LoSelect = Types.adi_adrv9010_OrxLoSel_e.ADI_ADRV9010_ORXLOSEL_TXLO
        initStruct.clocks.rfPll1LoMode = Types.adi_adrv9010_PllLoMode_e.ADI_ADRV9010_INTLO_NOOUTPUT
        initStruct.clocks.rfPll2LoMode = Types.adi_adrv9010_PllLoMode_e.ADI_ADRV9010_INTLO_NOOUTPUT
        initStruct.clocks.extLoFreq1_kHz = 0
        initStruct.clocks.extLoFreq2_kHz = 0
    
        postMcsInit = Types.adi_adrv9010_PostMcsInit_t()
        postMcsInit.radioCtrlInit.lo1PllFreq_Hz = 3500000000
        postMcsInit.radioCtrlInit.lo2PllFreq_Hz = 3550000000
        postMcsInit.radioCtrlInit.auxPllFreq_Hz = 0
        postMcsInit.radioCtrlInit.radioCtrlModeCfg.rxRadioCtrlModeCfg.rxChannelMask = 0x3FF
        postMcsInit.radioCtrlInit.radioCtrlModeCfg.rxRadioCtrlModeCfg.rxEnableMode = Types.adi_adrv9010_RxEnableMode_e.ADI_ADRV9010_RX_EN_SPI_MODE
        postMcsInit.radioCtrlInit.radioCtrlModeCfg.txRadioCtrlModeCfg.txChannelMask = 0xF
        postMcsInit.radioCtrlInit.radioCtrlModeCfg.txRadioCtrlModeCfg.txEnableMode = Types.adi_adrv9010_TxEnableMode_e.ADI_ADRV9010_TX_EN_SPI_MODE
        postMcsInit.radioCtrlInit.radioCtrlModeCfg.orxRadioCtrlModeCfg.orxEnableMode = Types.adi_adrv9010_ORxEnableMode_e.ADI_ADRV9010_ORX_EN_SPI_MODE
        postMcsInit.radioCtrlInit.radioCtrlModeCfg.orxRadioCtrlModeCfg.orxPinSelectSettlingDelay_armClkCycles = 0
        postMcsInit.radioCtrlInit.radioCtrlModeCfg.orxRadioCtrlModeCfg.singleChannel1PinModeOrxSel = Types.adi_adrv9010_SingleChannelPinModeOrxSel_e.ADI_ADRV9010_SINGLE_CH_PIN_MODE_ORX1_FE
        postMcsInit.radioCtrlInit.radioCtrlModeCfg.orxRadioCtrlModeCfg.singleChannel2PinModeHighOrxSel = Types.adi_adrv9010_SingleChannelPinModeOrxSel_e.ADI_ADRV9010_SINGLE_CH_PIN_MODE_ORX1_FE
        postMcsInit.radioCtrlInit.radioCtrlModeCfg.orxRadioCtrlModeCfg.singleChannel1PinModeOrxSel = Types.adi_adrv9010_SingleChannelPinModeOrxSel_e.ADI_ADRV9010_SINGLE_CH_PIN_MODE_ORX1_FE
        postMcsInit.radioCtrlInit.radioCtrlModeCfg.orxRadioCtrlModeCfg.dualChannel2PinModeOrxSel = Types.adi_adrv9010_DualChannelPinModeOrxSel_e.ADI_ADRV9010_DUAL_CH_PIN_MODE_ORX1_ORX3_SEL
        postMcsInit.radioCtrlInit.txToOrxMapping.orx1Map = Types.adi_adrv9010_TxToOrx1Mapping_e.ADI_ADRV9010_MAP_TX1_ORX1
        postMcsInit.radioCtrlInit.txToOrxMapping.orx2Map = Types.adi_adrv9010_TxToOrx2Mapping_e.ADI_ADRV9010_MAP_TX2_ORX2
        postMcsInit.radioCtrlInit.txToOrxMapping.orx3Map = Types.adi_adrv9010_TxToOrx3Mapping_e.ADI_ADRV9010_MAP_TX3_ORX3
        postMcsInit.radioCtrlInit.txToOrxMapping.orx4Map = Types.adi_adrv9010_TxToOrx4Mapping_e.ADI_ADRV9010_MAP_TX4_ORX4
    
        # Set up the Init Cal Mask
        postMcsInit.initCals.calMask = 0
        postMcsInit.initCals.calMask |= int(Types.adi_adrv9010_InitCalibrations_e.ADI_ADRV9010_TX_BB_FILTER)
        postMcsInit.initCals.calMask |= int(Types.adi_adrv9010_InitCalibrations_e.ADI_ADRV9010_ADC_TUNER)
        postMcsInit.initCals.calMask |= int(Types.adi_adrv9010_InitCalibrations_e.ADI_ADRV9010_RX_TIA)
        postMcsInit.initCals.calMask |= int(Types.adi_adrv9010_InitCalibrations_e.ADI_ADRV9010_ORX_TIA)
        postMcsInit.initCals.calMask |= int(Types.adi_adrv9010_InitCalibrations_e.ADI_ADRV9010_LBRX_TIA)
        postMcsInit.initCals.calMask |= int(Types.adi_adrv9010_InitCalibrations_e.ADI_ADRV9010_RX_DC_OFFSET)
        postMcsInit.initCals.calMask |= int(Types.adi_adrv9010_InitCalibrations_e.ADI_ADRV9010_ORX_DC_OFFSET)
        postMcsInit.initCals.calMask |= int(Types.adi_adrv9010_InitCalibrations_e.ADI_ADRV9010_LBRX_DC_OFFSET)
        postMcsInit.initCals.calMask |= int(Types.adi_adrv9010_InitCalibrations_e.ADI_ADRV9010_FLASH_CAL)
        postMcsInit.initCals.calMask |= int(Types.adi_adrv9010_InitCalibrations_e.ADI_ADRV9010_INTERNAL_PATH_DELAY)
        postMcsInit.initCals.calMask |= int(Types.adi_adrv9010_InitCalibrations_e.ADI_ADRV9010_TX_LO_LEAKAGE_INTERNAL)
        postMcsInit.initCals.calMask |= int(Types.adi_adrv9010_InitCalibrations_e.ADI_ADRV9010_LOOPBACK_RX_LO_DELAY)
        postMcsInit.initCals.calMask |= int(Types.adi_adrv9010_InitCalibrations_e.ADI_ADRV9010_RX_QEC_INIT)
        postMcsInit.initCals.calMask |= int(Types.adi_adrv9010_InitCalibrations_e.ADI_ADRV9010_ORX_QEC_INIT)
        postMcsInit.initCals.calMask |= int(Types.adi_adrv9010_InitCalibrations_e.ADI_ADRV9010_TX_DAC)
        postMcsInit.initCals.channelMask = 0xF
        postMcsInit.initCals.warmBoot = 0
        # Stream GPIO inputs init
        postMcsInit.radioCtrlInit.streamGpioCfg.streamGpInput0  = Types.adi_adrv9010_GpioPinSel_e.ADI_ADRV9010_GPIO_INVALID
        postMcsInit.radioCtrlInit.streamGpioCfg.streamGpInput1  = Types.adi_adrv9010_GpioPinSel_e.ADI_ADRV9010_GPIO_INVALID
        postMcsInit.radioCtrlInit.streamGpioCfg.streamGpInput2  = Types.adi_adrv9010_GpioPinSel_e.ADI_ADRV9010_GPIO_INVALID
        postMcsInit.radioCtrlInit.streamGpioCfg.streamGpInput3  = Types.adi_adrv9010_GpioPinSel_e.ADI_ADRV9010_GPIO_INVALID
        postMcsInit.radioCtrlInit.streamGpioCfg.streamGpInput4  = Types.adi_adrv9010_GpioPinSel_e.ADI_ADRV9010_GPIO_INVALID
        postMcsInit.radioCtrlInit.streamGpioCfg.streamGpInput5  = Types.adi_adrv9010_GpioPinSel_e.ADI_ADRV9010_GPIO_INVALID
        postMcsInit.radioCtrlInit.streamGpioCfg.streamGpInput6  = Types.adi_adrv9010_GpioPinSel_e.ADI_ADRV9010_GPIO_INVALID
        postMcsInit.radioCtrlInit.streamGpioCfg.streamGpInput7  = Types.adi_adrv9010_GpioPinSel_e.ADI_ADRV9010_GPIO_INVALID
        postMcsInit.radioCtrlInit.streamGpioCfg.streamGpInput8  = Types.adi_adrv9010_GpioPinSel_e.ADI_ADRV9010_GPIO_INVALID
        postMcsInit.radioCtrlInit.streamGpioCfg.streamGpInput9  = Types.adi_adrv9010_GpioPinSel_e.ADI_ADRV9010_GPIO_INVALID
        postMcsInit.radioCtrlInit.streamGpioCfg.streamGpInput10 = Types.adi_adrv9010_GpioPinSel_e.ADI_ADRV9010_GPIO_INVALID
        postMcsInit.radioCtrlInit.streamGpioCfg.streamGpInput11 = Types.adi_adrv9010_GpioPinSel_e.ADI_ADRV9010_GPIO_INVALID
        postMcsInit.radioCtrlInit.streamGpioCfg.streamGpInput12 = Types.adi_adrv9010_GpioPinSel_e.ADI_ADRV9010_GPIO_INVALID
        postMcsInit.radioCtrlInit.streamGpioCfg.streamGpInput13 = Types.adi_adrv9010_GpioPinSel_e.ADI_ADRV9010_GPIO_INVALID
        postMcsInit.radioCtrlInit.streamGpioCfg.streamGpInput14 = Types.adi_adrv9010_GpioPinSel_e.ADI_ADRV9010_GPIO_INVALID
        postMcsInit.radioCtrlInit.streamGpioCfg.streamGpInput15 = Types.adi_adrv9010_GpioPinSel_e.ADI_ADRV9010_GPIO_INVALID
        link.platform.board.Adrv9010Device.UtilityInitStructSet(postMcsInit)
    
        # MAKE SURE ARM/STREAM FILES ARE PROGRAMMED. PROGRAM THE DEVICE USING GUI TO LOAD DEFAULT ARM/STREAM FILES.
        link.platform.board.Adrv9010Device.ConfigFileLoad()
        # Ad9528 Config
        link.platform.board.ClockConfig(245760, 122880, 122880, 245760)
    
        # Program the Part
        link.platform.board.Program()
        #Set Tx Atten
        if (((initStruct.tx.txInitChannelMask & 0x01) == 0x01) & ((initStruct.tx.txInitChannelMask & 0x02) == 0x02)):
            print "Set Tx Atten For Channel 1", txAttenSet(30, 1), "and also For Channel 2", txAttenSet(30, 2)
        #Set Rx Gain
        if (((initStruct.rx.rxInitChannelMask & 0x01) == 0x01) & ((initStruct.rx.rxInitChannelMask & 0x02) == 0x02)):
            print "Set Rx Gain For Channel 1", rxGainSet(240, 1), " and also For Channel 2", rxGainSet(240, 2)
        print "[Finished Programming Device]"	
        
    #-----------------------------------------------------------------------------------------------------------------------------
        adrv9010 = link.Adrv9010Get(1)  
        RxChannel = Types.adi_adrv9010_RxChannels_e()
        Rx1 = RxChannel.ADI_ADRV9010_RX1;      Rx2 = RxChannel.ADI_ADRV9010_RX2
        ORx1 = RxChannel.ADI_ADRV9010_ORX1;    ORx2 = RxChannel.ADI_ADRV9010_ORX2
        RxOFF = RxChannel.ADI_ADRV9010_RXOFF;  RxLB12 = RxChannel.ADI_ADRV9010_LB12     # Tx1 or Tx2 internal loopback into ORx1/2 channel enabled 
    
        TxChannel = Types.adi_adrv9010_TxChannels_e()
        TxOFF = TxChannel.ADI_ADRV9010_TXOFF;  TxAll = TxChannel.ADI_ADRV9010_TXALL
        Tx1 = TxChannel.ADI_ADRV9010_TX1;      Tx2 = TxChannel.ADI_ADRV9010_TX2 
    
        # Create an instance of the rxGainMode , agcConfig classes
        agcConfig = Types.adi_adrv9010_AgcCfg_t()
        # ******General AGC Configuration******
        agcConfig.rxChannelMask = 0x01              # [D0] = Rx1, so 0xF means Rx1~Rx4 enable gain control
        # AGC clocks = GainUpdateCounter x 2(slowLoopSettlingDelay) + clock cycles
        # (gain update period) = (agcGainUpdateCounter) x 2(agcSlowLoopSettlingDelay) +  (agcPeakWaitTime)
        # (gain update period) = (921,600) x 2(16) + (4)
        # in this case is 29,491,204 (AGC clock (Hz) x gain update period (s))
        agcConfig.agcGainUpdateCounter = 921600     # value range:overload detector settings ~ 4194303(AGC_CLK_cycles)
        agcConfig.agcPeakWaitTime = 4               # agc clock cycles
        agcConfig.agcSlowLoopSettlingDelay = 4      # value range:0~127; number of AGC clock cycles to wait after a gain change before the AGC changes gain again
        agcConfig.agcLowThreshPreventGainInc = 1    # 0: apdLowThresh and hb2UnerRangeHighThresh are don't cares for gain recovery.
        # agcChangeGainIfThreshHigh
        # 00: APD & HB2 After expiry of agcGainUpdateCounter
        # 01: APD Immediately  &  HB2 After expiry of agcGainUpdateCounter
        # 10: APD After expiry of agcGainUpdateCounter  &  HB2 Immediately
        # 11: APD & HB2 Immediately
        agcConfig.agcChangeGainIfThreshHigh = 3     
        agcConfig.agcPeakThreshGainControlMode = 1      # 1 = AGC in peak detect mode; 0 = AGC in peak and power AGC mode
        agcConfig.agcResetOnRxon = 0                    # 1 = AGC state machine is reset when the receiver is disabled. The AGC gain setting is returned to the maximum gain.  
        agcConfig.agcEnableSyncPulseForGainCounter = 0  # 1 = Allows synchronization of the AGC gain update counter to the time slot boundary. GPIO setup required.  
        agcConfig.agcEnableFastRecoveryLoop = 1         # 1 = Enables the fast recovery AGC functionality using the HB2 overload detector. Only applicable in peak detect mode.
        agcConfig.agcRxMaxGainIndex = 255               # value range:0~255; must greater than min
        agcConfig.agcRxMinGainIndex = 195               # value range:0~255; must smaller than Max
        agcConfig.agcRxAttackDelay = 10                 # value range:0~63; Hold the duration the AGC must be held in reset when the receiver path is enabled.
        # ******end of General AGC Configuration******
        
        # (63+1)1024mV(13dB), (9+1)160mV(-3dB), 
        # (7+1)128mV(-5dB)
        # total: 18dB
        
        print "[APD] High:38, Low: 25"                               # 38:-2.91dBFS      25:-5.87dBFS
        agcConfig.agcPeak.apdHighThresh = 38;                        # apdHighThresh(mV) = (apdHighThresh + 1) × 16 mV; value range: apdLowThresh ~ 63;
        agcConfig.agcPeak.apdLowThresh = 25;                         # apdLowThresh(mV) = (apdLowThresh + 1) × 16 mV; value range: 7 ~ apdHighThresh;
        print "[HB2] High:-3,  UnderRangeHigh:-6,  UnderRangeMid:-8,  UnderRangeLow:-10"
        print "GainAttack:2dB  GainRecovery:1dB"
        agcConfig.agcPeak.hb2HighThresh = 11598;                     # 11598:-3dBFS; hb2HighThresh = 16,384x10^(hb2HighdBFS/20)     
        agcConfig.agcPeak.hb2UnderRangeHighThresh = 8211;            # value range: 0 ~ 16,383; user guide is wrong, (20*log10(value/16384)). 8211-->-6.005dbfs  5813-->-9.004dbfs 2913-->-15.0016 
        agcConfig.agcPeak.hb2UnderRangeMidThresh = 6403;             # hb2UnderRangeMidThresh = 16,384x10^(hb2UnderRangeMiddBFS/20)
        agcConfig.agcPeak.hb2UnderRangeLowThresh = 5121;             # hb2UnderRangeLowThresh = 16,384x10^(hb2UnderRangeLowdBFS/20), user guide is wrong, (20*log10(value/16384)). 8211-->-6.005dbfs  5813-->-9.004dbfs 2913-->-15.0016
        # 11598(-3)  8211(-6)  6523(-8)  5813(-9)  5181(-10) 
        # 4115(-12)  3269(-14) 2914(-15) 2597(-16) 2063(-18)  
        # 1638(-20)  1301(-22) 1034(-24) 921(-25)  
        # 518(-30)  291(-35)  164(-40)
    
        agcConfig.agcPeak.apdGainStepAttack = 8;                     # 4: 2dB; The step size in dB depends on the gain step resolution of the gain table (default 0.5 dB per index step).
        agcConfig.agcPeak.apdGainStepRecovery = 8;                   # 2: 1dB; same as apdGainStepAttack. 
      
        agcConfig.agcPeak.hb2GainStepAttack = 16;                    # value range: 0 ~ 31; 4 means 2dB; The step size in dB depends on the gain step resolution of the gain table (default 0.5 dB per index step).
        agcConfig.agcPeak.hb2GainStepHighRecovery = 16;              # value range: 0 ~ 31; Each mode use this parameter. The number of indices that the gain index pointer must be increased in the event of an HB2 underrange high threshold underrange event. 
        agcConfig.agcPeak.hb2GainStepMidRecovery = 24;               # value range: 0 ~ 31; This sets the number of indices that the gain index pointer must be increased in the event of an HB2 underrange mid threshold underrange event. 
        agcConfig.agcPeak.hb2GainStepLowRecovery = 30;               # value range: 0 ~ 31; This sets the number of indices that the gain index pointer must be increased in the event of an HB2 underrange low threshold underrange event. 
        
        agcConfig.agcPeak.apdUpperThreshPeakExceededCnt = 10;        # Sets number of peaks to detect greater than apdHighThresh to cause an APD high overrange event. In AGC modes, this results in a gain decrement set by apdGainStepAttack.
        agcConfig.agcPeak.apdLowerThreshPeakExceededCnt = 3;         # Sets number of peaks to detect greater than apdLowThresh to cause an APD low overload event. In AGC mode, if an APD low overload event is not occurring, this results in a gain increment set by apdGainStepRecovery.
        agcConfig.agcPeak.hb2UpperThreshPeakExceededCnt = 10;        # value range: 0 ~ 255; In AGC modes, this results in a gain decrement set by hb2GainStepAttack. Sets number of individual overloads greater than hb2HighThresh (number of times hb2OverloadThreshCnt was exceeded in hb2OverloadDurationCnt) to cause an HB2 high overrrange event. 
        agcConfig.agcPeak.hb2UnderRangeHighThreshExceededCnt = 3;    # value range: 0 ~ 255; In peak detect AGC mode, not having sufficient peaks to cause the overload is flagged as an underrange event and the gain is recovered by hb2GainStepHighRecovery. Sets number of individual overloads greater than hb2UnderRangeHighThresh (number of times hb2OverloadThreshCnt was exceeded in hb2OverloadDurationCnt) to cause an HB2 underrange high threshold overload event. 
    
    
        agcConfig.agcPeak.agcUnderRangeLowInterval = 837;            # value range: HB2 detector setting ~ 65536;  
        agcConfig.agcPeak.agcUnderRangeMidInterval = 2;              # value range: 0 ~ 63; (agcUnderRangeMidInterval + 1) × agcUnderRangeLowInterval. (when the signal peaks are less than hb2UnderRangeMidThresh.) 
        agcConfig.agcPeak.agcUnderRangeHighInterval = 4;             # value range: 0 ~ 63; (agcUnderRangeHighInterval + 1) × agcUnderRangeMidInterval. (when the signal peaks are less than hb2UnderRangeHighThresh.)  
        agcConfig.agcPeak.hb2UnderRangeMidThreshExceededCnt = 3;     # value range: 0 ~ 255; Sets number of individual overloads above hb2UnderRangeMidThresh (number of times hb2OverloadThreshCnt was exceeded in hb2OverloadDurationCnt) to cause an HB2 underrange mid threshold overload event. In peak detect AGC mode, not having sufficient peaks to cause the overload is flagged as an underrange event and the gain is recovered by hb2GainStepMidRecovery. 
        agcConfig.agcPeak.hb2UnderRangeLowThreshExceededCnt = 3;     # value range: 0 ~ 255; Sets the number of individual overloads greater than hb2UnderRangeLowThresh (number of times hb2OverloadThreshCnt was exceeded in hb2OverloadDurationCnt) to cause an HB2 underrange low threshold overload event. In peak detect AGC mode, not having sufficient peaks to cause the overload is flagged as an underrange event and the gain is recovered by hb2GainStepLowRecovery. 
       
        # Half-Band 2
        agcConfig.agcPeak.enableHb2Overload = 1;                     # 1: HB2 overload detector enabled.
        agcConfig.agcPeak.hb2OverloadDurationCnt = 1;                # value range: 0 ~ 6; The number of clocks is 2^(hb2OverloadDurationCnt + 1). The number of clock cycles (at the HB2 output rate) within which hb2OverloadThreshCnt
        agcConfig.agcPeak.hb2OverloadThreshCnt = 1;                  # value range: 1 ~ 15; Sets the number of individual samples exceeding hb2HighThresh or hb2LowThresh necessary within hb2OverloadDurationCnt for an overload to occur
    
        agcConfig.agcPeak.hb2OverloadPowerMode = 0;                  # Sets the measurement mode of the HB2 detector.  0 means the hb2 threshold sample type is signal amplitude. 1 means the hb2 threshold sample type is signal power. 
        agcConfig.agcPeak.hb2ThreshConfig = 3;                       # value only: 3; 
        
        # ******end of adi_adrv9025_AgcPeak_t Configuration******
        agcConfigArr = Array[Types.adi_adrv9010_AgcCfg_t]([agcConfig])        # Make agcConfig and rxGainMode into array types (necessary for syntax reasons)
        adrv9010.RadioCtrl.RxTxEnableSet(0x01, 0x01)                          # RX1 TX1 enabled 
        adrv9010.Agc.AgcCfgSet(agcConfigArr, 1)
        # -----------------------------------------------------End of setting AGC parameter-----------------------------------------------------
        adrv9010.RadioCtrl.RxTxEnableSet(0x01, 0x01)                                  # RX1 TX1 enabled 
        print "[Set] Rx1 and Tx1 enable."    
        RxTxEnableGetStatus = adrv9010.RadioCtrl.RxTxEnableGet(0, 0)  
        print "[Get Status] RxChannel: ", hex(RxTxEnableGetStatus[1]), "and TxChannel: ", hex(RxTxEnableGetStatus[2])
    
        # -----------------------------------------------------Test only starts--------------------------------------------------
    
        print "\n[Function Message starts]"
        TxTone = Types.adi_adrv9010_TxTestToneCfg_t()
        TxTone.txChannelMask = 0x01
        TxTone.enable = 1
        TxTone.txToneFreq_Hz = 30*1000000
        TxTone.txToneGain = Types.adi_adrv9010_TxNcoGain_e.ADI_ADRV9010_TX_NCO_0_DB    # ADI_ADRV9010_TX_NCO_NEG18_DB;  ADI_ADRV9010_TX_NCO_NEG12_DB;  ADI_ADRV9010_TX_NCO_NEG6DB;   ADI_ADRV9010_TX_NCO_0_DB   
        TxToneArr = Array[Types.adi_adrv9010_TxTestToneCfg_t]([TxTone])                # Make agcConfig and rxGainMode into array types (necessary for syntax reasons)
        adrv9010.Tx.TxTestToneSet(TxToneArr, 1)
        print "   [Set] (Tx1) Tone: 0dB"
        rxGainCtrlModeSet(Types.adi_adrv9010_RxAgcMode_e.ADI_ADRV9010_AGCSLOW, 0x01)   # (Default) ADI_ADRV9010_MGC, ADI_ADRV9010_AGCSLOW, ADI_ADRV9010_AGCFAST,;  0x01: Rx1   
        (Channel_RxGet_temp, RxGet_agcMode) = adrv9010.Rx.RxGainCtrlModeGet(Rx1, Types.adi_adrv9010_RxAgcMode_t())
        (Channel_RxGet_temp, RxGet_AgcGainIndexRange) = adrv9010.Agc.AgcGainIndexRangeGet(Rx1, Types.adi_adrv9010_AgcGainRange_t())
        (Channel_Tx_temp, TxGet_AttenMode, TxGet_AttenSimultUpdateCfg, TxGet_AttenPinCfg) = adrv9010.Tx.TxAttenModeGet(Tx1, Types.adi_adrv9010_TxAttenMode_e.ADI_ADRV9010_TXATTEN_SPI_MODE, Types.adi_adrv9010_TxAttenSimultUpdateCfg_t(), Types.adi_adrv9010_TxAttenPinCfg_t())
        print "   [Get] (Rx1) Gain Mode:", RxGet_agcMode.agcMode, "\n   [Get] AGC_MaxGain:", RxGet_AgcGainIndexRange.maxGainIndex, ", and AGC_MinGain:", RxGet_AgcGainIndexRange.minGainIndex 
        print "[Function Message ends]\n"
        print "[Tx_Attenuation & RX_GainIndex Data Starts]"    
        localtime = time.localtime() 
        # write data to file
        time_filename = time.strftime("_%m%d%Y_%H%M%S", localtime)
        path = str("C:\ADI\Output_Data" + time_filename + ".txt")  
        text_file = open(path, "w")                    # mode: 'w':write, 'a':appending,'+': Open a text file for updating
    
        
        # -----------------------------------------------------Test only ends-----------------------------------------------------
        k = 1
        table_x = (5, 15, 12, 0, 3, 5, 5, 15, 12, 0, 3, 5, 5, 15, 12, 0, 3, 5)
        for i in range(0, 1):
            #for x in range(0, 41, 1): 
            for x in range(0, 18):   # range(start, stop, step)
                adrv9010.RadioCtrl.RxTxEnableSet(0x01, 0x01)
                #atten = x
                atten = table_x[x]
                TxAtten = Types.adi_adrv9010_TxAtten_t()
                TxAtten.txAttenuation_mdB = int(atten) * 1000;
                TxAtten.txChannelMask = 0x01;
                TxAttenArr = Array[Types.adi_adrv9010_TxAtten_t]([TxAtten])                  # Make agcConfig and rxGainMode into array types (necessary for syntax reasons)
                adrv9010.Tx.TxAttenSet(TxAttenArr, 1)
                for y in range(0, 60, 1):
                    (Channel_temp, RxGainGet) = adrv9010.Rx.RxGainGet(Rx1, Types.adi_adrv9010_RxGain_t())             # Reads Rx AGC Gain Index 
                    (Channel_Tx_temp, TxGet_AttenNum) = adrv9010.Tx.TxAttenGet(Tx1, Types.adi_adrv9010_TxAtten_t())
                    Temp_Count = (k)
                    Temp_AttenNum = (TxGet_AttenNum.txAttenuation_mdB/1000.0)
                    Temp_GainIndex = (RxGainGet.gainIndex)
                    localtime = time.localtime()
                    Temp_time = time.strftime("%H:%M:%S", localtime)
                    text_file.write( str(Temp_Count) + "," + str(Temp_AttenNum) + "," + str(Temp_GainIndex) + "," + str(Temp_time) + "\n" )   # writelines is for list
                    print "( Count:", Temp_Count, ") [Tx1] Get_Attenuation:", Temp_AttenNum, "dB.  [Rx1] Gain_index:", Temp_GainIndex, "at", Temp_time  # channel depends on RxGainGet(Rx2,...) 
                    k = k + 1
                    time.sleep(0.5)   # unit: second
        text_file.close()
        print "[Tx_Attenuation & RX_GainIndex Data ends]"   
        print "[Data save successfully, close all ports]\n"
        adrv9010.RadioCtrl.RxTxEnableSet(0x00, 0x00)    
    
    else:
        print "Not Connected"
    
    if (connect):
        link.platform.board.Client.Disconnect()
        print "Disconnected"

Reply
  • Hi Ramarao,

    I have a Python script for the AGC setup.

    When I'm running the script in the Evaluation Board, the following error is coming.

    Starts at 07/19/2023  11:26:33
    [Programming Device]
    System.Exception: ERROR while attempting to init board : ERROR: Product Name:9029CE01C; : ; : ; : ; : ;  Error number 7, Recovery action -6. In file ../../../../c_src/boards/daughterboards/adrv9025/src/adi_adrv9025_daughter_board.c, in function adi_adrv9025Board_Dispatch, in line 2037, variable name __null. Error message ERROR-Phase1 fail: DaughterBoard Error - 7, ERROR-Phase1 fail: DaughterBoard Error - 7, 
    .
    ERROR: ad9528Device Error number 8193, Recovery action -5. In file ../../../../c_src/devices/ad9528/public/src/adi_ad9528.c, in function adi_ad9528_PllLockDebounce, in line 773, variable name __null. Error message Ad9528 PLL Not locked.

     

       at adrv9010_dll.TopLevelClasses.AdrvDaughterCard.Program()
       at Microsoft.Scripting.Interpreter.ActionCallInstruction`1.Run(InterpretedFrame frame)
       at Microsoft.Scripting.Interpreter.Interpreter.Run(InterpretedFrame frame)
       at Microsoft.Scripting.Interpreter.LightLambda.Run3[T0,T1,T2,TRet](T0 arg0, T1 arg1, T2 arg2)
       at System.Dynamic.UpdateDelegates.UpdateAndExecute2[T0,T1,TRet](CallSite site, T0 arg0, T1 arg1)
       at Microsoft.Scripting.Interpreter.DynamicInstruction`3.Run(InterpretedFrame frame)
       at Microsoft.Scripting.Interpreter.Interpreter.Run(InterpretedFrame frame)
       at Microsoft.Scripting.Interpreter.LightLambda.Run2[T0,T1,TRet](T0 arg0, T1 arg1)
       at IronPython.Compiler.PythonScriptCode.RunWorker(CodeContext ctx)
       at Adi.Tpg.IronPythonWindow.ScriptHost.Execute(String expression)

    Please have a look at it.

    #################################################################################
    #GUI Version: 6.4.0.17
    #DLL Version: 6.4.0.14
    #Cmd Server Version: 6.4.0.14
    #FPGA Version: 0xD900000A
    #ARM Version: 6.4.0.6(ADI_ADRV9025_ARMBUILD_RELEASE)
    #StreamVersion: 9.4.0.1
    
    #Albert Chang.
    #Oct.2022
    #AGC function code.
    #starts from connection in GUI (TES)  
    #################################################################################
    
    #Import Reference to the DLL
    import System
    import clr
    import time
    from System import Array
    clr.AddReferenceToFileAndPath("C:\\Program Files\\Analog Devices\\ADRV9025 Transceiver Evaluation Software_x64_FULL\\adrvtrx_dll.dll")
    from adrv9010_dll import AdiEvaluationSystem
    from adrv9010_dll import Types
    from adrv9010_dll import Ad9528Types
    
    def spiRead(address):
        data = adrv9010.Hal.SpiByteRead(address, 0)
        print "SPI Read Address " + hex(address) + ": " + hex(data[1])
    
    def spiWrite(address, data):
        adrv9010.Hal.SpiByteWrite(address, data)
        print "SPI Write Address " + hex(address) + ": " + hex(data)
    
    def runTxQECInitCal(txChannel):
        errorFlag = 0
        txCals = Types.adi_adrv9010_InitCals_t()
        txCals.calMask = int(Types.adi_adrv9010_InitCalibrations_e.ADI_ADRV9010_TX_QEC_INIT)
        txCals.channelMask = txChannel
        txCals.warmBoot = 0
        link.platform.board.Adrv9010Device.Cals.InitCalsRun(txCals)
        link.platform.board.Adrv9010Device.Cals.InitCalsWait(1000, errorFlag)
    
    def rxGainSet(gain, rxChannelMask):                                             # manual gain set, Rx1=bit[0]=0x1, Rx1~ORx4=bit[0~7]=0xF
        adrv9010RxGain = Array.CreateInstance(Types.adi_adrv9010_RxGain_t, 1)
        adrv9010RxGain[0] = Types.adi_adrv9010_RxGain_t()    
        adrv9010RxGain[0].gainIndex = gain;
        adrv9010RxGain[0].rxChannelMask = rxChannelMask;
        link.platform.board.Adrv9010Device.Rx.RxGainSet(adrv9010RxGain, 1);
    
    def rxGainCtrlModeSet(agcMode_user, rxChannelMask_user):                                              
        adrv9010RxGainCtrlMode = Array.CreateInstance(Types.adi_adrv9010_RxAgcMode_t, 1)       
        adrv9010RxGainCtrlMode[0] = Types.adi_adrv9010_RxAgcMode_t()    
        adrv9010RxGainCtrlMode[0].agcMode = agcMode_user;                         # Types.adi_adrv9010_RxAgcMode_e. ...
        adrv9010RxGainCtrlMode[0].rxChannelMask = rxChannelMask_user;
        link.platform.board.Adrv9010Device.Rx.RxGainCtrlModeSet(adrv9010RxGainCtrlMode, 1); 
    
    def txAttenSet(atten, txChannelMask): 
        adrv9010TxAtten = Array.CreateInstance(Types.adi_adrv9010_TxAtten_t, 1)
        adrv9010TxAtten[0] = Types.adi_adrv9010_TxAtten_t()    
        adrv9010TxAtten[0].txAttenuation_mdB = atten * 1000.0;
        adrv9010TxAtten[0].txChannelMask = txChannelMask;
        link.platform.board.Adrv9010Device.Tx.TxAttenSet(adrv9010TxAtten, 1);
    
    
    #Create an Instance of the Class
    link = AdiEvaluationSystem.Instance	
    connect = False
    
    if (link.IsConnected() == False):
        connect = True
        link.platform.board.Client.Connect("192.168.1.10", 55556)
        print "Connecting"
    
    if (link.IsConnected()):
        localtime = time.localtime() 
        print "Starts at " + time.strftime("%m/%d/%Y  %H:%M:%S", localtime) + "\n[Programming Device]"
        link.platform.board.Adrv9010Device.ConfigFileLoad("C:\\Program Files\\Analog Devices\\ADRV9025 Transceiver Evaluation Software_x64_FULL\\Resources\\Adi.ADRV9025.Profiles\\public\\ADRV9025Init_StdUseCase102_LinkSharing.profile")
        initStruct = link.platform.board.Adrv9010Device.InitStructGet()
    
        initStruct.clocks.deviceClock_kHz = 245760
        initStruct.rx.rxInitChannelMask = 0x3FF
        initStruct.tx.txInitChannelMask = 0xF
        initStruct.clocks.rx12LoSelect = Types.adi_adrv9010_LoSel_e.ADI_ADRV9010_LOSEL_LO1
        initStruct.clocks.rx34LoSelect = Types.adi_adrv9010_LoSel_e.ADI_ADRV9010_LOSEL_LO1
        initStruct.clocks.tx12LoSelect = Types.adi_adrv9010_LoSel_e.ADI_ADRV9010_LOSEL_LO2
        initStruct.clocks.tx34LoSelect = Types.adi_adrv9010_LoSel_e.ADI_ADRV9010_LOSEL_LO2
        initStruct.clocks.orx12LoSelect = Types.adi_adrv9010_OrxLoSel_e.ADI_ADRV9010_ORXLOSEL_TXLO
        initStruct.clocks.orx34LoSelect = Types.adi_adrv9010_OrxLoSel_e.ADI_ADRV9010_ORXLOSEL_TXLO
        initStruct.clocks.rfPll1LoMode = Types.adi_adrv9010_PllLoMode_e.ADI_ADRV9010_INTLO_NOOUTPUT
        initStruct.clocks.rfPll2LoMode = Types.adi_adrv9010_PllLoMode_e.ADI_ADRV9010_INTLO_NOOUTPUT
        initStruct.clocks.extLoFreq1_kHz = 0
        initStruct.clocks.extLoFreq2_kHz = 0
    
        postMcsInit = Types.adi_adrv9010_PostMcsInit_t()
        postMcsInit.radioCtrlInit.lo1PllFreq_Hz = 3500000000
        postMcsInit.radioCtrlInit.lo2PllFreq_Hz = 3550000000
        postMcsInit.radioCtrlInit.auxPllFreq_Hz = 0
        postMcsInit.radioCtrlInit.radioCtrlModeCfg.rxRadioCtrlModeCfg.rxChannelMask = 0x3FF
        postMcsInit.radioCtrlInit.radioCtrlModeCfg.rxRadioCtrlModeCfg.rxEnableMode = Types.adi_adrv9010_RxEnableMode_e.ADI_ADRV9010_RX_EN_SPI_MODE
        postMcsInit.radioCtrlInit.radioCtrlModeCfg.txRadioCtrlModeCfg.txChannelMask = 0xF
        postMcsInit.radioCtrlInit.radioCtrlModeCfg.txRadioCtrlModeCfg.txEnableMode = Types.adi_adrv9010_TxEnableMode_e.ADI_ADRV9010_TX_EN_SPI_MODE
        postMcsInit.radioCtrlInit.radioCtrlModeCfg.orxRadioCtrlModeCfg.orxEnableMode = Types.adi_adrv9010_ORxEnableMode_e.ADI_ADRV9010_ORX_EN_SPI_MODE
        postMcsInit.radioCtrlInit.radioCtrlModeCfg.orxRadioCtrlModeCfg.orxPinSelectSettlingDelay_armClkCycles = 0
        postMcsInit.radioCtrlInit.radioCtrlModeCfg.orxRadioCtrlModeCfg.singleChannel1PinModeOrxSel = Types.adi_adrv9010_SingleChannelPinModeOrxSel_e.ADI_ADRV9010_SINGLE_CH_PIN_MODE_ORX1_FE
        postMcsInit.radioCtrlInit.radioCtrlModeCfg.orxRadioCtrlModeCfg.singleChannel2PinModeHighOrxSel = Types.adi_adrv9010_SingleChannelPinModeOrxSel_e.ADI_ADRV9010_SINGLE_CH_PIN_MODE_ORX1_FE
        postMcsInit.radioCtrlInit.radioCtrlModeCfg.orxRadioCtrlModeCfg.singleChannel1PinModeOrxSel = Types.adi_adrv9010_SingleChannelPinModeOrxSel_e.ADI_ADRV9010_SINGLE_CH_PIN_MODE_ORX1_FE
        postMcsInit.radioCtrlInit.radioCtrlModeCfg.orxRadioCtrlModeCfg.dualChannel2PinModeOrxSel = Types.adi_adrv9010_DualChannelPinModeOrxSel_e.ADI_ADRV9010_DUAL_CH_PIN_MODE_ORX1_ORX3_SEL
        postMcsInit.radioCtrlInit.txToOrxMapping.orx1Map = Types.adi_adrv9010_TxToOrx1Mapping_e.ADI_ADRV9010_MAP_TX1_ORX1
        postMcsInit.radioCtrlInit.txToOrxMapping.orx2Map = Types.adi_adrv9010_TxToOrx2Mapping_e.ADI_ADRV9010_MAP_TX2_ORX2
        postMcsInit.radioCtrlInit.txToOrxMapping.orx3Map = Types.adi_adrv9010_TxToOrx3Mapping_e.ADI_ADRV9010_MAP_TX3_ORX3
        postMcsInit.radioCtrlInit.txToOrxMapping.orx4Map = Types.adi_adrv9010_TxToOrx4Mapping_e.ADI_ADRV9010_MAP_TX4_ORX4
    
        # Set up the Init Cal Mask
        postMcsInit.initCals.calMask = 0
        postMcsInit.initCals.calMask |= int(Types.adi_adrv9010_InitCalibrations_e.ADI_ADRV9010_TX_BB_FILTER)
        postMcsInit.initCals.calMask |= int(Types.adi_adrv9010_InitCalibrations_e.ADI_ADRV9010_ADC_TUNER)
        postMcsInit.initCals.calMask |= int(Types.adi_adrv9010_InitCalibrations_e.ADI_ADRV9010_RX_TIA)
        postMcsInit.initCals.calMask |= int(Types.adi_adrv9010_InitCalibrations_e.ADI_ADRV9010_ORX_TIA)
        postMcsInit.initCals.calMask |= int(Types.adi_adrv9010_InitCalibrations_e.ADI_ADRV9010_LBRX_TIA)
        postMcsInit.initCals.calMask |= int(Types.adi_adrv9010_InitCalibrations_e.ADI_ADRV9010_RX_DC_OFFSET)
        postMcsInit.initCals.calMask |= int(Types.adi_adrv9010_InitCalibrations_e.ADI_ADRV9010_ORX_DC_OFFSET)
        postMcsInit.initCals.calMask |= int(Types.adi_adrv9010_InitCalibrations_e.ADI_ADRV9010_LBRX_DC_OFFSET)
        postMcsInit.initCals.calMask |= int(Types.adi_adrv9010_InitCalibrations_e.ADI_ADRV9010_FLASH_CAL)
        postMcsInit.initCals.calMask |= int(Types.adi_adrv9010_InitCalibrations_e.ADI_ADRV9010_INTERNAL_PATH_DELAY)
        postMcsInit.initCals.calMask |= int(Types.adi_adrv9010_InitCalibrations_e.ADI_ADRV9010_TX_LO_LEAKAGE_INTERNAL)
        postMcsInit.initCals.calMask |= int(Types.adi_adrv9010_InitCalibrations_e.ADI_ADRV9010_LOOPBACK_RX_LO_DELAY)
        postMcsInit.initCals.calMask |= int(Types.adi_adrv9010_InitCalibrations_e.ADI_ADRV9010_RX_QEC_INIT)
        postMcsInit.initCals.calMask |= int(Types.adi_adrv9010_InitCalibrations_e.ADI_ADRV9010_ORX_QEC_INIT)
        postMcsInit.initCals.calMask |= int(Types.adi_adrv9010_InitCalibrations_e.ADI_ADRV9010_TX_DAC)
        postMcsInit.initCals.channelMask = 0xF
        postMcsInit.initCals.warmBoot = 0
        # Stream GPIO inputs init
        postMcsInit.radioCtrlInit.streamGpioCfg.streamGpInput0  = Types.adi_adrv9010_GpioPinSel_e.ADI_ADRV9010_GPIO_INVALID
        postMcsInit.radioCtrlInit.streamGpioCfg.streamGpInput1  = Types.adi_adrv9010_GpioPinSel_e.ADI_ADRV9010_GPIO_INVALID
        postMcsInit.radioCtrlInit.streamGpioCfg.streamGpInput2  = Types.adi_adrv9010_GpioPinSel_e.ADI_ADRV9010_GPIO_INVALID
        postMcsInit.radioCtrlInit.streamGpioCfg.streamGpInput3  = Types.adi_adrv9010_GpioPinSel_e.ADI_ADRV9010_GPIO_INVALID
        postMcsInit.radioCtrlInit.streamGpioCfg.streamGpInput4  = Types.adi_adrv9010_GpioPinSel_e.ADI_ADRV9010_GPIO_INVALID
        postMcsInit.radioCtrlInit.streamGpioCfg.streamGpInput5  = Types.adi_adrv9010_GpioPinSel_e.ADI_ADRV9010_GPIO_INVALID
        postMcsInit.radioCtrlInit.streamGpioCfg.streamGpInput6  = Types.adi_adrv9010_GpioPinSel_e.ADI_ADRV9010_GPIO_INVALID
        postMcsInit.radioCtrlInit.streamGpioCfg.streamGpInput7  = Types.adi_adrv9010_GpioPinSel_e.ADI_ADRV9010_GPIO_INVALID
        postMcsInit.radioCtrlInit.streamGpioCfg.streamGpInput8  = Types.adi_adrv9010_GpioPinSel_e.ADI_ADRV9010_GPIO_INVALID
        postMcsInit.radioCtrlInit.streamGpioCfg.streamGpInput9  = Types.adi_adrv9010_GpioPinSel_e.ADI_ADRV9010_GPIO_INVALID
        postMcsInit.radioCtrlInit.streamGpioCfg.streamGpInput10 = Types.adi_adrv9010_GpioPinSel_e.ADI_ADRV9010_GPIO_INVALID
        postMcsInit.radioCtrlInit.streamGpioCfg.streamGpInput11 = Types.adi_adrv9010_GpioPinSel_e.ADI_ADRV9010_GPIO_INVALID
        postMcsInit.radioCtrlInit.streamGpioCfg.streamGpInput12 = Types.adi_adrv9010_GpioPinSel_e.ADI_ADRV9010_GPIO_INVALID
        postMcsInit.radioCtrlInit.streamGpioCfg.streamGpInput13 = Types.adi_adrv9010_GpioPinSel_e.ADI_ADRV9010_GPIO_INVALID
        postMcsInit.radioCtrlInit.streamGpioCfg.streamGpInput14 = Types.adi_adrv9010_GpioPinSel_e.ADI_ADRV9010_GPIO_INVALID
        postMcsInit.radioCtrlInit.streamGpioCfg.streamGpInput15 = Types.adi_adrv9010_GpioPinSel_e.ADI_ADRV9010_GPIO_INVALID
        link.platform.board.Adrv9010Device.UtilityInitStructSet(postMcsInit)
    
        # MAKE SURE ARM/STREAM FILES ARE PROGRAMMED. PROGRAM THE DEVICE USING GUI TO LOAD DEFAULT ARM/STREAM FILES.
        link.platform.board.Adrv9010Device.ConfigFileLoad()
        # Ad9528 Config
        link.platform.board.ClockConfig(245760, 122880, 122880, 245760)
    
        # Program the Part
        link.platform.board.Program()
        #Set Tx Atten
        if (((initStruct.tx.txInitChannelMask & 0x01) == 0x01) & ((initStruct.tx.txInitChannelMask & 0x02) == 0x02)):
            print "Set Tx Atten For Channel 1", txAttenSet(30, 1), "and also For Channel 2", txAttenSet(30, 2)
        #Set Rx Gain
        if (((initStruct.rx.rxInitChannelMask & 0x01) == 0x01) & ((initStruct.rx.rxInitChannelMask & 0x02) == 0x02)):
            print "Set Rx Gain For Channel 1", rxGainSet(240, 1), " and also For Channel 2", rxGainSet(240, 2)
        print "[Finished Programming Device]"	
        
    #-----------------------------------------------------------------------------------------------------------------------------
        adrv9010 = link.Adrv9010Get(1)  
        RxChannel = Types.adi_adrv9010_RxChannels_e()
        Rx1 = RxChannel.ADI_ADRV9010_RX1;      Rx2 = RxChannel.ADI_ADRV9010_RX2
        ORx1 = RxChannel.ADI_ADRV9010_ORX1;    ORx2 = RxChannel.ADI_ADRV9010_ORX2
        RxOFF = RxChannel.ADI_ADRV9010_RXOFF;  RxLB12 = RxChannel.ADI_ADRV9010_LB12     # Tx1 or Tx2 internal loopback into ORx1/2 channel enabled 
    
        TxChannel = Types.adi_adrv9010_TxChannels_e()
        TxOFF = TxChannel.ADI_ADRV9010_TXOFF;  TxAll = TxChannel.ADI_ADRV9010_TXALL
        Tx1 = TxChannel.ADI_ADRV9010_TX1;      Tx2 = TxChannel.ADI_ADRV9010_TX2 
    
        # Create an instance of the rxGainMode , agcConfig classes
        agcConfig = Types.adi_adrv9010_AgcCfg_t()
        # ******General AGC Configuration******
        agcConfig.rxChannelMask = 0x01              # [D0] = Rx1, so 0xF means Rx1~Rx4 enable gain control
        # AGC clocks = GainUpdateCounter x 2(slowLoopSettlingDelay) + clock cycles
        # (gain update period) = (agcGainUpdateCounter) x 2(agcSlowLoopSettlingDelay) +  (agcPeakWaitTime)
        # (gain update period) = (921,600) x 2(16) + (4)
        # in this case is 29,491,204 (AGC clock (Hz) x gain update period (s))
        agcConfig.agcGainUpdateCounter = 921600     # value range:overload detector settings ~ 4194303(AGC_CLK_cycles)
        agcConfig.agcPeakWaitTime = 4               # agc clock cycles
        agcConfig.agcSlowLoopSettlingDelay = 4      # value range:0~127; number of AGC clock cycles to wait after a gain change before the AGC changes gain again
        agcConfig.agcLowThreshPreventGainInc = 1    # 0: apdLowThresh and hb2UnerRangeHighThresh are don't cares for gain recovery.
        # agcChangeGainIfThreshHigh
        # 00: APD & HB2 After expiry of agcGainUpdateCounter
        # 01: APD Immediately  &  HB2 After expiry of agcGainUpdateCounter
        # 10: APD After expiry of agcGainUpdateCounter  &  HB2 Immediately
        # 11: APD & HB2 Immediately
        agcConfig.agcChangeGainIfThreshHigh = 3     
        agcConfig.agcPeakThreshGainControlMode = 1      # 1 = AGC in peak detect mode; 0 = AGC in peak and power AGC mode
        agcConfig.agcResetOnRxon = 0                    # 1 = AGC state machine is reset when the receiver is disabled. The AGC gain setting is returned to the maximum gain.  
        agcConfig.agcEnableSyncPulseForGainCounter = 0  # 1 = Allows synchronization of the AGC gain update counter to the time slot boundary. GPIO setup required.  
        agcConfig.agcEnableFastRecoveryLoop = 1         # 1 = Enables the fast recovery AGC functionality using the HB2 overload detector. Only applicable in peak detect mode.
        agcConfig.agcRxMaxGainIndex = 255               # value range:0~255; must greater than min
        agcConfig.agcRxMinGainIndex = 195               # value range:0~255; must smaller than Max
        agcConfig.agcRxAttackDelay = 10                 # value range:0~63; Hold the duration the AGC must be held in reset when the receiver path is enabled.
        # ******end of General AGC Configuration******
        
        # (63+1)1024mV(13dB), (9+1)160mV(-3dB), 
        # (7+1)128mV(-5dB)
        # total: 18dB
        
        print "[APD] High:38, Low: 25"                               # 38:-2.91dBFS      25:-5.87dBFS
        agcConfig.agcPeak.apdHighThresh = 38;                        # apdHighThresh(mV) = (apdHighThresh + 1) × 16 mV; value range: apdLowThresh ~ 63;
        agcConfig.agcPeak.apdLowThresh = 25;                         # apdLowThresh(mV) = (apdLowThresh + 1) × 16 mV; value range: 7 ~ apdHighThresh;
        print "[HB2] High:-3,  UnderRangeHigh:-6,  UnderRangeMid:-8,  UnderRangeLow:-10"
        print "GainAttack:2dB  GainRecovery:1dB"
        agcConfig.agcPeak.hb2HighThresh = 11598;                     # 11598:-3dBFS; hb2HighThresh = 16,384x10^(hb2HighdBFS/20)     
        agcConfig.agcPeak.hb2UnderRangeHighThresh = 8211;            # value range: 0 ~ 16,383; user guide is wrong, (20*log10(value/16384)). 8211-->-6.005dbfs  5813-->-9.004dbfs 2913-->-15.0016 
        agcConfig.agcPeak.hb2UnderRangeMidThresh = 6403;             # hb2UnderRangeMidThresh = 16,384x10^(hb2UnderRangeMiddBFS/20)
        agcConfig.agcPeak.hb2UnderRangeLowThresh = 5121;             # hb2UnderRangeLowThresh = 16,384x10^(hb2UnderRangeLowdBFS/20), user guide is wrong, (20*log10(value/16384)). 8211-->-6.005dbfs  5813-->-9.004dbfs 2913-->-15.0016
        # 11598(-3)  8211(-6)  6523(-8)  5813(-9)  5181(-10) 
        # 4115(-12)  3269(-14) 2914(-15) 2597(-16) 2063(-18)  
        # 1638(-20)  1301(-22) 1034(-24) 921(-25)  
        # 518(-30)  291(-35)  164(-40)
    
        agcConfig.agcPeak.apdGainStepAttack = 8;                     # 4: 2dB; The step size in dB depends on the gain step resolution of the gain table (default 0.5 dB per index step).
        agcConfig.agcPeak.apdGainStepRecovery = 8;                   # 2: 1dB; same as apdGainStepAttack. 
      
        agcConfig.agcPeak.hb2GainStepAttack = 16;                    # value range: 0 ~ 31; 4 means 2dB; The step size in dB depends on the gain step resolution of the gain table (default 0.5 dB per index step).
        agcConfig.agcPeak.hb2GainStepHighRecovery = 16;              # value range: 0 ~ 31; Each mode use this parameter. The number of indices that the gain index pointer must be increased in the event of an HB2 underrange high threshold underrange event. 
        agcConfig.agcPeak.hb2GainStepMidRecovery = 24;               # value range: 0 ~ 31; This sets the number of indices that the gain index pointer must be increased in the event of an HB2 underrange mid threshold underrange event. 
        agcConfig.agcPeak.hb2GainStepLowRecovery = 30;               # value range: 0 ~ 31; This sets the number of indices that the gain index pointer must be increased in the event of an HB2 underrange low threshold underrange event. 
        
        agcConfig.agcPeak.apdUpperThreshPeakExceededCnt = 10;        # Sets number of peaks to detect greater than apdHighThresh to cause an APD high overrange event. In AGC modes, this results in a gain decrement set by apdGainStepAttack.
        agcConfig.agcPeak.apdLowerThreshPeakExceededCnt = 3;         # Sets number of peaks to detect greater than apdLowThresh to cause an APD low overload event. In AGC mode, if an APD low overload event is not occurring, this results in a gain increment set by apdGainStepRecovery.
        agcConfig.agcPeak.hb2UpperThreshPeakExceededCnt = 10;        # value range: 0 ~ 255; In AGC modes, this results in a gain decrement set by hb2GainStepAttack. Sets number of individual overloads greater than hb2HighThresh (number of times hb2OverloadThreshCnt was exceeded in hb2OverloadDurationCnt) to cause an HB2 high overrrange event. 
        agcConfig.agcPeak.hb2UnderRangeHighThreshExceededCnt = 3;    # value range: 0 ~ 255; In peak detect AGC mode, not having sufficient peaks to cause the overload is flagged as an underrange event and the gain is recovered by hb2GainStepHighRecovery. Sets number of individual overloads greater than hb2UnderRangeHighThresh (number of times hb2OverloadThreshCnt was exceeded in hb2OverloadDurationCnt) to cause an HB2 underrange high threshold overload event. 
    
    
        agcConfig.agcPeak.agcUnderRangeLowInterval = 837;            # value range: HB2 detector setting ~ 65536;  
        agcConfig.agcPeak.agcUnderRangeMidInterval = 2;              # value range: 0 ~ 63; (agcUnderRangeMidInterval + 1) × agcUnderRangeLowInterval. (when the signal peaks are less than hb2UnderRangeMidThresh.) 
        agcConfig.agcPeak.agcUnderRangeHighInterval = 4;             # value range: 0 ~ 63; (agcUnderRangeHighInterval + 1) × agcUnderRangeMidInterval. (when the signal peaks are less than hb2UnderRangeHighThresh.)  
        agcConfig.agcPeak.hb2UnderRangeMidThreshExceededCnt = 3;     # value range: 0 ~ 255; Sets number of individual overloads above hb2UnderRangeMidThresh (number of times hb2OverloadThreshCnt was exceeded in hb2OverloadDurationCnt) to cause an HB2 underrange mid threshold overload event. In peak detect AGC mode, not having sufficient peaks to cause the overload is flagged as an underrange event and the gain is recovered by hb2GainStepMidRecovery. 
        agcConfig.agcPeak.hb2UnderRangeLowThreshExceededCnt = 3;     # value range: 0 ~ 255; Sets the number of individual overloads greater than hb2UnderRangeLowThresh (number of times hb2OverloadThreshCnt was exceeded in hb2OverloadDurationCnt) to cause an HB2 underrange low threshold overload event. In peak detect AGC mode, not having sufficient peaks to cause the overload is flagged as an underrange event and the gain is recovered by hb2GainStepLowRecovery. 
       
        # Half-Band 2
        agcConfig.agcPeak.enableHb2Overload = 1;                     # 1: HB2 overload detector enabled.
        agcConfig.agcPeak.hb2OverloadDurationCnt = 1;                # value range: 0 ~ 6; The number of clocks is 2^(hb2OverloadDurationCnt + 1). The number of clock cycles (at the HB2 output rate) within which hb2OverloadThreshCnt
        agcConfig.agcPeak.hb2OverloadThreshCnt = 1;                  # value range: 1 ~ 15; Sets the number of individual samples exceeding hb2HighThresh or hb2LowThresh necessary within hb2OverloadDurationCnt for an overload to occur
    
        agcConfig.agcPeak.hb2OverloadPowerMode = 0;                  # Sets the measurement mode of the HB2 detector.  0 means the hb2 threshold sample type is signal amplitude. 1 means the hb2 threshold sample type is signal power. 
        agcConfig.agcPeak.hb2ThreshConfig = 3;                       # value only: 3; 
        
        # ******end of adi_adrv9025_AgcPeak_t Configuration******
        agcConfigArr = Array[Types.adi_adrv9010_AgcCfg_t]([agcConfig])        # Make agcConfig and rxGainMode into array types (necessary for syntax reasons)
        adrv9010.RadioCtrl.RxTxEnableSet(0x01, 0x01)                          # RX1 TX1 enabled 
        adrv9010.Agc.AgcCfgSet(agcConfigArr, 1)
        # -----------------------------------------------------End of setting AGC parameter-----------------------------------------------------
        adrv9010.RadioCtrl.RxTxEnableSet(0x01, 0x01)                                  # RX1 TX1 enabled 
        print "[Set] Rx1 and Tx1 enable."    
        RxTxEnableGetStatus = adrv9010.RadioCtrl.RxTxEnableGet(0, 0)  
        print "[Get Status] RxChannel: ", hex(RxTxEnableGetStatus[1]), "and TxChannel: ", hex(RxTxEnableGetStatus[2])
    
        # -----------------------------------------------------Test only starts--------------------------------------------------
    
        print "\n[Function Message starts]"
        TxTone = Types.adi_adrv9010_TxTestToneCfg_t()
        TxTone.txChannelMask = 0x01
        TxTone.enable = 1
        TxTone.txToneFreq_Hz = 30*1000000
        TxTone.txToneGain = Types.adi_adrv9010_TxNcoGain_e.ADI_ADRV9010_TX_NCO_0_DB    # ADI_ADRV9010_TX_NCO_NEG18_DB;  ADI_ADRV9010_TX_NCO_NEG12_DB;  ADI_ADRV9010_TX_NCO_NEG6DB;   ADI_ADRV9010_TX_NCO_0_DB   
        TxToneArr = Array[Types.adi_adrv9010_TxTestToneCfg_t]([TxTone])                # Make agcConfig and rxGainMode into array types (necessary for syntax reasons)
        adrv9010.Tx.TxTestToneSet(TxToneArr, 1)
        print "   [Set] (Tx1) Tone: 0dB"
        rxGainCtrlModeSet(Types.adi_adrv9010_RxAgcMode_e.ADI_ADRV9010_AGCSLOW, 0x01)   # (Default) ADI_ADRV9010_MGC, ADI_ADRV9010_AGCSLOW, ADI_ADRV9010_AGCFAST,;  0x01: Rx1   
        (Channel_RxGet_temp, RxGet_agcMode) = adrv9010.Rx.RxGainCtrlModeGet(Rx1, Types.adi_adrv9010_RxAgcMode_t())
        (Channel_RxGet_temp, RxGet_AgcGainIndexRange) = adrv9010.Agc.AgcGainIndexRangeGet(Rx1, Types.adi_adrv9010_AgcGainRange_t())
        (Channel_Tx_temp, TxGet_AttenMode, TxGet_AttenSimultUpdateCfg, TxGet_AttenPinCfg) = adrv9010.Tx.TxAttenModeGet(Tx1, Types.adi_adrv9010_TxAttenMode_e.ADI_ADRV9010_TXATTEN_SPI_MODE, Types.adi_adrv9010_TxAttenSimultUpdateCfg_t(), Types.adi_adrv9010_TxAttenPinCfg_t())
        print "   [Get] (Rx1) Gain Mode:", RxGet_agcMode.agcMode, "\n   [Get] AGC_MaxGain:", RxGet_AgcGainIndexRange.maxGainIndex, ", and AGC_MinGain:", RxGet_AgcGainIndexRange.minGainIndex 
        print "[Function Message ends]\n"
        print "[Tx_Attenuation & RX_GainIndex Data Starts]"    
        localtime = time.localtime() 
        # write data to file
        time_filename = time.strftime("_%m%d%Y_%H%M%S", localtime)
        path = str("C:\ADI\Output_Data" + time_filename + ".txt")  
        text_file = open(path, "w")                    # mode: 'w':write, 'a':appending,'+': Open a text file for updating
    
        
        # -----------------------------------------------------Test only ends-----------------------------------------------------
        k = 1
        table_x = (5, 15, 12, 0, 3, 5, 5, 15, 12, 0, 3, 5, 5, 15, 12, 0, 3, 5)
        for i in range(0, 1):
            #for x in range(0, 41, 1): 
            for x in range(0, 18):   # range(start, stop, step)
                adrv9010.RadioCtrl.RxTxEnableSet(0x01, 0x01)
                #atten = x
                atten = table_x[x]
                TxAtten = Types.adi_adrv9010_TxAtten_t()
                TxAtten.txAttenuation_mdB = int(atten) * 1000;
                TxAtten.txChannelMask = 0x01;
                TxAttenArr = Array[Types.adi_adrv9010_TxAtten_t]([TxAtten])                  # Make agcConfig and rxGainMode into array types (necessary for syntax reasons)
                adrv9010.Tx.TxAttenSet(TxAttenArr, 1)
                for y in range(0, 60, 1):
                    (Channel_temp, RxGainGet) = adrv9010.Rx.RxGainGet(Rx1, Types.adi_adrv9010_RxGain_t())             # Reads Rx AGC Gain Index 
                    (Channel_Tx_temp, TxGet_AttenNum) = adrv9010.Tx.TxAttenGet(Tx1, Types.adi_adrv9010_TxAtten_t())
                    Temp_Count = (k)
                    Temp_AttenNum = (TxGet_AttenNum.txAttenuation_mdB/1000.0)
                    Temp_GainIndex = (RxGainGet.gainIndex)
                    localtime = time.localtime()
                    Temp_time = time.strftime("%H:%M:%S", localtime)
                    text_file.write( str(Temp_Count) + "," + str(Temp_AttenNum) + "," + str(Temp_GainIndex) + "," + str(Temp_time) + "\n" )   # writelines is for list
                    print "( Count:", Temp_Count, ") [Tx1] Get_Attenuation:", Temp_AttenNum, "dB.  [Rx1] Gain_index:", Temp_GainIndex, "at", Temp_time  # channel depends on RxGainGet(Rx2,...) 
                    k = k + 1
                    time.sleep(0.5)   # unit: second
        text_file.close()
        print "[Tx_Attenuation & RX_GainIndex Data ends]"   
        print "[Data save successfully, close all ports]\n"
        adrv9010.RadioCtrl.RxTxEnableSet(0x00, 0x00)    
    
    else:
        print "Not Connected"
    
    if (connect):
        link.platform.board.Client.Disconnect()
        print "Disconnected"

Children