51d5841bc597afff3ee690b612a552c594d21e58
1 /*
2 * Copyright (c) Texas Instruments Incorporated 2020
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 */
33 /*
34 * @file main.c
35 *
36 * @brief
37 * Unit Test code for the CBUFF MSS and DSS
38 * Streams a chunk of data to LVDS interface.
39 * Runs on MSS and DSS.
40 * User needs to manually verify that data is captured on DCA1000 EVM.
41 *
42 */
44 /* *************** Test definition: ***************************************************
45 1. User needs to configure DCA1000GUI to receive data with default settings.
46 2. MSS/DSS comes out of reset and initializes CBUFF driver.
47 3. CBUFF driver is configured for a SW triggered session.
48 4. MSS/DSS activates the CBUFF Session which triggers data transfer from
49 local RAM to CBUFF FIFO.
50 5. Verify that data is captured on DCA1000.
51 6. It is expected to capture data on DCA1000 EVM. If not the test is considered as
52 FAIL.
53 */
55 /* ========================================================================== */
56 /* Include Files */
57 /* ========================================================================== */
58 /* Standard Include Files. */
59 #include <string.h>
60 #include <stdio.h>
62 #include <ti/osal/TaskP.h>
63 #include <ti/osal/DebugP.h>
64 #include <ti/osal/CacheP.h>
66 #include <ti/board/board.h>
67 #include <ti/csl/cslr.h>
68 #include <ti/drv/edma/soc/edma_soc.h>
70 /* Cbuff Driver: */
71 #include <ti/drv/cbuff/cbuff.h>
72 #include <ti/drv/cbuff/src/cbuff_internal.h>
75 /* ========================================================================== */
76 /* Macros & Typedefs */
77 /* ========================================================================== */
79 /**
80 * @brief This is the number of EDMA Channels which have been allocated and can be used
81 * by the CBUFF Driver.
82 */
83 #define TEST_APP_MAX_EDMA_TABLE_ENTRIES 3
85 /**
86 * @brief
87 * The DCA1000EVM FPGA needs a minimum delay of 12ms between Bit clock starts and
88 * actual LVDS Data start to lock the LVDS PLL IP. This is documented in the DCA UG
89 */
90 #define HSI_DCA_MIN_DELAY_MSEC 12U
92 /* ========================================================================== */
93 /* Function Declarations */
94 /* ========================================================================== */
96 /* None. */
98 /* ========================================================================== */
99 /* Structure Declarations */
100 /* ========================================================================== */
102 /* None. */
104 /* ========================================================================== */
105 /* Global Variables */
106 /* ========================================================================== */
107 static uint8_t gAppTskStackMain[4 * 1024] __attribute__((aligned(32)));
109 uint16_t gUserBuffer0[CSL_NEXT_MULTIPLE_OF_POW2(1024,CSL_CACHE_L1D_LINESIZE)] __attribute__ ((aligned(CSL_CACHE_L1D_LINESIZE)));
111 /**
112 * @brief This is the DSS_A instance of EDMA which have been used by the CBUFF Driver.
113 */
114 volatile int8_t gInstanceId = EDMA_DRV_INST_DSS_A;
116 /**
117 * @brief Global Variable which is used to test the failure of EDMA Channel allocation
118 */
119 uint8_t gTestEDMAChannelAllocationFailure = 0U;
121 /**
122 * @brief This is a global variable which tracks the EDMA Channels which have been allocated to the
123 * CBUFF.
124 */
125 uint8_t gCBUFFEDMAChannelResourceCounter = 0;
127 /* ========================================================================== */
128 /* Function Definitions */
129 /* ========================================================================== */
132 /**
133 * @brief Global CBUFF EDMA Channel Resource Table:
134 */
135 static CBUFF_EDMAChannelCfg gCBUFFEDMAChannelResource [TEST_APP_MAX_EDMA_TABLE_ENTRIES] =
136 {
137 /* EDMA Channel Identifier, Shadow Link Channel Identifier */
138 { EDMA_DSS_TPCC_A_EVT_CBUFF_DMA_REQ0, 65 },
139 { EDMA_DSS_TPCC_A_EVT_FREE_0, 66 },
140 { EDMA_DSS_TPCC_A_EVT_FREE_1, 67 }
141 };
144 /**
145 * @b Description
146 * @n
147 * Performs Board Initialization
148 *
149 * @retval
150 * Success - true
151 * @retval
152 * Error - false
153 */
154 static bool MmwDemo_BoardInit(void)
155 {
156 Board_initCfg boardCfg;
157 Board_STATUS status;
159 boardCfg = BOARD_INIT_PINMUX_CONFIG |
160 BOARD_INIT_MODULE_CLOCK |
161 BOARD_INIT_UNLOCK_MMR;
163 status = Board_init(boardCfg);
165 if (status != BOARD_SOK)
166 {
167 return false;
168 }
169 else
170 {
171 return true;
172 }
173 }
175 /**
176 * @b Description
177 * @n
178 * Registered callback function with the EDMA to be invoked on an error
179 *
180 * @retval
181 * Not Applicable.
182 */
183 void Test_edmaErrorCallbackFxn(EDMA_Handle handle, EDMA_errorInfo_t *errorInfo)
184 {
185 DebugP_assert(0);
186 }
188 /**
189 * @b Description
190 * @n
191 * Registered callback function with the EDMA to be invoked on an error
192 *
193 * @retval
194 * Not Applicable.
195 */
196 void Test_edmaTransferControllerErrorCallbackFxn
197 (
198 EDMA_Handle handle,
199 EDMA_transferControllerErrorInfo_t* errorInfo
200 )
201 {
202 DebugP_assert(0);
203 }
205 /**
206 * @b Description
207 * @n
208 * This is the registered allocation function which is hooked up with the
209 * CBUFF driver to allocate EDMA Channels
210 *
211 * @retval
212 * Success - 0
213 * @retval
214 * Error - <0
215 */
216 int32_t Test_EDMAAllocateCBUFFChannel (CBUFF_EDMAInfo* ptrEDMAInfo, CBUFF_EDMAChannelCfg* ptrEDMAChannelCfg)
217 {
218 /* Are we testing the EDMA allocation failure mode? */
219 if (gTestEDMAChannelAllocationFailure == 0U)
220 {
221 /* NO: Have we allocated all the EDMA channels? */
222 if (gCBUFFEDMAChannelResourceCounter >= TEST_APP_MAX_EDMA_TABLE_ENTRIES)
223 {
224 /* Error: Exceeded the allocated table. Failure */
225 DebugP_assert (0);
226 return -1;
227 }
229 /* Special case handling: First EDMA channel which is being allocated */
230 if (ptrEDMAInfo->isFirstEDMAChannel == true)
231 {
232 switch (ptrEDMAInfo->dmaNum)
233 {
234 case 0:
235 {
236 ptrEDMAChannelCfg->chainChannelsId = EDMA_DSS_TPCC_A_EVT_CBUFF_DMA_REQ0;
237 ptrEDMAChannelCfg->shadowLinkChannelsId = 65;
238 break;
239 }
240 case 1:
241 {
242 ptrEDMAChannelCfg->chainChannelsId = EDMA_DSS_TPCC_A_EVT_CBUFF_DMA_REQ1;
243 ptrEDMAChannelCfg->shadowLinkChannelsId = 100;
244 break;
245 }
246 case 2:
247 {
248 ptrEDMAChannelCfg->chainChannelsId = EDMA_DSS_TPCC_A_EVT_CBUFF_DMA_REQ2;
249 ptrEDMAChannelCfg->shadowLinkChannelsId = 101;
250 break;
251 }
252 case 3:
253 {
254 ptrEDMAChannelCfg->chainChannelsId = EDMA_DSS_TPCC_A_EVT_CBUFF_DMA_REQ3;
255 ptrEDMAChannelCfg->shadowLinkChannelsId = 102;
256 break;
257 }
258 case 4:
259 {
260 ptrEDMAChannelCfg->chainChannelsId = EDMA_DSS_TPCC_A_EVT_CBUFF_DMA_REQ4;
261 ptrEDMAChannelCfg->shadowLinkChannelsId = 103;
262 break;
263 }
264 case 5:
265 {
266 ptrEDMAChannelCfg->chainChannelsId = EDMA_DSS_TPCC_A_EVT_CBUFF_DMA_REQ5;
267 ptrEDMAChannelCfg->shadowLinkChannelsId = 104;
268 break;
269 }
270 case 6:
271 {
272 ptrEDMAChannelCfg->chainChannelsId = EDMA_DSS_TPCC_A_EVT_CBUFF_DMA_REQ6;
273 ptrEDMAChannelCfg->shadowLinkChannelsId = 105;
274 break;
275 }
276 default:
277 {
278 DebugP_assert (0);
279 break;
280 }
281 }
282 }
283 else
284 {
285 /* Copy over the allocated EDMA configuration. */
286 memcpy ((void *)ptrEDMAChannelCfg, (void*)&gCBUFFEDMAChannelResource[gCBUFFEDMAChannelResourceCounter],
287 sizeof(CBUFF_EDMAChannelCfg));
288 }
290 /* Increment the number of EDMA Channels which have been allocated */
291 gCBUFFEDMAChannelResourceCounter++;
292 return 0;
293 }
294 else
295 {
296 /* YES: Return a failure to indicate that the channel allocation failed. We use this
297 * to ensure that the CBUFF driver correctly reports errors. */
298 return -1;
299 }
300 }
302 /**
303 * @b Description
304 * @n
305 * This is the registered free function which is hooked up with the
306 * CBUFF driver to free the allocated EDMA Channels
307 *
308 * @retval
309 * Not applicable
310 */
311 void Test_EDMAFreeCBUFFChannel(CBUFF_EDMAChannelCfg* ptrEDMACfg)
312 {
313 /* Debug Message: */
314 gCBUFFEDMAChannelResourceCounter--;
315 return;
316 }
318 /**
319 * @b Description
320 * @n
321 * The function is used to test the invalid data size
322 *
323 * @param[in] socHandle
324 * SOC Driver Handle
325 * @param[in] edmaHandle
326 * EDMA Driver Handle
327 *
328 * @retval
329 * Success - 0
330 * @retval
331 * Error - <0
332 */
333 int32_t Test_Cbuff
334 (
335 EDMA_Handle edmaHandle
336 )
337 {
338 CBUFF_SessionCfg sessionCfg;
339 CBUFF_Handle cbuffHandle;
340 CBUFF_InitCfg initCfg;
341 int32_t errCode;
342 CBUFF_SessionHandle sessionHandle;
343 uint32_t i = 0;
345 /* Debug Message: */
346 DebugP_log0 ("---------------------------------------------------\n");
347 DebugP_log0 ("Debug: Testing CBUFF interface \n");
348 DebugP_log0 ("---------------------------------------------------\n");
350 /* Initialize the configuration: */
351 memset ((void*)&initCfg, 0, sizeof(CBUFF_InitCfg));
353 /* Populate the configuration: */
354 initCfg.outputDataFmt = CBUFF_OutputDataFmt_16bit;
355 initCfg.enableECC = 0U;
356 initCfg.crcEnable = 0U;
357 initCfg.enableDebugMode = false;
358 initCfg.maxSessions = 2U;
359 initCfg.interface = CBUFF_Interface_LVDS;
360 initCfg.lvdsCfg.crcEnable = 0U;
361 initCfg.lvdsCfg.msbFirst = 1U;
362 initCfg.lvdsCfg.ddrClockMode = 1U;
363 initCfg.lvdsCfg.ddrClockModeMux= 1U;
365 /* Setup the lanes */
366 initCfg.lvdsCfg.lvdsLaneEnable = 0xFU;
368 /* Initialize the CBUFF Driver: */
369 cbuffHandle = CBUFF_init (&initCfg, &errCode);
370 if (cbuffHandle == NULL)
371 {
372 DebugP_log1 ("Error: CBUFF Driver initialization failed [Error code %d]\n", errCode);
373 return -1;
374 }
376 /* Configure LVDS PAD Control registers. */
377 /* Probably this functionality has to be from Board library. */
378 HW_WR_REG32(CSL_MSS_TOPRCM_U_BASE + CSL_MSS_TOPRCM_LVDS_PAD_CTRL0 , 0x0);
380 HW_WR_REG32(CSL_MSS_TOPRCM_U_BASE + CSL_MSS_TOPRCM_LVDS_PAD_CTRL1 , 0x02000000);
382 /*The delay below is needed only if the DCA1000EVM is being used to capture the data traces.
383 This is needed because the DCA1000EVM FPGA needs the delay to lock to the
384 bit clock before they can start capturing the data correctly. */
385 TaskP_sleepInMsecs(HSI_DCA_MIN_DELAY_MSEC);
387 /* Initialize the configuration */
388 memset ((void*)&sessionCfg, 0, sizeof(CBUFF_SessionCfg));
390 /* Initialize the configuration: */
391 for(i = 0; i < (sizeof(gUserBuffer0)/2); i++)
392 {
393 gUserBuffer0[i] = i;
394 }
395 CacheP_wbInv (gUserBuffer0, sizeof(gUserBuffer0));
397 /* Populate the configuration: */
398 sessionCfg.executionMode = CBUFF_SessionExecuteMode_SW;
399 sessionCfg.edmaHandle = edmaHandle;
400 sessionCfg.allocateEDMAChannelFxn = Test_EDMAAllocateCBUFFChannel;
401 sessionCfg.freeEDMAChannelFxn = Test_EDMAFreeCBUFFChannel;
402 sessionCfg.dataType = CBUFF_DataType_COMPLEX;
403 sessionCfg.u.swCfg.userBufferInfo[0].size = sizeof(gUserBuffer0);
404 sessionCfg.u.swCfg.userBufferInfo[0].address = (uint32_t)&gUserBuffer0[0];
407 /* Create the SW CBUFF Session: */
408 sessionHandle = CBUFF_open (cbuffHandle, &sessionCfg, &errCode);
409 if (sessionHandle == NULL)
410 {
411 DebugP_log1 ("Error: Unable to create the session [Error code %d]\n", errCode);
412 return -1;
413 }
415 /* Debug Message: Display the EDMA Channel Usage for the test. */
416 DebugP_log1 ("Debug: EDMA Channel Usage = %d\n", gCBUFFEDMAChannelResourceCounter);
418 /* Activate the session: */
419 if (CBUFF_activateSession (sessionHandle, &errCode) < 0)
420 {
421 DebugP_log1 ("Error: Unable to activate the session [Error code %d]\n", errCode);
422 return -1;
423 }
425 /* Deactivate the session: */
426 if (CBUFF_deactivateSession (sessionHandle, &errCode) < 0)
427 {
428 DebugP_log1 ("Error: Unable to deactivate the session [Error code %d]\n", errCode);
429 return -1;
430 }
432 /* Delete the session: */
433 if (CBUFF_close (sessionHandle, &errCode) < 0)
434 {
435 DebugP_log1 ("Error: Unable to delete the session [Error code %d]\n", errCode);
436 return -1;
437 }
439 /* Sanity Check: Ensure that all the EDMA resources have been cleaned up */
440 if (gCBUFFEDMAChannelResourceCounter != 0)
441 {
442 DebugP_log0 ("Error: EDMA Channel Memory leak detected\n");
443 return -1;
444 }
446 return 0;
447 }
449 void Test_initTask(void* arg0, void* arg1)
450 {
451 EDMA_Handle edmaHandle;
452 int32_t errCode;
454 EDMA_instanceInfo_t instanceInfo;
456 EDMA3CCInitParams initParam;
457 EDMA_errorConfig_t errorConfig;
459 char instName[25];
460 EDMA_getInstanceName(gInstanceId, &instName[0], sizeof(instName));
461 DebugP_log2("EDMA instance #%d: %s\n", gInstanceId, (uintptr_t)instName);
463 EDMA3CCInitParams_init(&initParam);
464 initParam.initParamSet = TRUE;
466 /* Initialize the edma instance. */
467 errCode = EDMA_init(gInstanceId, &initParam);
469 if (errCode == EDMA_NO_ERROR)
470 {
471 /* Open the first edma Instance */
472 edmaHandle = EDMA_open(gInstanceId, &errCode, &instanceInfo);
473 if (edmaHandle == NULL)
474 {
475 DebugP_log1("Error: Unable to open the edma Instance, erorCode = %d\n", errCode);
476 }
477 }
479 /* Setup the EDMA Error Monitoring: */
480 errorConfig.isConfigAllEventQueues = true;
481 errorConfig.isConfigAllTransferControllers = true;
482 errorConfig.isEventQueueThresholdingEnabled = true;
483 errorConfig.eventQueueThreshold = EDMA_EVENT_QUEUE_THRESHOLD_MAX;
484 errorConfig.isEnableAllTransferControllerErrors = true;
485 errorConfig.callbackFxn = Test_edmaErrorCallbackFxn;
486 errorConfig.transferControllerCallbackFxn = Test_edmaTransferControllerErrorCallbackFxn;
487 errCode = EDMA_configErrorMonitoring(edmaHandle, &errorConfig);
488 if (errCode != EDMA_NO_ERROR)
489 {
490 DebugP_log1("Debug: EDMA_configErrorMonitoring() failed with errorCode = %d\n", errCode);
491 return;
492 }
494 /* Test */
495 if (Test_Cbuff (edmaHandle) < 0)
496 return;
498 /* Stop OS */
499 OS_stop();
501 return;
502 }
504 int main (void)
505 {
506 TaskP_Params taskParams;
508 MmwDemo_BoardInit();
510 /* Configure HSI interface Clock */
511 HW_WR_REG32(CSL_MSS_TOPRCM_U_BASE + CSL_MSS_TOPRCM_HSI_CLK_SRC_SEL, 0x444); //Div by 2
512 HW_WR_REG32(CSL_MSS_TOPRCM_U_BASE + CSL_MSS_TOPRCM_HSI_DIV_VAL, 0x111);
513 HW_WR_REG32(CSL_MSS_TOPRCM_U_BASE + CSL_MSS_TOPRCM_HSI_CLK_GATE , 0x0);
515 /* Select MDO source as CBUFF. By default it is set to AURORA. */
516 /* Probably this functionality has to be from Board library. */
517 HW_WR_REG32(CSL_TOP_CTRL_U_BASE + 4, 0x10);
519 /* Debug Message: */
520 DebugP_log0 ("***********************************************\n");
521 DebugP_log0 ("************** CBUFF Unit Tests ***************\n");
522 DebugP_log0 ("***********************************************\n");
524 /* Initialize the Task Parameters. */
525 TaskP_Params_init(&taskParams);
526 taskParams.stack = gAppTskStackMain;
527 taskParams.stacksize = sizeof(gAppTskStackMain);
528 TaskP_create(Test_initTask, &taskParams);
530 /* Start OS */
531 OS_start();
532 return 0;
533 }