addressed review comments.
[processor-sdk/pdk.git] / packages / ti / drv / cbuff / example / cbuff_manual_testapp / main.c
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)
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     }
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)
185     DebugP_assert(0);
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
198     EDMA_Handle                         handle,
199     EDMA_transferControllerErrorInfo_t* errorInfo
202     DebugP_assert(0);
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)
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     }
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)
313     /* Debug Message: */
314     gCBUFFEDMAChannelResourceCounter--;
315     return;
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
335     EDMA_Handle     edmaHandle
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;
449 void Test_initTask(void* arg0, void* arg1)
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;
504 int main (void)
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;