]> Gitweb @ Texas Instruments - Open Source Git Repositories - git.TI.com/gitweb - processor-sdk/pdk.git/blob - packages/ti/drv/aif2/test/cpricheckrf/ltetddcheckrf.c
aif2-lld: add to PDK
[processor-sdk/pdk.git] / packages / ti / drv / aif2 / test / cpricheckrf / ltetddcheckrf.c
1 /****************************************************************************\
2  *           (C) Copyright 2009, Texas Instruments, Inc.                    *
3  *                                                                          *
4  *  Redistribution and use in source and binary forms, with or without      *
5  *  modification, are permitted provided that the following conditions      *
6  *  are met:                                                                *
7  *                                                                          *
8  *    Redistributions of source code must retain the above copyright        *
9  *    notice, this list of conditions and the following disclaimer.         *
10  *                                                                          *
11  *    Redistributions in binary form must reproduce the above copyright     *
12  *    notice, this list of conditions and the following disclaimer in the   *
13  *    documentation and/or other materials provided with the                *
14  *    distribution.                                                         *
15  *                                                                          *
16  *    Neither the name of Texas Instruments Incorporated nor the names of   *
17  *    its contributors may be used to endorse or promote products derived   *
18  *    from this software without specific prior written permission.         *
19  *                                                                          *
20  *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS     *
21  *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT       *
22  *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR   *
23  *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT    *
24  *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,   *
25  *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT        *
26  *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,   *
27  *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY   *
28  *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT     *
29  *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE   *
30  *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.    *
31  ****************************************************************************
32  *                                                                          *
33  * Target processors : TMS320C66xx                                          *
34  *                                                                          *
35  \****************************************************************************/
37 //////////////////////////////////////////////////////////////////////////////
38 // Include Files
40 #include <stdio.h>
41 #include <stdlib.h>
42 #include <string.h>
43 #include <c6x.h>
44 #include <math.h>
46 #include <ti/csl/csl.h>
47 #include <ti/csl/csl_cache.h>
48 #include <ti/csl/csl_cacheAux.h>
49 #include <ti/csl/csl_xmcAux.h>
51 #include <ti/drv/aif2/aif2.h>
52 #include <ti/drv/cppi/cppi_drv.h>
53 #include <ti/drv/cppi/cppi_desc.h>
54 #include <ti/drv/qmss/qmss_drv.h>
55 #if EVM_TYPE == 3
56 #include <ti/platform/evmc6670l/platform_lib/include/evmc66x_pllc.h>
57 #endif
59 #if EVM_TYPE == 0
60 #include <EVM.h>
61 #endif
63 //include for GPIO
64 #include <ti/csl/csl_gpio.h>
65 #include <ti/csl/csl_gpioAux.h>
67 #include "cslUtils.h"
68 #include "mnavUtils.h"
69 #include "mathUtils.h"
71 #include <DSP_fft16x16.h>
72 #include <gen_twiddle_fft16x16.h>
73 #include <gen_twiddle_fft16x16.c>
75 #if EVM_TYPE == 5 || EVM_TYPE == 7
76 #include "appletonScbpSync.h"
77 #endif
79 /* TEST DESCRIPTION
80  * This CPRI LTE TDD Check RF test is designed to work either in internal loopback mode, or with a dual EVM setup connected with a break-out card, or with a
81  * CPRI Relay setup (tci6614 evm + scbp + tsw3726), or with a Scbp/Tsw3726 standalone setup.
82  * The default project configurations in the pdk-generated workspace are supporting:
83  * - EVM_LBACK: test compiled for internal loopback mode. Can be used with device simulators as well.
84  * - EVM6614: test compiled for CPRI Relay setup and run in RF loopback mode (rx1/rx2 and tx1/tx2 on tsw3726 are connected together)
85  * - SCBP_DSP1: test compiled for Scbp/Tsw3726 standalone setup and run in RF loopback mode (rx1/rx2 and tx1/tx2 on tsw3726 are connected together)
86  * - EVM6670_DSP1 and EVM6670_DSP2: test compiled for first and second EVMs of a dual EVM setup connected with a break-out card
87  *
88  * This CPRI LTE TDD Check RF test runs on a single link of AIF2 and configures 2 AxCs. Both AxCs IQ data are pure single or dual tone sinewaves at given frequencies,
89  * such that upon reception of LTE symbols for both antennas, IQ data can be checked with fft software. If the signal doesn't go from digital to analog and back, it
90  * can also be checked bitwise. For the purpose of TDD validation in RF loopback mode, only UL symbols are pushed in egress direction.
91  *
92  * Pre-processing constants of interest:
93  * - CPRI_RELAY_CFG: Set it to 1 as default. Set to 2 if testing towards tsw3726 RF board.
94  * - CPRI_RELAY_RATE: selects the LTE rate to be used. Values: 5, 10, or 20
95  * - EVM_TYPE: 1 - KeyStone-I internal loopback or EVM DSP1 (dual EVM setup), 2 - EVM DSP2 (dual EVM setup), 3 - SCBP DSP1, 5 - EVM6614 (Cpri Relay setup), (0 - old Lyrtech C6670 EVM)
96  *             6 - KeyStone-II internal loopback (EVM), 7 - EVM6638K2K (Cpri Relay setup)
97  * - LOOPBACK: selects internal loopback mode (SerDes level, AIF2 SW trigger)
98  *
99  * Note on usage with CPRI relay setup:
100  *              0. FPGA firmware upgrades:
101  *          a. Scbp board must be upgraded to the proper SCBP FPGA LTE version for the given LTE rate of interest.
102  *          b. Tci6614 EVM boards must be upgraded to v0004 of Fpga firmware
103  *              1. In order to run the CPRI relay test, go to the SCBP CPRI relay web interface and run the following config:
104  *                      a. For the CPRI relay loopback (loopback on the link0 through Scbp FPGA, CPRI_RELAY_CFG=1):
105  *                              - click on "Relay Init" to configure the pll with the 10Mhz reference clock, enable the SFP and SPI port.
106  *                              - Run the "relay LOOPBACK" button to configure the link0 for internal loopback in FPGA.
107  *                              - Load and run the code on the Appleton DSP.
108  *                      b. For the CPRI relay going through TI's RF (CPRI_RELAY_CFG=2), the radio needs to be configured as well as SCBP FPGA:
109  *                              - click on "Radio Init"
110  *                              - click on "Relay Init" to configure the pll with the 10Mhz reference clock, enable the SFP and SPI port.
111  *                              - load and run the Appleton code.
112  *                              - when the boards are synchronized (after few seconds), do a Radio ON to enable the radio.
113  *
114  *              In case of Cpri relay setup, the reference clock use to synchronize both board is a 10Mhz clock at 3.3V connected to the SCBP.
115  *              Then the SCBP generate a 16Hz pps signal that will be used by the Tci6614 board to synchronize with SCBP via the BoardsSync function.
116  *
117  * Note on Lte Symbol packet descriptors
118  * 14 symbols of an AxC subframe time are contained in 14 different monolithic descriptors. The pure single or dual tone sinewaves are generated in a continuous manner
119  * across the payload of the 14 symbols of a particular AxC. The test is configured to work at the granularity of a Lte slot. For LTE, AIF2 requires usage of monolithic
120  *  descriptor packets with a 16-byte header. In the header, a protocol specific word is required to indicate the antenna carrier number, the symbol number and the direction
121  *  (Ingress/Egress). That means that every 0.5 ms, the test will push and pop from the AIF2 HW queues:
122  * 7 symbols * numAxCs per link * numLinks * 2 (for Egress/Ingress traffic)
123  * This then makes a total of 56 outstanding monolithic packets in the case of LTE 20MHz / 2 AxCs / 1 Links / both directions
124  * When defining a descriptor memory region, the following rules apply:
125  * - Descriptor size is multiple of 16 bytes, min 32.
126  * - Descriptor count is a power of 2, minimum 25.
127  * - Memory region base address must be aligned to a 16-byte address boundary.
128  * Here are some considerations regarding PktDMA traffic:
129  *              - For Egress, it is up to the user to insure that DMA data is available prior to beginning PE message construction (PE2 event). Breaking real time on DMA has
130  *              similar effects to breaking CorePac MIPS real time. Specifically, AIF2 will fail each affected AxC until the beginning of the next radio frame boundary.
131  *              - For Ingress, it is important that DMA is efficient enough that the AIF2 input buffers never overflow.
132  *              - TDD specifics: for TX, TDD_AXC mode should be enabled in PE, if it is turned on, PE will insert symbol only when it receives the packet from packet DMA.
133  *              So, it is user\92s responsibility to not push packets into the packet DMA TX queue during inactive TDD time slots; and for active TDD timer slots, user should
134  *              take care the time to push packet into the TX queue. A packet should  only be pushed into TX queue just one packet ahead, for example, if packet of
135  *              LTE symbol N need be sent in active TDD time slot, then packet N must be pushed into the TX queue  in the time period of symbol (N-1).
136  *              For RX, PD implements programmable bit map for each channel, each bit corresponds to one packet in a radio Frame, \931\94 means corresponding packet will be
137  *              received, \930\94 means that packet will be dropped. Please note, in LTE protocol level, the TDD is controlled in the unit of sub frame, but the AIF2 PD TDD
138  *              bit map is defined in the unit of packets, and one LTE sub frame includes multiple packets (symbols), so the LTE TDD \93bit map\94 in sub frame should be
139  *              expanded to PD TDD \93bit map\94 in packets, that is, we need to program multiple bits to select each LTE symbol in a sub frame.
140  *              Example with AIF2 LLD:
141  *              aifObj.linkConfig[i].lteTddUlDlCfg[j]   = AIF2_LTETDD_ULDL_CFG0;        // UL DL configuration for Lte TDD
142  *              aifObj.linkConfig[i].lteTddSsfNcpCfg[j] = AIF2_LTETDD_SSF_NCP_CFG0;     // Special SF configuration for Lte TDD
143  */
146 ////////////////////////////////////////////////////////////////////////////////
147 // Constant definitions
149 #define     TRIG_TIMER          0       // Used to start AIF2 timers, Frame sync with one shot pulse - could be any timer
150 #if defined(DEVICE_K2K) || defined(DEVICE_K2H)
151 #define         SYNC_TIMER                      8
152 #else
153 #define     SYNC_TIMER          5       // Used to call the SW PLL periodically - Cpri relay setup only - could be an OS PRD thread as well
154 #endif
155 #define     PLL_TIMER           4       // Used by the SW PLL for adjustments against the external 16Hz clock - Cpri relay setup only - could be any timer
157 //Value for Sin calculation
158 #if CPRI_RELAY_CFG == 1
159 #define     Q_FACTOR            511             // When the signal stays digital, reducing Q factor to avoid overflow in fft software
160 #else
161 #define     Q_FACTOR            2047    // 8191
162 #endif
163 #if CPRI_RELAY_RATE == 20
164 #define     SAMP_FREQ_FLOAT     30.72   // LTE20 sample rate
165 #elif CPRI_RELAY_RATE == 10
166 #define     SAMP_FREQ_FLOAT     15.36   // LTE10 sample rate
167 #elif CPRI_RELAY_RATE == 5
168 #define     SAMP_FREQ_FLOAT     7.68    // LTE5 sample rate
169 #else
170 #error          "CPRI_RELAY_RATE not valid."
171 #endif
172 #define     PI                  3.14159265358979323846
174 #define     TEST_NUM            2       // Number of test configurations
175 #define         _AIF2FL_DUMP            0       // Enable the DUMP of the AIF configuration, for debug purposes
176 #define     NBCHANNELPERLINK    2       // Number of AxCs in use per link
177 #if CPRI_RELAY_RATE == 20
178 #define     NBCHANNELMAXPERLINK 2       // Max number of AxCs per link
179 #elif CPRI_RELAY_RATE == 10
180 #define     NBCHANNELMAXPERLINK 4       // Max number of AxCs per link
181 #elif CPRI_RELAY_RATE == 5
182 #define     NBCHANNELMAXPERLINK 8       // Max number of AxCs per link
183 #endif
184 #define     NBSYMBOL                    AIF2_LTE_SYMBOL_NUM                                                                                     // Number of symbols per slot
185 #if CPRI_RELAY_RATE == 20
186 #define         LTESYMBOLSIZE           ((AIF2_LTE20_FFT_SIZE+AIF2_LTE20_CYPRENORMAL1_SIZE)*4 + 16)    // 8848: FFT size + CP first
187 #define         LTESYMBOL2SIZE          ((AIF2_LTE20_FFT_SIZE+AIF2_LTE20_CYPRENORMAL_SIZE)*4 + 16)     // 8784: FFT size + CP 2nd-6th
188 #define         FFT_SIZE                        AIF2_LTE20_FFT_SIZE
189 #define         CYPRENORMAL1_SIZE       AIF2_LTE20_CYPRENORMAL1_SIZE
190 #define         CYPRENORMAL_SIZE        AIF2_LTE20_CYPRENORMAL_SIZE
191 #elif CPRI_RELAY_RATE == 10
192 #define         LTESYMBOLSIZE           ((AIF2_LTE10_FFT_SIZE+AIF2_LTE10_CYPRENORMAL1_SIZE)*4 + 16)    
193 #define         LTESYMBOL2SIZE          ((AIF2_LTE10_FFT_SIZE+AIF2_LTE10_CYPRENORMAL_SIZE)*4 + 16)
194 #define         FFT_SIZE                        AIF2_LTE10_FFT_SIZE
195 #define         CYPRENORMAL1_SIZE       AIF2_LTE10_CYPRENORMAL1_SIZE
196 #define         CYPRENORMAL_SIZE        AIF2_LTE10_CYPRENORMAL_SIZE
197 #elif CPRI_RELAY_RATE == 5
198 #define         LTESYMBOLSIZE           ((AIF2_LTE5_FFT_SIZE+AIF2_LTE5_CYPRENORMAL1_SIZE)*4 + 16)
199 #define         LTESYMBOL2SIZE          ((AIF2_LTE5_FFT_SIZE+AIF2_LTE5_CYPRENORMAL_SIZE)*4 + 16)
200 #define         FFT_SIZE                        AIF2_LTE5_FFT_SIZE
201 #define         CYPRENORMAL1_SIZE       AIF2_LTE5_CYPRENORMAL1_SIZE
202 #define         CYPRENORMAL_SIZE        AIF2_LTE5_CYPRENORMAL_SIZE
203 #endif
205 #define         NBCHANNELINIT           1
207 #if EVM_TYPE == 0 || EVM_TYPE == 3 || EVM_TYPE == 5 || EVM_TYPE == 7
208 #define     DESCMSM                             1                       // Putting packet descriptors in internal MSM
209 #else
210 #define     DESCMSM                             1                       // else going to DDR
211 #endif
212 #define         NBDESCMAX                       64          // Descriptor count rounded to the next power of 2
213 #define         MAX_DEBUG_SYMBOL        280                     // For debug, size of monitoring arrays
214 #if EVM_TYPE == 0 || EVM_TYPE == 3
215 #define     SYSCLK_INPUT_KHZ    153600          // on Lyrtech and Scbp EVM, the Frequency is based on an external 153.60 MHz clock
216 #else
217 #define     SYSCLK_INPUT_KHZ    122880          // on Advantech EVM , the Frequency is based on an external 122.88 MHz clock
218 #endif
220 #define     DIO_0               AIF2FL_DIO_ENGINE_0 // DIO engines are not used in LTE mode - instead PKTDMA and HW queues are used to carry the antenna data from/to AIF2
222 #define         MONO_RX_FDQ         2012 // Define Rx queue base index for ingress traffic and the associated Rx free descriptor queue base index
223 #define         MONO_RX_Q           1000
225 #define         RX_SUCCESS_CNT          (32000*7) // Define a number of consecutive runtime RF check success prior to monitoring runtime failures
226                                                                                   // RF checks now done at symbol pace
228 #define         FREQ                            1.0
229 #define     PEAK_LOC_2MHZ               (FFT_SIZE/SAMP_FREQ_FLOAT*FREQ*2) // Used for peak detection after fft on Rx symbols  - 2048/30.72*2MHz, same for Lte5 or Lte10
230 #define         PEAK_LOC_1MHZ           (FFT_SIZE/SAMP_FREQ_FLOAT*FREQ)   // Used for peak detection after fft on Rx symbols  - 2048/30.72*1MHz, same for Lte5 or Lte10
231 #define         N   (2048)                                                                                        // Used for twiddle factor generation
232 #define         PAD (16)                                                                                          // Used for twiddle factor generation
234 #ifdef LOOPBACK
235 #define FIRST_SYMBOL_PUSH       139                     // The first push needs to happen on the last symbol number before frame boundary
236 #else
237 #define FIRST_SYMBOL_PUSH       138
238 #endif
239 #if CPRI_RELAY_CFG == 2
240 #define SYMBOL_NUM_DATA_CHECK   (75000*7)       // If NEVER_END_TEST == 0, test stops after this amount of Lte slots
241 #else
242 #define SYMBOL_NUM_DATA_CHECK   (7500*7)        // If NEVER_END_TEST == 0, test stops after this amount of Lte slots
243 #endif
245 //////////////////////////////////////////////////////////////////////////////
246 // Typedefs
248 typedef struct {
249         int16_t re;
250         int16_t im;
251         } Complex16;
253 typedef struct {
254         // Test name
255         const unsigned char name[32];
256         //AIF link enable or disable, 1 or 0
257         uint32_t                   linkEnable[AIF_MAX_NUM_LINKS];
258         //AIF link rate (1=1x; 2=2x; 4= 4x).
259         uint32_t                   linkRate[AIF_MAX_NUM_LINKS];
260         //AIF link data type for outbound burst traffic.
261         Aif2Fl_LinkDataType     outboundDataType[AIF_MAX_NUM_LINKS];
262         //AIF link data width for outbound burst traffic.
263         Aif2Fl_DataWidth        outboundDataWidth[AIF_MAX_NUM_LINKS];
264         //AIF link data type for inbound burst traffic.
265         Aif2Fl_LinkDataType     inboundDataType[AIF_MAX_NUM_LINKS];
266         //AIF link data width for inbound burst traffic.
267         Aif2Fl_DataWidth        inboundDataWidth[AIF_MAX_NUM_LINKS];
268         //AIF link DIO engine used
269         Aif2Fl_DioEngineIndex   dioEngine[AIF_MAX_NUM_LINKS];
270         } TestObj;
272 //////////////////////////////////////////////////////////////////////////////
273 // Global variables
274 AIF_ConfigObj               aifObj;                                     // Main AIF2 LLD object for AIF2 configuration
275 AIF_ConfigHandle            hConfigAif = &aifObj;
277 #if EVM_TYPE == 3
278 uint32_t NEVER_END_TEST=1;                              // Enable the infinite loop for visual check when running on SCBP-TSW standalone setup
279 #else
280 uint32_t NEVER_END_TEST = 0;                            // Test stops after a given number of Lte slots
281 #endif
283 volatile unsigned int ntest = 0;                // used for running multiple tests
284 volatile unsigned int testcheck = 1;    // reports pass fail at the end of the test
286 #ifdef LOOPBACK
287 volatile unsigned int swSync        = 1;        // AIF2 SW trigger
288 volatile unsigned int intLoopback   = 1;        // SerDes loopback mode
289 #else
290 volatile unsigned int intLoopback   = 0;
291 #if EVM_TYPE == 3
292 volatile unsigned int swSync        = 1;
293 #else
294 volatile unsigned int swSync        = 0;
295 #endif
296 #endif
298 volatile unsigned char testEnable[TEST_NUM] =
299     {
300 #if EVM_TYPE == 5 || EVM_TYPE == 7
301         1,     // CPRI 4x - Link 3 is used on CPRI relay setup to connect TCI6614 EVM and SCBP via SFP
302         0
303 #else
304         0,     // CPRI 4x - Link 0
305                 1
306 #endif
307     };
309 volatile TestObj                     testObjTab[TEST_NUM] = {
310         {//1st configuration - CPRI 4x - Link 3 is used on CPRI relay setup to connect TCI6614 EVM and SCBP via SFP
311 #if CPRI_RELAY_RATE == 20
312           "LTETDD_RELAY_20MHZ_RF_CHECK", // test name
313 #elif CPRI_RELAY_RATE == 10
314           "LTETDD_RELAY_10MHZ_RF_CHECK", // test name
315 #elif CPRI_RELAY_RATE == 5
316           "LTETDD_RELAY_5MHZ_RF_CHECK", // test name
317 #endif
318          // link0          link1          link2          link3          link4          link5
319           {0,             0,             0,             1,             0,             0            },  // link enable
320           {4,             4,             4,             4,             4,             4            },  // link rate
321           {DATA_TYPE_DL,  DATA_TYPE_DL,  DATA_TYPE_DL,  DATA_TYPE_DL,  DATA_TYPE_DL,  DATA_TYPE_DL },  // outboundDataType
322           {DATA_WIDTH_15, DATA_WIDTH_15, DATA_WIDTH_15, DATA_WIDTH_15, DATA_WIDTH_15, DATA_WIDTH_15},  // outboundDataWidth
323           {DATA_TYPE_DL,  DATA_TYPE_DL,  DATA_TYPE_DL,  DATA_TYPE_DL,  DATA_TYPE_DL,  DATA_TYPE_DL },  // inboundDataType
324           {DATA_WIDTH_15, DATA_WIDTH_15, DATA_WIDTH_15, DATA_WIDTH_15, DATA_WIDTH_15, DATA_WIDTH_15},  // inboundDataWidth
325           {DIO_0,         DIO_0,         DIO_0,         DIO_0,         DIO_0,         DIO_0},          // not applicable for LTE test
326         },
327         {//2nd configuration - CPRI 4x - Link 0
328 #if CPRI_RELAY_RATE == 20
329           "LTETDD_RELAY_20MHZ_RF_CHECK", // test name
330 #elif CPRI_RELAY_RATE == 10
331           "LTETDD_RELAY_10MHZ_RF_CHECK", // test name
332 #elif CPRI_RELAY_RATE == 5
333           "LTETDD_RELAY_5MHZ_RF_CHECK", // test name
334 #endif
335          // link0          link1          link2          link3          link4          link5
336           {1,             0,             0,             0,             0,             0            },  // link enable
337           {4,             4,             4,             4,             4,             4            },  // link rate
338           {DATA_TYPE_DL,  DATA_TYPE_DL,  DATA_TYPE_DL,  DATA_TYPE_DL,  DATA_TYPE_DL,  DATA_TYPE_DL },  // outboundDataType
339           {DATA_WIDTH_15, DATA_WIDTH_15, DATA_WIDTH_15, DATA_WIDTH_15, DATA_WIDTH_15, DATA_WIDTH_15},  // outboundDataWidth
340           {DATA_TYPE_DL,  DATA_TYPE_DL,  DATA_TYPE_DL,  DATA_TYPE_DL,  DATA_TYPE_DL,  DATA_TYPE_DL },  // inboundDataType
341           {DATA_WIDTH_15, DATA_WIDTH_15, DATA_WIDTH_15, DATA_WIDTH_15, DATA_WIDTH_15, DATA_WIDTH_15},  // inboundDataWidth
342           {DIO_0,         DIO_0,         DIO_0,         DIO_0,         DIO_0,         DIO_0},          // not applicable for LTE test
343         }
344    };
346 /* Monolithic descriptor region for all outstanding symbols in a subframe (1ms)
347  * Region base address is 16-byte aligned. (aligning to a L1D 64-byte cache line boundary)
348  * The linker will place this >1MBytes buffer in internal shared memory (MSM)
349  * symbolcount size is 8.8K bytes for Normal cyclic prefix 20 MHz LTE
350  */
351 #if DESCMSM == 1
352 #pragma DATA_SECTION(mono_region_test,".aifdescmsm");
353 #else
354 #pragma DATA_SECTION(mono_region_test,".aifdescddr");
355 #endif
356 #pragma DATA_ALIGN (mono_region_test, 64);
357 uint8_t   mono_region_test[NBDESCMAX * LTESYMBOLSIZE * NBCHANNELINIT];
359 /*
360  * Buffers storing TX and RX symbols for debug and verification
361  */
362 #pragma DATA_SECTION(txSamples,".aifdescddr");
363 uint8_t   txSamples[NBCHANNELPERLINK][NBSYMBOL*2][LTESYMBOLSIZE - 16];
364 #pragma DATA_SECTION(rxSamples,".aifdescddr");
365 uint8_t   rxSamples[NBCHANNELPERLINK][NBSYMBOL*2][LTESYMBOLSIZE - 16];
367 /*
368  * Variables used for RF checks
369  */
370 uint8_t   rxBuffer[NBCHANNELPERLINK+1][LTESYMBOLSIZE-16]; // MUST BE IN LL2 to enable HW cache coherency
371 uint8_t   rxCheck[NBCHANNELPERLINK][NBSYMBOL];                  // Keeps track of current check of all LTE symbols on a slot per AxC
372 uint16_t  rxRuntimeFail[NBCHANNELPERLINK][NBSYMBOL];            // Keeps track of the number of failures per LTE symbols on a slot per AxC
373 uint8_t   rxCheckCnt=0;                                                                 // Counter
374 uint32_t  rxRuntimeSuccess=0;                                                           // Counter
376 /*
377  *      Variables used fft software
378  */
379 #pragma DATA_ALIGN(twiddleFacts, 8);
380 int16_t   twiddleFacts[2*N + 2*PAD];
382 /*
383  * Define an array that can contain all descriptor addresses.
384  * This way, all packets can be popped from the FDQ and prepared at once for the purpose of this test.
385  */
386 Cppi_MonolithicDesc* symbolPkt[NBCHANNELMAXPERLINK][NBSYMBOL*2];
388 /* Storing first sample of each packet to check packet sequence at runtime */
389 Complex16 firstSample[NBCHANNELMAXPERLINK][NBSYMBOL*2];
391 /*
392  * Define Rx flows for AIF2 ingress traffic
393  * The flow will tell AIF2 from which FDQ to pop new symbol descriptors
394  */
395 Cppi_RxFlowCfg rxFlow[AIF_MAX_NUM_LINKS][NBCHANNELMAXPERLINK];
397 /* Variables for test purposes */
398 uint32_t nbchanneltotal    = NBCHANNELPERLINK; // Default to 1 link
399 uint32_t   activeLink;                                          // link configured at test init time
401 /*
402  * Slot and symbolcount counters - some used for debug purposes
403  */
404 #ifdef LOOPBACK
405 volatile uint32_t symbolcount = 1;              //for Loopback test, the frame boundary occurs with a delay of 1 symbol (sw sync issue)
406 volatile uint32_t symbolslotcount = 1;  // count from 0 to 6 and is used to determine the symbol length
407 #else
408 volatile uint32_t symbolcount = 2;              //for no-Loopback test, the frame boundary occurs with a delay of 2 symbols (phy sync issue)
409 volatile uint32_t symbolslotcount = 2;
410 #endif
412 volatile uint32_t totalsymbolcount = 0;
413 volatile uint32_t aif2SymbolEgressCount[MAX_DEBUG_SYMBOL];
414 volatile uint32_t aif2SymbolIngressCount[MAX_DEBUG_SYMBOL];
415 volatile uint32_t getCpuTimestamp[MAX_DEBUG_SYMBOL];
416 volatile uint32_t getPhyTimerFrames[MAX_DEBUG_SYMBOL];
417 volatile uint32_t getPhyTimerClk[MAX_DEBUG_SYMBOL];
418 volatile uint32_t getRadtSymbolCnt[MAX_DEBUG_SYMBOL];
419 volatile uint32_t egressSymEnable[144];
420 volatile uint32_t receivedPacket[NBCHANNELPERLINK];
421 volatile uint32_t dbgSymbol = 0;
422 volatile uint32_t checkRfTimerStamp[3];
423 volatile uint32_t checkchan = 0;
424 #if CPRI_RELAY_CFG != 2         // if not using the CPRI relay with the RF, we can check every packet first data in order to verify if it's not null.
425 volatile uint32_t badPacket = 0;
426 volatile uint32_t goodPacket = 0;
427 #endif
429 /*
430  * Flag used for printing out exceptions at the end of the test.
431  * Please note that exceptions are always enabled during this test.
432  * Having AIF2 exceptions reported during this test should be considered as a test failure.
433  *
434  */
435 uint32_t printexceptions = 1;
437 //////////////////////////////////////////////////////////////////////////////
438 // References to external variables
440 extern uint8_t             keepAifOff;
441 extern uint8_t             keepStartupDelay;
442 //extern int                   PEAKDEBUG;
444 //////////////////////////////////////////////////////////////////////////////
445 // Function prototypes
447 #if _AIF2FL_DUMP == 1
448 void dump_Aif2Fl_Setup (FILE *output, Aif2Fl_Setup *value);
449 #endif
450 void getcomplex(Complex16* payload,uint32_t index,uint32_t tx);
451 void UTILS_setLteTddDlBitmap(AIF2_LteTddUlDlCfg tddSubFrameBitMap, AIF2_LteTddSsfNcpCfg tddSpecSubFrameBitMap);
453 //////////////////////////////////////////////////////////////////////////////
454 // Function bodies
456 /*
457  * User Isr that is called from pre-defined Isr in cslUtils.c, called every Lte symbol
458  */
459 void symbolIsr()
461         uint32_t chan, i, checkrf;
462         uint32_t               rxSymCnt, payloadLen;
463         Cppi_MonolithicDesc *ptrMonoDesc, *ptrMonoDescRx;
464         uint32_t              *payloadPtr;
465         int32_t                         testrf;
467     getPhyTimerFrames[dbgSymbol]   = aifObj.hFl->regs->AT_PHYT_FRM_VALUE_LSBS;
468     getPhyTimerClk[dbgSymbol]      = aifObj.hFl->regs->AT_PHYT_CLKCNT_VALUE;
469     getRadtSymbolCnt[dbgSymbol]   = (aifObj.hFl->regs->AT_RADT_VALUE_LSBS >> 19);
471     aif2SymbolEgressCount[dbgSymbol]  = aifObj.hFl->regs->DB_EDB_EOP_CNT;
472         aif2SymbolIngressCount[dbgSymbol] = aifObj.hFl->regs->AD_ISCH_EOP_CNT;
474         checkrf = 0;
476         if ((totalsymbolcount <= SYMBOL_NUM_DATA_CHECK) || (NEVER_END_TEST == 1))
477         {
479                 for(chan = 0; chan < nbchanneltotal; chan++)
480                 {
481                         rxSymCnt = Qmss_getQueueEntryCount(aifObj.pktDmaConfig.rxQAxC[chan]);
483                         for(i=0;i<rxSymCnt;i++)
484                         {
485                                 ptrMonoDescRx = (Cppi_MonolithicDesc *)QMSS_DESC_PTR(Qmss_queuePop(aifObj.pktDmaConfig.rxQAxC[chan]));
486                                 CACHE_invL1d((void *)ptrMonoDescRx, 16+8, CACHE_WAIT);
487                                 Cppi_getData (Cppi_DescType_MONOLITHIC, (Cppi_Desc*)ptrMonoDescRx, (uint8_t**)&payloadPtr, &payloadLen);
488                                  //check payload length
489                                 if ((payloadLen != (LTESYMBOLSIZE-16)*NBCHANNELINIT) && (payloadLen != (LTESYMBOL2SIZE-16)*NBCHANNELINIT))
490                                 {
491                                         UTILS_aif2ExceptIntDisable();
492                                         totalsymbolcount = SYMBOL_NUM_DATA_CHECK  + DSP_procId;
493                                         NEVER_END_TEST = 0;
494                                         printf("FATAL: unexpected payload length:%d\n",payloadLen);
495                                         AIF_printException(&aifObj);
496                                 } else {
497                                         if (checkchan == chan) {
498                                         CACHE_invL1d((void *)payloadPtr, payloadLen, CACHE_WAIT);
499                                         memcpy(&rxBuffer[chan][0],(uint32_t *) payloadPtr, payloadLen);
500 #if     EVM_TYPE == 5 || EVM_TYPE == 7 || EVM_TYPE == 8
501                                         checkrf = 1;
502 #endif
503                                         }
504                                 }
505 #if CPRI_RELAY_CFG != 2         //store the number of symbols that are good or bad.
506                                 if ((payloadPtr[0] == 0)&&(payloadPtr[1] == 0))
507                                 {
508                                         badPacket++;
509                                 } else{
510                                         goodPacket++;
511                                 }
512 #endif
513                                 // recycle symbol packet on rx free queue
514                                 Qmss_queuePushDesc(aifObj.pktDmaConfig.rxFqAxC[chan], (uint32_t*)ptrMonoDescRx);
515                         }
516                         receivedPacket[chan] += rxSymCnt;
517                 }
518         }
520         if (totalsymbolcount == SYMBOL_NUM_DATA_CHECK) {
521         UTILS_aif2ExceptIntDisable();
522     }
524         if ((totalsymbolcount>=FIRST_SYMBOL_PUSH))
525         {
526                 for(chan = 0; chan < nbchanneltotal; chan++)
527                 {
528                         if((1==egressSymEnable[symbolcount])||(totalsymbolcount<(FIRST_SYMBOL_PUSH+7)))
529                         {
530                                 ptrMonoDesc = (Cppi_MonolithicDesc *)QMSS_DESC_PTR(Qmss_queuePop(aifObj.pktDmaConfig.txFqAxC[chan]));
531                                 if(ptrMonoDesc!= NULL)
532                                 {
533                                         CACHE_invL1d((void *)ptrMonoDesc, 16, CACHE_WAIT);
534                                         if((symbolslotcount) == 0) {
535                                                 Cppi_setPacketLen(Cppi_DescType_MONOLITHIC,(Cppi_Desc *)ptrMonoDesc,(LTESYMBOLSIZE-16));
536                                         } else {
537                                                 Cppi_setPacketLen(Cppi_DescType_MONOLITHIC, (Cppi_Desc *)ptrMonoDesc,(LTESYMBOL2SIZE-16));
538                                         }
539                                         Cppi_getPSData (Cppi_DescType_MONOLITHIC, Cppi_PSLoc_PS_IN_DESC, (Cppi_Desc*)ptrMonoDesc, (uint8_t**)&payloadPtr, &payloadLen);
540                                         payloadPtr[0] = (uint32_t )(0x00008000 + chan + ((symbolcount) << 7));//add symbol number into PS field
541                                         CACHE_wbL1d((void *)ptrMonoDesc, 16, CACHE_WAIT); // writeback the descriptor header in MSM
542                                         Qmss_queuePushDesc((aifObj.pktDmaConfig.txQAxC[chan]), (uint32_t*)ptrMonoDesc);
543                                 } else {
544                                         printf ("Tx free Q is empty at symbol %d\n",totalsymbolcount);
545                                         UTILS_aif2ExceptIntDisable();
546                                         totalsymbolcount = SYMBOL_NUM_DATA_CHECK  + DSP_procId;
547                                         NEVER_END_TEST = 0;
548                                         printf("FATAL: unexpected payload length:%d\n",payloadLen);
549                                         AIF_printException(&aifObj);
550                                 }
551                         }
552                 }
553         }
555         if (checkrf == 1)
556         {
557                 checkRfTimerStamp[0] = TSCL;
558                 DSP_fft16x16(&twiddleFacts[PAD], FFT_SIZE, (int16_t*)&rxBuffer[checkchan][CYPRENORMAL_SIZE*4], (int16_t*)&rxBuffer[2][0]);
559                 checkRfTimerStamp[1] = TSCL;
560                 if (checkchan == 0) {
561                         testrf = checkSingleTone((int16_t*)&rxBuffer[2][0],FFT_SIZE,PEAK_LOC_1MHZ,0);
562                 } else {
563                         testrf = checkDualTone((int16_t*)&rxBuffer[2][0],FFT_SIZE,PEAK_LOC_1MHZ,PEAK_LOC_2MHZ,1);
564                 }
565                 if (testrf)
566                 {
567                         checkRfTimerStamp[2] = TSCL;
568                         rxCheck[checkchan][symbolslotcount] = 1;
569                         if (rxRuntimeSuccess < RX_SUCCESS_CNT) rxRuntimeSuccess++;
570                 } else {
571                         checkRfTimerStamp[2] = TSCL;
572                         rxCheck[checkchan][symbolslotcount] = 0;
573                         if (rxRuntimeSuccess == RX_SUCCESS_CNT){
574                                 rxRuntimeFail[checkchan][symbolslotcount]++;
575                         }
576                         else rxRuntimeSuccess = 0;
577                 }
578                 checkchan++;
579                 if (checkchan == nbchanneltotal) checkchan=0;
580         }
582     if (totalsymbolcount == FIRST_SYMBOL_PUSH) {
583         AIF_enableException(&aifObj);
584     }
586         /* PktDMA activity monitoring */
587         aif2SymbolEgressCount[dbgSymbol]  = aifObj.hFl->regs->DB_EDB_EOP_CNT;
588         aif2SymbolIngressCount[dbgSymbol] = aifObj.hFl->regs->AD_ISCH_EOP_CNT;
589     symbolcount++;
590     symbolslotcount++;
591         totalsymbolcount++;
592         dbgSymbol++;
593         if (symbolcount == AIF2_LTE_FRAME_SYMBOL_NUM) symbolcount = 0;
594         if (symbolslotcount == AIF2_LTE_SYMBOL_NUM) symbolslotcount = 0;
595         if (dbgSymbol == MAX_DEBUG_SYMBOL) dbgSymbol = 0;
599 int main(void)
601     uint32_t               idx, idx1, idx2, i, payloadLen, testpass, j, nblink = 1;
602     uint16_t               myboard      = EVM_TYPE;
603         uint32_t               monoRxCount, monoTxCount, rx_count, value;
604         Complex16            *payloadPtr;
605         Cppi_MonolithicDesc  *ptrMonoDesc;
607         uint32_t               chan;
608     Cppi_MonolithicDesc *mono_pkt;
609     Qmss_Queue                   descQueue;
610     Qmss_Queue           queueInfo;
611     Cppi_DescTag                 descTag;
612 #if EVM_TYPE == 3
613     PllcHwSetup pllc_hwSetup;
614 #endif
615 #ifdef SIMULATOR_SUPPORT
616         printf ("\n Error: This example code does not run on the simulator.\n\n");
617         return(0);
618 #endif
620     /* Make shared memory (MSM) non cacheable for the purpose of testing */
621     CSL_XMC_invalidatePrefetchBuffer();
622     CACHE_setMemRegionInfo(12,1,0); // MAR12 - cacheable (always), not prefetchable
623     CACHE_setMemRegionInfo(13,1,0); // MAR13 - cacheable (always), not prefetchable
625 #if CPRI_RELAY_CFG == 1
626     printf("Beginning AIF2 LTE TDD CPRI relay Software testing\n");
627 #else
628     printf("Starting AIF2 LTE TDD CPRI relay Software\n");
629 #endif
631     UTILS_waitForHw(100000);
633     if (myboard == 0)  UTILS_configMasterSlave();
634     else if (EVM_TYPE == 5) DSP_procId = 1;
635         else if (EVM_TYPE == 6) DSP_procId = 1;
636     else if (EVM_TYPE == 7) DSP_procId = 1;
637     else if (myboard <= 2)  DSP_procId = EVM_TYPE; // For Advantech: myboard  = 1 (DSP_1) or 2 (DSP_2)
638     else DSP_procId = (uint8_t)(EVM_TYPE - 2);       // For SCBP: myboard  = 3 (DSP_1) or 4  (DSP_2)
640 #if EVM_TYPE == 3
641     /* Clear local data structures */
642         memset(&pllc_hwSetup, 0, sizeof(PllcHwSetup));
644         /* Setup PLLC hardware parameters */
645         pllc_hwSetup.divEnable  = (CSL_BitMask32) (PLLC_DIVEN_PLLDIV2 |
646                                                                                            PLLC_DIVEN_PLLDIV5 |
647                                                                                            PLLC_DIVEN_PLLDIV8) ;
649         /* Setup PLLC hardware parameters */
650         pllc_hwSetup.pllM       = 16 -1;
651         pllc_hwSetup.preDiv   = 1 - 1;
652         pllc_hwSetup.pllDiv2  = 3 - 1;
653         pllc_hwSetup.pllDiv5  = 5 - 1;
654         pllc_hwSetup.pllDiv8  = 64 - 1;
655         pllc_hwSetup.postDiv  = 2 -1;
657         /* set Pll */
658         CorePllcHwSetup(&pllc_hwSetup);
659 #endif
661    // AIF2 LLD programs AT event 6 with lte symbol period in case of LTE
662    aif2evt6_userIsr = symbolIsr;
664         // Take AIF out of power saver
665         AIF_enable();
667 #ifdef USE_SMA
668         // disable link 0 on DSP_1
669         testObjTab[ntest].linkEnable[3]  = 0;
670         testObjTab[ntest].linkEnable[4]  = 1;
671         activeLink = 4;
672 #endif
675         // General parameters
676         memset(&aifObj, 0, sizeof(aifObj));
677         aifObj.aif2ClkSpeedKhz    = (uint32_t)SYSCLK_INPUT_KHZ;
678         aifObj.protocol           = AIF2FL_LINK_PROTOCOL_CPRI;
679         aifObj.pktdmaOrDioEngine  = AIF2FL_CPPI;
680         aifObj.mode               = AIF_LTE_TDD_MODE;
681         aifObj.superPacket                = false;
683         if (swSync == 0)
684                 aifObj.aif2TimerSyncSource= AIF2FL_PHYT_CMP_SYNC;
685         else
686                 aifObj.aif2TimerSyncSource= AIF2FL_SW_SYNC;
688         UTILS_setLteTddDlBitmap(AIF2_LTETDD_ULDL_CFG0, AIF2_LTETDD_SSF_NCP_CFG0);
690     for(ntest=0;ntest<TEST_NUM;ntest++)
691         {
692         if (testEnable[ntest] == 1 )
693         {
694                 chan    = 0;
695                 nblink  = 0 ;
696                         for (i=0;i<AIF_MAX_NUM_LINKS;i++)
697                         {
698                                 if (testObjTab[ntest].linkEnable[i]==1 && (aifObj.linkConfig[i].RtEnabled==0))
699                                 {
700                                         nblink++;
701                                         // PktDma parameters
702                                         for (idx=0 ; idx<NBCHANNELPERLINK ; idx++)
703                                         {
704                                                 aifObj.pktDmaConfig.txRegionAxC[chan]   = UTILS_getMemRegionNum(mono_region_test);
705                                                 aifObj.pktDmaConfig.txNumDescAxC[chan]  = NBSYMBOL*2; // double num of Pkts
706                                                 aifObj.pktDmaConfig.txDescSizeAxC[chan] = LTESYMBOLSIZE;
707                                                 aifObj.pktDmaConfig.rxRegionAxC[chan]   = UTILS_getMemRegionNum(mono_region_test);
708                                                 aifObj.pktDmaConfig.rxNumDescAxC[chan]  = NBSYMBOL*2; // double num of Pkts
709                                                 aifObj.pktDmaConfig.rxDescSizeAxC[chan] = LTESYMBOLSIZE*NBCHANNELINIT;
711                                                 memset(&rxFlow[i][idx], 0, sizeof(Cppi_RxFlowCfg));
712                                                 rxFlow[i][idx].rx_dest_qnum     = MONO_RX_Q+chan;
713                                                 rxFlow[i][idx].rx_fdq0_sz0_qnum = MONO_RX_FDQ+chan;
714                                                 rxFlow[i][idx].rx_desc_type     = (uint8_t)Cppi_DescType_MONOLITHIC;    // MONO
715                                                 rxFlow[i][idx].rx_fdq1_qnum     = MONO_RX_FDQ+chan;
716                                                 rxFlow[i][idx].rx_fdq2_qnum     = MONO_RX_FDQ+chan;
717                                                 rxFlow[i][idx].rx_fdq3_qnum     = MONO_RX_FDQ+chan;
718                                         rxFlow[i][idx].rx_psinfo_present = 1;
719                                                 rxFlow[i][idx].rx_sop_offset    = 12+4;   // desc header size for Monolithic packet with PS
721                                                 aifObj.pktDmaConfig.hRxFlowAxC[chan]    = &rxFlow[i][idx];
722                                                 aifObj.pktDmaConfig.hRxFlowCtrl[chan]   = NULL;
723                                                 chan++;
724                                         }
725                                 } else {
726                                         aifObj.pktDmaConfig.hRxFlowAxC[chan]    = NULL;
727                                 }
728                         }
729                 nbchanneltotal = NBCHANNELPERLINK*nblink;
730                 memset(mono_region_test, 0, NBDESCMAX * LTESYMBOLSIZE * NBCHANNELINIT);
731                 printf("Software configuration: %s\n", testObjTab[ntest].name);
733                 // proceed with HW cleanup but may require GEL_AdvancedReset("System Reset") on PreFileLoaded callback for 100% robustness
734                 UTILS_doCleanup(&aifObj,TRIG_TIMER);
736                 for (i=0;i<AIF_MAX_NUM_LINKS;i++)
737                 {
739                                  aifObj.linkConfig[i].linkEnable         = testObjTab[ntest].linkEnable[i];
740                                  if (testObjTab[ntest].linkEnable[i] == 1)
741                                  {
742                                          aifObj.linkConfig[i].numPeAxC                   = NBCHANNELPERLINK;
743                                          aifObj.linkConfig[i].numPdAxC                   = NBCHANNELPERLINK;
744                                  }
745                                  aifObj.linkConfig[i].linkRate           = (Aif2Fl_LinkRate)testObjTab[ntest].linkRate[i];
746 #if CPRI_RELAY_RATE == 20
747                                  aifObj.linkConfig[i].sampleRate                 = AIF_SRATE_30P72MHZ;
748                                  aifObj.linkConfig[i].cpriPackMode       = AIF2_LTE_CPRI_8b8;
749 #elif CPRI_RELAY_RATE ==10
750                                  aifObj.linkConfig[i].sampleRate                 = AIF_SRATE_15P36MHZ;
751                                  aifObj.linkConfig[i].cpriPackMode       = AIF2_LTE_CPRI_4b4;
752 #elif CPRI_RELAY_RATE ==5
753                                  aifObj.linkConfig[i].sampleRate                 = AIF_SRATE_7P68MHZ;
754                                  aifObj.linkConfig[i].cpriPackMode       = AIF2_LTE_CPRI_2b2;
755 #endif
756                                  // avoid superpacket workaround (Advisory 12 for c6670)
757 #if EVM_TYPE == 0 || EVM_TYPE == 1 || EVM_TYPE == 2 || EVM_TYPE == 3
758                                  aifObj.linkConfig[i].cpriPackMode       = AIF2_LTE_CPRI_1b1;
759 #endif
761                                  aifObj.linkConfig[i].outboundDataType   = testObjTab[ntest].outboundDataType[i];
762                                  aifObj.linkConfig[i].outboundDataWidth  = testObjTab[ntest].outboundDataWidth[i];
763                                  aifObj.linkConfig[i].inboundDataType    = testObjTab[ntest].inboundDataType[i];
764                                  aifObj.linkConfig[i].inboundDataWidth   = testObjTab[ntest].inboundDataWidth[i];
765                                  aifObj.linkConfig[i].psMsgEnable        = 0;
766                                  if (intLoopback == 1 ) aifObj.linkConfig[i].comType = AIF2_LOOPBACK;
767                                  else                                   aifObj.linkConfig[i].comType = AIF2_2_AIF2;
768                                  aifObj.linkConfig[i].dioEngine          = testObjTab[ntest].dioEngine[i]; //NA for pkDMA
769                                  for (j=0;j<NBCHANNELPERLINK;j++)
770                                  {
771                                          aifObj.linkConfig[i].lteTddUlDlCfg[j]   = AIF2_LTETDD_ULDL_CFG0;
772                                          aifObj.linkConfig[i].lteTddSsfNcpCfg[j] = AIF2_LTETDD_SSF_NCP_CFG0;
773                                  }
774             }
776                         for (i= 0 ; i<AIF_MAX_NUM_LINKS; i++)
777                         {
778                                 if (aifObj.linkConfig[i].linkEnable)
779                                 {
780                                         activeLink = i;
781                                 }
782                         }
784 #if EVM_TYPE == 5 || EVM_TYPE == 7
785                                 aifObj.linkConfig[activeLink].nodeTx      = 0;
786                                 aifObj.linkConfig[activeLink].nodeRx      = 2;
787 #endif
789                 if (DSP_procId == 1)
790                 {
791                         UTILS_initTimer(TRIG_TIMER);
792                 }
794                 // Interrupt initialization
795                 UTILS_aifIntcSetup();
797                 /* For SCBP-Appleton EVM run, we'll now proceed with SW clock sync */
798 #if EVM_TYPE == 5 // DSP_ProcId = 1
799                 UTILS_boardsSync(SYNC_TIMER,PLL_TIMER); // required board sync process when using CPRI relay setups
800 #endif
802                         // Compute default AIF2 parameters given this user configuration
803                         AIF_calcParameters(&aifObj);
805             // initialization function for qmss and cppi low-level drivers
806             UTILS_initQmss((uint32_t*)mono_region_test, NBDESCMAX, LTESYMBOLSIZE * NBCHANNELINIT, 0, NULL);
808                         // initialization of Pktdma and Qmss resources given this user configuration
809                         AIF_initPktDma(&aifObj);
811                         // Adjust AIF2 timing parameters if calcParameters didn't implement this LTE case or doesn't match the application Tx/Rx delays
812 #if EVM_TYPE == 5 || EVM_TYPE == 7
813 #if CPRI_RELAY_CFG == 2
814                                 aifObj.linkConfig[activeLink].piMin += 20 + 64; // taking into account SCBP FPGA specific extra delay on Rx path when going thru RF
815 #endif
816 #endif
818                         // initialization function for the AIF2 H/W CSL structure (can still be overridden afterwards)
819                         AIF_initHw(&aifObj);
821                         /*
822                          *  LTE Tx packet symbol initialization at once
823                          */
825                         for(chan = 0;chan < nbchanneltotal;chan++)
826                         {
827                                 idx1=0;
828                                 for(idx = 0;idx < (NBSYMBOL*2);idx++)
829                                 {
830                                         symbolPkt[chan][idx] = (Cppi_MonolithicDesc *)QMSS_DESC_PTR(Qmss_queuePop(aifObj.pktDmaConfig.txFqAxC[chan]));
831                                         mono_pkt = symbolPkt[chan][idx];
833                                         //Create Mono packet
834                                         Cppi_setDescType((Cppi_Desc *)mono_pkt,Cppi_DescType_MONOLITHIC);
835                                         Cppi_setPacketType(Cppi_DescType_MONOLITHIC,(Cppi_Desc *)mono_pkt,0);
836                                         Cppi_setDataOffset(Cppi_DescType_MONOLITHIC,(Cppi_Desc *)mono_pkt,16);
838                                         // Always set for longer CP and then adjust length at runtime
839                                         Cppi_setPacketLen(Cppi_DescType_MONOLITHIC,(Cppi_Desc *)mono_pkt,(LTESYMBOLSIZE-16));
841                                         Cppi_setPSFlags (Cppi_DescType_MONOLITHIC,(Cppi_Desc *)mono_pkt,1);
842                                         Cppi_setPSLen(Cppi_DescType_MONOLITHIC,(Cppi_Desc *)mono_pkt,4);
844                                         queueInfo = Qmss_getQueueNumber(aifObj.pktDmaConfig.txFqAxC[chan]);
845                                         descQueue.qMgr = queueInfo.qMgr;
846                                         descQueue.qNum = queueInfo.qNum;
847                                         Cppi_setReturnQueue(Cppi_DescType_MONOLITHIC,(Cppi_Desc *)mono_pkt,descQueue);
849                                         descTag.destTagHi = 0;                                  descTag.destTagLo = 0;
850                                         descTag.srcTagHi  = 0;                                  descTag.srcTagLo  = 0;
851                                         Cppi_setTag(Cppi_DescType_MONOLITHIC,(Cppi_Desc *)mono_pkt,&descTag);
853                                         // Get payload address
854                                         Cppi_getData (Cppi_DescType_MONOLITHIC, (Cppi_Desc*)mono_pkt, (uint8_t**)&payloadPtr, &payloadLen);
856                                          //payload data setup(first and longest symbol)
857                                         for (idx2 = 0; idx2 < (LTESYMBOLSIZE-16)/4; idx2 ++)
858                                         {
859                                                 getcomplex(&payloadPtr[idx2],idx1,chan);
860 //                                                      payloadPtr[idx2] = idx2+1;
861                                                 idx1++;
862                                         }
863                                         memcpy((void*)&txSamples[chan][idx][0],(void*)payloadPtr,LTESYMBOLSIZE-16);
864                                         firstSample[chan][idx].re =  payloadPtr[0].re;
865                                         firstSample[chan][idx].im =  payloadPtr[0].im;
867                                         //Create PS data
868                                         Cppi_getPSData (Cppi_DescType_MONOLITHIC, Cppi_PSLoc_PS_IN_DESC, (Cppi_Desc*)mono_pkt, (uint8_t**)&payloadPtr, &payloadLen);
869                                         *((uint32_t*)payloadPtr) = (uint32_t )(0x00008000 + chan + (idx << 7));//add symbol number into PS field
871                                         Qmss_queuePushDesc((aifObj.pktDmaConfig.txFqAxC[chan]), (uint32_t*)mono_pkt);
872                                 }
873                         }
874                         /*
875                          * Perform block writeback on L1D to make sure all symbol packets are coherent with MSM
876                          */
877                         for(idx = 0;idx < (NBDESCMAX * NBCHANNELMAXPERLINK);idx++) {
878                                 CACHE_wbInvL1d((void *)(mono_region_test+(idx*LTESYMBOLSIZE)), LTESYMBOLSIZE, CACHE_WAIT);
879                         }
880                         gen_twiddle_fft16x16(&twiddleFacts[PAD], FFT_SIZE);
881                         memset(rxCheck,0x00,sizeof(rxCheck));
882                         memset(rxRuntimeFail,0x00,sizeof(rxRuntimeFail));
883                         // start AIF2 HW and PktDMA and then wait for frame synchronization
884 #if _AIF2FL_DUMP == 1
885                         if (DSP_procId == 1)
886                         {
887                            FILE *fout;
888                            fout = fopen("aif2fl_dump.txt","w");
889                            if (fout)
890                            {
891                                    dump_Aif2Fl_Setup(fout,aifObj.hAif2Setup);
892                                    fclose(fout);
893                            }
895                         }
896 #endif
898                         // Disabling this mode, so that, on Cpri relay setup, once AIF2 timers are triggered, they keep running based on the initial pulse. Note there isn't a periodic 10ms pulse generated from EVMTCI6614, just a one shot pulse.
899                         aifObj.hAif2Setup->commonSetup->pAtCommonSetup->AutoResyncMode = AIF2FL_NO_AUTO_RESYNC_MODE;
901 #if CPRI_RELAY_CFG == 2
902                         // Compensating data delay due to Rf chain in the case of RF loopback
903                         aifObj.hAif2Setup->commonSetup->pPdCommonSetup->AxCOffset[0] = 122;
904                         aifObj.hAif2Setup->commonSetup->pPdCommonSetup->AxCOffset[1] = 122;
905 #endif
907                         // Now programming AIF2 registers
908                         AIF_startHw(&aifObj);
910                         // Now triggering AIF2 physical and radio timers
911                         if (DSP_procId == 1)
912                         {
913                                 keepStartupDelay = 0;
914                                 UTILS_triggerFsync(&aifObj);
915                         }
917                         // entering the idle loop and monitoring the end of the test, if any.
918                         monoRxCount = 0;
919                         monoTxCount = 0;
920                         while(1)
921                         {
923                                 asm (" IDLE");
924                                 // wait for one extra symbols to run out of Rx free pkts
925                                 if((totalsymbolcount > (SYMBOL_NUM_DATA_CHECK)) && (NEVER_END_TEST == 0))
926                                 {
927                                         // Wait for ingress symbols from 2 lte slots as we have stopped recycling
928                                         while (Qmss_getQueueEntryCount(aifObj.pktDmaConfig.rxQAxC[0]) != (NBSYMBOL*2)) {
929                                                 asm (" IDLE");
930                                         }
931                                         //AT disable all events and halt timer
932                                         CSR&= 0xFFFFFFFE;
933                                         // Wait for all egress symbols to be recycled 
934                                         while (Qmss_getQueueEntryCount(aifObj.pktDmaConfig.txFqAxC[0]) != (NBSYMBOL*2));                                        
935                                         //Stop AIF2 and proceed to verification
936                                         UTILS_doCleanup(&aifObj,TRIG_TIMER);
937                                         break;
938                                 }
939                         }
941                         // disable interrupts before checking for data
942                         CSR&= 0xFFFFFFFE;
945                         monoRxCount = Qmss_getQueueEntryCount(aifObj.pktDmaConfig.rxQAxC[0]); // get number of received packed on first channel
946                         monoTxCount = Qmss_getQueueEntryCount(aifObj.pktDmaConfig.txFqAxC[0]); // channel 0 only
947                         printf(" Number of monolithic packets received in RX queue channel0: %d\n", monoRxCount);
948                         printf(" Number of monolithic packets in TX free queue for channel0: %d\n", monoTxCount);
949                         monoRxCount = Qmss_getQueueEntryCount(aifObj.pktDmaConfig.rxQAxC[1]);
950                         monoTxCount = Qmss_getQueueEntryCount(aifObj.pktDmaConfig.txFqAxC[1]);
951                         printf(" Number of monolithic packets received in RX queue channel1: %d\n", monoRxCount);
952                         printf(" Number of monolithic packets in TX free queue for channel1: %d\n", monoTxCount);
954                         /* Check received symbol packet data */
955                         for(chan =0; chan < nbchanneltotal; chan++)
956                         {
957                                 idx1 = 0;
958                                 testpass = 1;
959                                 PEAKDEBUG= 0;
960                                 rx_count = Qmss_getQueueEntryCount((aifObj.pktDmaConfig.rxQAxC[chan]));
961                                 if (rx_count == 0) {testpass =0;testcheck++;}
963                                 for (idx = 0; idx < NBSYMBOL*2; idx ++)
964                                 {
965                                         ptrMonoDesc = (Cppi_MonolithicDesc *)QMSS_DESC_PTR(Qmss_queuePop(aifObj.pktDmaConfig.rxQAxC[chan]));
966                                         CACHE_invL1d((void *)ptrMonoDesc, 16, CACHE_WAIT);
967                                         Cppi_getData (Cppi_DescType_MONOLITHIC, (Cppi_Desc*)ptrMonoDesc, (uint8_t**)&payloadPtr, &payloadLen);
968                                         CACHE_invL1d((void *)payloadPtr, payloadLen, CACHE_WAIT);
969                                         memcpy((void*)&rxBuffer[chan][0],(void*)payloadPtr,payloadLen);
970                                         memcpy((void*)&rxSamples[chan][idx][0],(void*)rxBuffer[chan],payloadLen);
971                                         if (payloadLen == (LTESYMBOLSIZE-16)) {
972                                                 DSP_fft16x16(&twiddleFacts[PAD], FFT_SIZE, (int16_t*)&rxBuffer[chan][CYPRENORMAL1_SIZE*4], (int16_t*)&rxBuffer[2][0]);
973                                         }
974                                         if (payloadLen == (LTESYMBOL2SIZE-16)) {
975                                                 DSP_fft16x16(&twiddleFacts[PAD], FFT_SIZE, (int16_t*)&rxBuffer[chan][CYPRENORMAL_SIZE*4], (int16_t*)&rxBuffer[2][0]);
976                                         }
977                                         if(chan == 0)
978                                         {
979                                                 if (!checkSingleTone((int16_t*)&rxBuffer[2][0],FFT_SIZE,PEAK_LOC_1MHZ,chan)) {
980                                                                 testpass = 0;testcheck++;
981                                                         rxCheck[0][idx%NBSYMBOL] = 0;
982 #if CPRI_RELAY_CFG != 2
983                                                         badPacket++;
984 #endif
985                                                 } else {
986                                                         rxCheck[0][idx%NBSYMBOL] = 1;
987 #if CPRI_RELAY_CFG != 2
988                                                         goodPacket++;
989 #endif
990                                                 }
991                                         } else {
992                                                 if (!checkDualTone((int16_t*)&rxBuffer[2][0],FFT_SIZE,PEAK_LOC_1MHZ, PEAK_LOC_2MHZ,chan)) {
993                                                         testpass = 0;testcheck++;
994                                                         rxCheck[1][idx%NBSYMBOL] = 0;
995 #if CPRI_RELAY_CFG != 2
996                                                         badPacket++;
997 #endif
998                                                 } else {
999                                                         rxCheck[1][idx%NBSYMBOL] = 1;
1000 #if CPRI_RELAY_CFG != 2
1001                                                         goodPacket++;
1002 #endif
1003                                                 }
1004                                         }
1005                                         receivedPacket[chan] += 1;
1006                                         Qmss_queuePushDesc(aifObj.pktDmaConfig.rxFqAxC[chan], (uint32_t*) ptrMonoDesc);
1007                                 }
1008                                 printf(" Test a) Monolithic Packet Data Recv: on chan: %d are :%d \n", chan, rx_count);
1009                         }
1011                         if (testpass == 1) {
1012                                 printf(" Test a) Monolithic Packet Data Send/Recv: PASS on channel: %d \n", chan);
1013                         } else {
1014                                 printf(" Test a) Monolithic Packet Data Send/Recv: FAIL\n");
1015                         }
1017                         /* read the descriptor counts of the Monolithic queues. */
1018                         value =0;
1019                         for (i =0 ; i< nbchanneltotal; i++) {
1020                                 value += Qmss_getQueueEntryCount(aifObj.pktDmaConfig.txQAxC[i]);
1021                         }
1022                         if (value != 0) printf(" Test b1) Monolithic Packet Tx Descriptor Counts:%d FAIL\n",value);
1023                         else printf(" Test b1) Monolithic Packet Tx Descriptor Counts:%d PASS\n",value);
1024                         value =0;
1025                         for (i =0 ; i< nbchanneltotal; i++) {
1026                                 value += Qmss_getQueueEntryCount(aifObj.pktDmaConfig.txFqAxC[i]); // channel0
1027                         }
1028                         if (value != nbchanneltotal*NBSYMBOL*2) printf(" Test b2) Monolithic Packet Tx Complete Descriptor Counts:%d FAIL\n",value);
1029                         else printf(" Test b2) Monolithic Packet Tx Complete Descriptor Counts:%d PASS\n",value);
1030                         value =0;
1031                         for (i =0 ; i< nbchanneltotal; i++) {
1032                                 value += Qmss_getQueueEntryCount(aifObj.pktDmaConfig.rxQAxC[i]);
1033                         }
1034                         if (value != 0) printf(" Test b3) Monolithic Packet Rx Descriptor Counts:%d FAIL\n",value);
1035                         else printf(" Test b3) Monolithic Packet Rx Descriptor Counts:%d PASS\n",value);
1036                         value =0;
1037                         for (i =0 ; i< nbchanneltotal; i++) {
1038                                 value += Qmss_getQueueEntryCount(aifObj.pktDmaConfig.rxFqAxC[i]);
1039                         }
1040                         if (value != nbchanneltotal*NBSYMBOL*2) printf(" Test b4) Monolithic Packet Rx Free Descriptor Counts:%d FAIL\n",value);
1041                         else printf(" Test b4) Monolithic Packet Rx Free Descriptor Counts:%d PASS\n",value);
1043                         //UTILS_doCleanup(&aifObj,TRIG_TIMER);
1045                         if (printexceptions == 1)
1046                         {
1047                                 AIF_printException(&aifObj);
1048                         }
1050 #if CPRI_RELAY_CFG != 2
1051                         printf ("received bad packets: %d \n", badPacket);
1052                         printf ("received good packets: %d \n",goodPacket);
1053 #endif
1054                         printf ("total transmitted packets: %d \n",aif2SymbolEgressCount[dbgSymbol]);
1055                         printf ("total received packets: %d \n",aif2SymbolIngressCount[dbgSymbol]);
1056                         printf ("total received packets for channel 0: %d \n",receivedPacket[0]);
1057                         printf ("total received packets for channel 1: %d \n",receivedPacket[1]);
1058                         printf("\nEnding %s test\n", testObjTab[ntest].name);
1059             }
1060     }
1061 #if CPRI_RELAY_RATE == 20
1062     printf("Test: ending AIF2 LTE TDD 20Mhz RF test \n");
1063 #elif CPRI_RELAY_RATE == 10
1064     printf("Test: ending AIF2 LTE TDD 10Mhz RF test \n");
1065 #endif
1067     if (aifObj.aif2EeCount.eeFlag != 0) testcheck++;
1069     if (testcheck == 1) {
1070            testcheck = 0;
1071            printf("All tests have passed\n");
1072     } else {
1073            printf("Some tests have failed\n");
1074     }
1076     return (0);
1079 void getcomplex(Complex16* payload,uint32_t index,uint32_t tx)
1081         float freq;
1082         Complex16 x1;
1083         Complex16 y;
1084         if (tx==0)
1085         {
1086                 // 1 MHz signal
1087                 freq = FREQ;
1088                 x1.re = (int16_t) ( (cos(2*PI*freq*(1/SAMP_FREQ_FLOAT)*index)) * Q_FACTOR );
1089                 x1.im = (int16_t) ( (sin(2*PI*freq*(1/SAMP_FREQ_FLOAT)*index)) * Q_FACTOR );
1090                 y = x1;
1091         } else if (tx==1)
1092         {
1093                 Complex16         x2;
1094                 // 1 MHz signal
1095                 freq = FREQ;
1096                 x1.re = (int16_t) (0.5 * (cos(2*PI*freq*(1/SAMP_FREQ_FLOAT)*index)) * Q_FACTOR );
1097                 x1.im = (int16_t) (0.5 * (sin(2*PI*freq*(1/SAMP_FREQ_FLOAT)*index)) * Q_FACTOR );
1098                 // 2 MHz signal
1099                 freq = 2*FREQ;
1100                 x2.re = (int16_t) (0.5 * (cos(2*PI*freq*(1/SAMP_FREQ_FLOAT)*index)) * Q_FACTOR );
1101                 x2.im = (int16_t) (0.5 * (sin(2*PI*freq*(1/SAMP_FREQ_FLOAT)*index)) * Q_FACTOR );
1102                 // dual tone signal
1103                 y.re = x1.re + x2.re;
1104                 y.im = x1.im + x2.im;
1105         }
1106                 payload->re = y.re;
1107                 payload->im = y.im;
1110 //This function is used to select the symbol we need to push or not regarding the symbol number starting from the frame boundary.
1111 void UTILS_setLteTddDlBitmap(AIF2_LteTddUlDlCfg tddSubFrameBitMap, AIF2_LteTddSsfNcpCfg tddSpecSubFrameBitMap)
1113         int32_t k, j;
1114         uint32_t tddSpecSubFrameBitMap2;
1116         for(k=0;k<144;k++)
1117                 egressSymEnable[k]= 1; //enable all symbols by default
1119         for (k=0;k<10;k++)
1120         {
1121                 // DL SF
1122                 if ((tddSubFrameBitMap & 0x00000003) == 0x00000000) {
1123                         for (j=0;j<(AIF2_LTE_SYMBOL_NUM*2);j++)
1124                         {
1125                                 egressSymEnable[j+AIF2_LTE_SYMBOL_NUM*2*k] = 0;
1126                         }
1127                 }
1128                 // UL SF
1129                 if ((tddSubFrameBitMap & 0x00000003) == 0x00000003) {
1130                         for (j=0;j<(AIF2_LTE_SYMBOL_NUM*2);j++)
1131                         {
1132                                 egressSymEnable[j+AIF2_LTE_SYMBOL_NUM*2*k] = 1;
1133                         }
1134                 }
1135                 // Special SF
1136                 if ((tddSubFrameBitMap & 0x00000003) == 0x00000001) {
1137                         tddSpecSubFrameBitMap2 = tddSpecSubFrameBitMap;
1138                         for (j=0;j<(AIF2_LTE_SYMBOL_NUM*2);j++)
1139                         {
1140                                 if ((tddSpecSubFrameBitMap2 & 0x00000003) == 0x00000003) {
1141                                         egressSymEnable[j+AIF2_LTE_SYMBOL_NUM*2*k] = 1;
1142                                 } else {
1143                                         egressSymEnable[j+AIF2_LTE_SYMBOL_NUM*2*k] = 0;
1144                                 }
1145                                 tddSpecSubFrameBitMap2>>=2;
1146                         }
1147                 }
1148                 tddSubFrameBitMap>>=2;
1149         }
1150         /*for(k=0;k<7;k++)
1151                 egressSymEnable[k]= 1; //enable all symbols by default*/
1155 ////////////