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()
460 {
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;
596 }
599 int main(void)
600 {
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);
1077 }
1079 void getcomplex(Complex16* payload,uint32_t index,uint32_t tx)
1080 {
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;
1108 }
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)
1112 {
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*/
1153 }
1155 ////////////