PRSDK-3515 Add Board_init function to enable module clock
[keystone-rtos/mcbsp-lld.git] / example / c6657 / MCBSPDigLpbk / mcbspMasterDigLpbk.c
1 /*
2  * mcbspMasterDigLpbk.c
3  *
4  * This file contains the test / demo code to demonstrate the McBSP driver
5  * master functionality using Digital Loopback setup. The file configures 
6  * the EVM in master mode.
7  *
8  * Copyright (C) 2012 - 2018 Texas Instruments Incorporated - http://www.ti.com/
9  *
10  *
11  *  Redistribution and use in source and binary forms, with or without
12  *  modification, are permitted provided that the following conditions
13  *  are met:
14  *
15  *    Redistributions of source code must retain the above copyright
16  *    notice, this list of conditions and the following disclaimer.
17  *
18  *    Redistributions in binary form must reproduce the above copyright
19  *    notice, this list of conditions and the following disclaimer in the
20  *    documentation and/or other materials provided with the
21  *    distribution.
22  *
23  *    Neither the name of Texas Instruments Incorporated nor the names of
24  *    its contributors may be used to endorse or promote products derived
25  *    from this software without specific prior written permission.
26  *
27  *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
28  *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
29  *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
30  *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
31  *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
32  *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
33  *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
34  *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
35  *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
36  *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
37  *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
38  *
39 */
41 /* ========================================================================== */
42 /*                            INCLUDE FILES                                   */
43 /* ========================================================================== */
45 #include <ti/sysbios/BIOS.h>
46 #include <xdc/std.h>
47 #include <ti/sysbios/knl/Task.h>
48 #include <string.h>
49 #include <ti/sysbios/knl/Queue.h>
50 #include <xdc/runtime/System.h>
52 #include <xdc/cfg/global.h>
53 #include <board.h>
55 /* Include EDMA3 Driver */
56 #include <ti/sdo/edma3/drv/edma3_drv.h>
58 /* CSL Chip Functional Layer */
59 //#include <ti/csl/csl_chip.h>
61 /* CSL Cache Functional Layer */
62 //#include <ti/csl/csl_cacheAux.h>
64 /* CSL CPINTC Include Files. */
65 //#include<ti/csl/csl_cpIntc.h>
67 /* MCBSP Driver Include File. */
68 #include <ti/drv/mcbsp/mcbsp_drv.h>
69 #include <ti/drv/mcbsp/mcbsp_osal.h>
71 /* PlatformLib Include File */
72 //#include <ti/platform/platform.h>
75 extern EDMA3_DRV_GblConfigParams sampleEdma3GblCfgParams[];
76 extern EDMA3_RM_InstanceInitConfig sampleInstInitConfig[2][8];
77 /* ========================================================================== */
78 /*                        EXTERNAL FUNCTIONS                                  */
79 /* ========================================================================== */
81 extern EDMA3_DRV_Handle edma3init(unsigned int edma3Id, EDMA3_DRV_Result *);
83 extern void McbspDevice_init(void);
85 extern int32_t Osal_dataBufferInitMemory(uint32_t dataBufferSize);
87 extern void McbspXmtInterrupt_init(void *mcbspTxChan);
88 extern void McbspRcvInterrupt_init(void *mcbspRxChan);
90 extern Board_STATUS Board_init(Board_initCfg);
92 /* FPGA Configuration Misc-1 Register offset */
93 #define MCBSP_FPGA_MISC_REG_OFFSET (0x0C)
95 /* ========================================================================== */
96 /*                           MACRO DEFINTIONS                                 */
97 /* ========================================================================== */
99 #define NUM_BUFS                     2          /* Max of buffers used in each direction */
100 #define FRAMESIZE                   40          /* e.g 5 ms 8 KHz samples         */
101 #define NUM_OF_ENABLED_CHANNELS      8          /* Number of slots to be used     */
102 #define NUM_OF_MAX_CHANNELS            128                      /* Maximum number of time slots available based on clock settings   */
103 #define BUFSIZE                   (NUM_OF_ENABLED_CHANNELS * FRAMESIZE)        /* Total buffer size per frame */
105 /* Defines the core number responsible for system initialization. */
106 #define CORE_SYS_INIT         0
107 /* Number of iterations to execute test: Only applicable to INTERNAL CLOCK Loopback test */
108 #define NUM_OF_ITERATIONS 10
110 /* Number of MCBSP Frame structures used for submit channel */
111 #define NUM_OF_MCBSP_FRAMES 2
113 /* Number of buffers initially submitted to Mcbsp lld: Only applicable to
114    External clock test ; Note: This should be set to 2*/
115 #define INIT_SUBMIT_Q_CNT 2
117 /*============================================================================*/
118 /*                            GLOBAL VARIABLES                                */
119 /*============================================================================*/
121 /* Shared Memory Variable to ensure synchronizing MCBSP initialization
122  * with all the other cores. */
123 /* Created an array to pad the cache line with MCBSP_CACHE_LENGTH size */
124 #pragma DATA_ALIGN   (isMCBSPInitialized, MCBSP_MAX_CACHE_ALIGN)
125 #pragma DATA_SECTION (isMCBSPInitialized, ".mcbspSharedMem");
126 volatile Uint32 isMCBSPInitialized[(MCBSP_CACHE_LENGTH / sizeof(Uint32))] = { 0 };
128 /* Handle to the EDMA driver instance */
129 #pragma DATA_ALIGN   (hEdma, MCBSP_MAX_CACHE_ALIGN)
130 EDMA3_DRV_Handle hEdma[(MCBSP_CACHE_LENGTH / sizeof(EDMA3_DRV_Handle))] = { NULL };
132 /* Handle to MCBSP driver instance */
133 typedef void* Mcbsp_DevHandle;
134 Mcbsp_DevHandle  hMcbspDev;
136 /* Handle to MCBSP driver channel instance */
137 typedef void* Mcbsp_ChanHandle;
138 Mcbsp_ChanHandle  hMcbspTxChan;
139 Mcbsp_ChanHandle  hMcbspRxChan;
141 /* Core Number Identifier */
142 UInt32 coreNum = 0xFFFF;
144 /* Array to hold the pointer to the allocated buffers     */
145 void* bufRx[NUM_BUFS];
146 void* bufTx[NUM_BUFS];
148 #ifdef MCBSP_LOOP_PING_PONG
149 /* Ping pong buffers used to submit to Mcbsp lld, which will be used in a loop */
150 void* bufRxPingPong[INIT_SUBMIT_Q_CNT];
151 void* bufTxPingPong[INIT_SUBMIT_Q_CNT];
152 #endif
153 /* Global Error call back function prototype */
154 void mcbsp_GblErrCallback(uint32_t chanHandle,uint32_t spcr_read,uint32_t Arg3);
156 /* Variables to indicate status of EDMA TX and RX requests */
157 volatile uint32_t edmaTxDone = 0;
158 volatile uint32_t edmaRxDone = 0;
159 /* Global variables to track number of buffers submitted, number of iterations, error counts etc */
160 int rxSubmitCount=0, txSubmitCount=0;
161 uint32_t num_iterations=0;
162 uint32_t num_rx_Call_backs=0, num_tx_Call_backs=0, dummy_call_backs=0;
163 uint32_t rxunderflowcnt=0, txunderflowcnt=0;
164 uint32_t errBuffCount=0;
165 /* Debug variables */
166 volatile int debugVar=1;  /* This can be used to maintain a while loop, If set to 0 will exit loop */
167 volatile int debugCommand=1;  /* This can be used to set to value below to send command to restart channel  */
169 #define DEBUG_COMMAND_RESTART_CHANNELS 1
170 /**
171  * \brief    Mcbsp Sample rate generator default parameters.
172  *
173  */
174 Mcbsp_srgConfig mcbspSrgCfg =
176     FALSE,                     /* No gsync to be used as input is not CLKS    */
177     Mcbsp_ClkSPol_RISING_EDGE, /* Dont care as input clock is not clks        */
178     Mcbsp_SrgClk_CLKCPU,       /* McBSP internal clock to be used             */
179     //166666667,                 /* Mcbsp internal clock frequency(PLL-SYSCLK6) */
180     333333333, //sys_oscclk or cpu_clk/3
181     0                          /* frame sync pulse width (val+1) is used      */
182 };
184 /**
185  * \brief    Mcbsp device creation default parameters.
186  *
187  */
188 const Mcbsp_Params Mcbsp_PARAMS =
190     Mcbsp_DevMode_McBSP,       /* Use the device as MCBSP                     */
191     Mcbsp_OpMode_DMAINTERRUPT, /* Use DMA mode of operation                   */
192     TRUE,                      /* cache coherency taken care of by driver     */
193     Mcbsp_EmuMode_FREE,        /* Emulation mode free is to be enabled        */
194 #ifdef    MCBSP_EXTERNAL_CLOCK
195     Mcbsp_Loopback_DISABLE,    /* Loop back mode disabled                     */
196 #else
197     Mcbsp_Loopback_ENABLE,     /* Loop back mode enabled                      */
198 #endif
199     &mcbspSrgCfg,              /* sample rate generator configuration         */
200     NULL,                      /* TX pending buffer queue from application    */
201     NULL,                      /* TX floating buffer queue in DMA             */
202     NULL,                      /* RX pending buffer queue from application    */
203     NULL                       /* RX floating buffer queue in DMA             */
204 };
206 #pragma DATA_ALIGN(loopTxJob, MCBSP_MAX_CACHE_ALIGN)
207 static Int32 loopTxJob[16] = {
208     /* Filling with Mu law silence pattern : Can be any user defined pattern */
209     0x7f7f7f7f, 0x7f7f7f7f, 0x7f7f7f7f, 0x7f7f7f7f, 0x7f7f7f7f, 0x7f7f7f7f, 0x7f7f7f7f, 0x7f7f7f7f,
210     0x7f7f7f7f, 0x7f7f7f7f, 0x7f7f7f7f, 0x7f7f7f7f, 0x7f7f7f7f, 0x7f7f7f7f, 0x7f7f7f7f, 0x7f7f7f7f
211 };
212 #pragma DATA_ALIGN(loopRxJob, MCBSP_MAX_CACHE_ALIGN)
213 static Int32 loopRxJob[16] = {
214     0, 0, 0, 0, 0, 0, 0, 0,
215     0, 0, 0, 0, 0, 0, 0, 0
216 };
218 /**< settings to configure the TX or RX hardware sections                 */
219 Mcbsp_DataConfig mcbspChanConfigTx =
221     Mcbsp_Phase_SINGLE,
222     Mcbsp_WordLength_8,
223     Mcbsp_WordLength_8,    /* Dont care for single phase*/
224     NUM_OF_MAX_CHANNELS,
225     NUM_OF_MAX_CHANNELS,      // Only used with dual phase
226     Mcbsp_FrmSync_DETECT,
227 #ifdef MCBSP_EXTERNAL_CLOCK
228     Mcbsp_DataDelay_0_BIT,
229 #else
230     Mcbsp_DataDelay_1_BIT,
231 #endif
232     Mcbsp_Compand_OFF_MSB_FIRST,
233     Mcbsp_BitReversal_DISABLE,
234     Mcbsp_IntMode_ON_SYNCERR,
235     Mcbsp_RxJust_RZF,  /* Dont care for TX         */
236     Mcbsp_DxEna_OFF
237 };
239 /**< settings to configure the TX or RX hardware sections                 */
240 Mcbsp_DataConfig mcbspChanConfigRx =
242     Mcbsp_Phase_SINGLE,
243     Mcbsp_WordLength_8,
244     Mcbsp_WordLength_8,    /* Dont care for single phase*/
245     NUM_OF_MAX_CHANNELS,
246     NUM_OF_MAX_CHANNELS,      // Only used with dual phase
247     Mcbsp_FrmSync_DETECT,
248 #ifdef MCBSP_EXTERNAL_CLOCK
249     Mcbsp_DataDelay_0_BIT,
250 #else
251     Mcbsp_DataDelay_1_BIT,
252 #endif
253     Mcbsp_Compand_OFF_MSB_FIRST,
254     Mcbsp_BitReversal_DISABLE,
255     Mcbsp_IntMode_ON_SYNCERR,
256     Mcbsp_RxJust_RZF,  /* Dont care for TX         */
257     Mcbsp_DxEna_OFF
258 };
259 /**< clock setup for the TX section                     */
260 Mcbsp_ClkSetup mcbspClkConfigTx =
262 #ifdef MCBSP_EXTERNAL_CLOCK
263     Mcbsp_FsClkMode_EXTERNAL,
264     8000,                   /* 8KHz                   */
265     Mcbsp_TxRxClkMode_EXTERNAL,
266 #else
267     Mcbsp_FsClkMode_INTERNAL,
268     8000,                   /* 8KHz                   */
269     Mcbsp_TxRxClkMode_INTERNAL,
270 #endif
271     Mcbsp_FsPol_ACTIVE_HIGH,
272     Mcbsp_ClkPol_RISING_EDGE
273 };
275 /**< clock setup for the RX section                     */
276 Mcbsp_ClkSetup mcbspClkConfigRx =
278 #ifdef MCBSP_EXTERNAL_CLOCK
279     Mcbsp_FsClkMode_EXTERNAL,
280     8000,                   /* 8KHz                   */
281     Mcbsp_TxRxClkMode_EXTERNAL,
282 #else
283     Mcbsp_FsClkMode_INTERNAL,
284     8000,                   /* 8KHz                   */
285     Mcbsp_TxRxClkMode_INTERNAL,
286 #endif
287     Mcbsp_FsPol_ACTIVE_HIGH,
288     Mcbsp_ClkPol_FALLING_EDGE
289 };
291 /**< Multi channel setup                                                      */
292 Mcbsp_McrSetup mcbspMultiChanCtrl =
294     Mcbsp_McmMode_ALL_CHAN_DISABLED_UNMASKED,
295     Mcbsp_PartitionMode_CHAN_0_15,
296     Mcbsp_PartitionMode_CHAN_16_31,
297     Mcbsp_PartitionMode_2
298 };
301 Mcbsp_ChanParams mcbspChanparamTx =
303     Mcbsp_WordLength_8,  /* wordlength configured    */
304     &loopTxJob[0],          /* loop job buffer internal */
305     8,                    /* user loopjob length      */
306     mcbsp_GblErrCallback, /* global error callback    */
307     NULL,                 /* edma Handle              */
308     1,                    /* EDMA event queue         */
309     8,                    /* hwi number               */
310     Mcbsp_BufferFormat_MULTISLOT_NON_INTERLEAVED,
311     TRUE,                 /* FIFO mode enabled        */
312     &mcbspChanConfigTx,   /* channel configuration    */
313     &mcbspClkConfigTx,    /* clock configuration      */
314     &mcbspMultiChanCtrl,  /* multi channel control    */
315     0x7531,  /* Enabled timeslots: 0, 4, 5, 8, 10, 12, 13, 14 */
316     0x00,
317     0x00,
318     0x00,
319     NUM_OF_ENABLED_CHANNELS    /* Total number of channels enabled*/
320 };
322 Mcbsp_ChanParams mcbspChanparamRx =
324     Mcbsp_WordLength_8,  /* wordlength configured    */
325     &loopRxJob[0],          /* loop job buffer internal */
326     8,                    /* user loopjob length      */
327     mcbsp_GblErrCallback, /* global error callback    */
328     NULL,                 /* edma Handle              */
329     1,                    /* EDMA event queue         */
330     8,                    /* hwi number               */
331     Mcbsp_BufferFormat_MULTISLOT_NON_INTERLEAVED,
332     TRUE,                 /* FIFO mode enabled        */
333     &mcbspChanConfigRx,   /* channel configuration    */
334     &mcbspClkConfigRx,    /* clock configuration      */
335     &mcbspMultiChanCtrl,  /* multi channel control    */
336     0x7531,  /* Enabled timeslots: 0, 4, 5, 8, 10, 12, 13, 14 */
337     0x00,
338     0x00,
339     0x00,
340     NUM_OF_ENABLED_CHANNELS    /* Total number of channels enabled*/
341 };
344 /* ========================================================================== */
345 /*                           FUNCTION DEFINITIONS                             */
346 /* ========================================================================== */
348 /*
349  *   This is the application's callback function. The driver will
350  *   call this function whenever an EDMA I/O operation is over.
351  *
352  */
353 void mcbspAppCallback(void* arg, Mcbsp_IOBuf *ioBuf)
355     int32_t mode;
356     int32_t *pmode = (int32_t *)arg;
358     mode = *pmode;
359     if (mode == MCBSP_MODE_OUTPUT)
360     {
361         if(ioBuf) {
362             num_tx_Call_backs++;
363             edmaTxDone = 1;
364         }else
365             txunderflowcnt++;
366     }
367     else if (mode == MCBSP_MODE_INPUT)
368     {
369         if(ioBuf) {
370             num_rx_Call_backs++;
371             edmaRxDone = 1;
372         }else
373             rxunderflowcnt++;
374     }else
375         dummy_call_backs++;
376     return;
379 /*
380  *   This is the application's Global error callback function 
381  */
382 void mcbsp_GblErrCallback(uint32_t chanHandle,uint32_t spcr_read,uint32_t Arg3)
384     System_printf ("Debug(Core %d): ERROR callback called SPCR: %x", coreNum, spcr_read);
387 /*
388  * \brief   This function demostrates the use of Mcbsp using digital loopback
389  *          communication setup.
390  *
391  * \param   None
392  *
393  * \return  None
394  */
395 void mcbspDigLpbkApp(UArg arg0, UArg arg1)
397     /**< Mcbsp device params                                                  */
398     Mcbsp_Params  mcbspParams;
400     /**< Queue to hold the pending packets received from the application      */
401     Queue_Struct  txQueuePendingList, rxQueuePendingList;
402     /**< Queue to manage floating packets in DMA                              */
403     Queue_Struct  txQueueFloatingList, rxQueueFloatingList;
405     uint32_t count   = 0, tempCount = 0;
406     int32_t  status  = 0, retval = 0;
407     int32_t  txChanMode = MCBSP_MODE_OUTPUT;
408     int32_t  rxChanMode = MCBSP_MODE_INPUT;
409     uint32_t mcbspTxDone = 0, mcbspRxDone = 0;
410     Mcbsp_IOBuf txFrame[NUM_OF_MCBSP_FRAMES], rxFrame[NUM_OF_MCBSP_FRAMES];
411     int txFrameIndex=0, rxFrameIndex=0;
412     int init_count=0;
413 #ifdef MCBSP_LOOP_PING_PONG
414     int pingPongIndex=0;
415 #endif
417     /* Initialize the OSAL */
418     if (Osal_dataBufferInitMemory(BUFSIZE) < 0)
419     {
420         System_printf ("Debug(Core %d): Error: Unable to initialize the OSAL. \n", coreNum);
421         return;
422     }
424     /* update EDMA3 handle to channel parameters */
425     mcbspChanparamTx.edmaHandle = hEdma[0];
426     mcbspChanparamRx.edmaHandle = hEdma[0];
428     /* create the pending and floating queue for the TX channel           */
429     Queue_construct(&txQueuePendingList, NULL);
430     Queue_construct(&txQueueFloatingList, NULL);
432     /* create the pending and floating queue for the RX channel           */
433     Queue_construct(&rxQueuePendingList, NULL);
434     Queue_construct(&rxQueueFloatingList, NULL);
437     mcbspParams                 = Mcbsp_PARAMS;
438     mcbspParams.txQPendingList  = &txQueuePendingList;
439     mcbspParams.txQFloatingList = &txQueueFloatingList;
440     mcbspParams.rxQPendingList  = &rxQueuePendingList;
441     mcbspParams.rxQFloatingList = &rxQueueFloatingList;
444     /* Bind the driver instance with device instance */
445     status = mcbspBindDev(&hMcbspDev, coreNum, &mcbspParams);
447     if (status != MCBSP_STATUS_COMPLETED)
448     {
449         System_printf ("Debug(Core %d): MCBSP LLD Bind Device Failed\n", coreNum);
450         return;
451     }
453     /* If the user loopjob buffer is in local L2 memory: Convert into Global memory address space */
454     if(mcbspChanparamRx.userLoopJobBuffer)
455         mcbspChanparamRx.userLoopJobBuffer = (void *)Mcbsp_osalLocal2Global(mcbspChanparamRx.userLoopJobBuffer);
457     /* Create a RX channel for receiving */
458     status = mcbspCreateChan(&hMcbspRxChan, hMcbspDev, MCBSP_MODE_INPUT, &mcbspChanparamRx, mcbspAppCallback, &rxChanMode);
459     if (MCBSP_STATUS_COMPLETED != status)
460     {
461         System_printf ("Debug(Core %d): Error: Create Channel (RX) failed\n", coreNum);
462         return;
463     }
465     /* If the user loopjob buffer is in local L2 memory: Convert into Global memory address space */
466     if(mcbspChanparamTx.userLoopJobBuffer)
467         mcbspChanparamTx.userLoopJobBuffer = Mcbsp_osalLocal2Global(mcbspChanparamTx.userLoopJobBuffer);
469     /* Create a TX channel for the transmission */
470     status = mcbspCreateChan(&hMcbspTxChan, hMcbspDev, MCBSP_MODE_OUTPUT, &mcbspChanparamTx, mcbspAppCallback, &txChanMode);
471     if (MCBSP_STATUS_COMPLETED != status)
472     {
473         System_printf ("Debug(Core %d): Error: Create Channel (TX) failed\n", coreNum);
474         return;
475     }
477     /* Register mcbsp interrupts */
478     //McbspRcvInterrupt_init(hMcbspRxChan);
479     //McbspXmtInterrupt_init(hMcbspTxChan);
481     /* create the buffers required for the TX and RX operations */
482     for (count = 0; count < (NUM_BUFS); count++)
483     {
484         bufTx[count] = (uint8_t *)Osal_mcbspDataBufferMalloc(BUFSIZE);
485         bufRx[count] = (uint8_t *)Osal_mcbspDataBufferMalloc(BUFSIZE);
487         if (bufTx[count] == NULL)
488         {
489             System_printf ("Debug(Core %d): Error: Tx Buffer (%d) Memory Allocation Failed\n", coreNum, count);
490             return;
491         }
492         if (bufRx[count] == NULL)
493         {
494             System_printf ("Debug(Core %d): Error: Rx Buffer (%d) Memory Allocation Failed\n", coreNum, count);
495             return;
496         }
497     }
498 #ifdef MCBSP_LOOP_PING_PONG
499     /* create the ping pong buffers required for the TX and RX operations */
500     for (count = 0; count < (NUM_BUFS); count++)
501     {
502         bufRxPingPong[count] = (uint8_t *)Osal_mcbspDataBufferMalloc(BUFSIZE);
503         bufTxPingPong[count] = (uint8_t *)Osal_mcbspDataBufferMalloc(BUFSIZE);
505         if (bufTxPingPong[count] == NULL)
506         {
507             System_printf ("Debug(Core %d): Error: Tx Ping pong Buffer (%d) Memory Allocation Failed\n", coreNum, count);
508             return;
509         }
510         if (bufRxPingPong[count] == NULL)
511         {
512             System_printf ("Debug(Core %d): Error: Rx Ping pong Buffer (%d) Memory Allocation Failed\n", coreNum, count);
513             return;
514         }
515     }
516 #endif
517     /* Fill the buffers with known data and transmit the same and 
518        check if the same pattern is received */
519     for (count = 0; count < (NUM_BUFS); count++)
520     {
521         memset((uint8_t *)bufTx[count], 0, BUFSIZE);
522         for (tempCount = 0; tempCount < BUFSIZE; tempCount++)
523         {
524             ((uint8_t *)bufTx[count])[tempCount] = (tempCount % 0x100);
525         }
526     }
527     System_printf ("Debug(Core %d): If required to restart set debugCommand variable to %d\n", coreNum, DEBUG_COMMAND_RESTART_CHANNELS);
529 restart_mcbsp_point:
530     txFrameIndex=0;
531     rxFrameIndex=0;
532     init_count=0;
533 #ifdef MCBSP_EXTERNAL_CLOCK
534     /* Initial loading of ping ping buffers */
535     for(init_count =0 ; init_count < INIT_SUBMIT_Q_CNT; init_count++)
536     {
537 #ifdef MCBSP_LOOP_PING_PONG
538         memset((uint8_t *)bufRxPingPong[init_count], 0, BUFSIZE);
540         /* RX frame processing */
541         rxFrame[rxFrameIndex].cmd = Mcbsp_IOBuf_Cmd_READ;
542         rxFrame[rxFrameIndex].addr = (void*)bufRxPingPong[init_count];
543 #else
544         memset((uint8_t *)bufRx[init_count], 0, BUFSIZE);
547         /* RX frame processing */
548         rxFrame[rxFrameIndex].cmd = Mcbsp_IOBuf_Cmd_READ;
549         rxFrame[rxFrameIndex].addr = (void*)bufRx[init_count];
550 #endif
552         rxFrame[rxFrameIndex].size = BUFSIZE;
553         rxFrame[rxFrameIndex].arg = (uint32_t) hMcbspRxChan;
554         rxFrame[rxFrameIndex].status = MCBSP_STATUS_COMPLETED;
555         rxFrame[rxFrameIndex].misc = 1;   /* reserved - used in callback to indicate asynch packet */
557         status = mcbspSubmitChan(hMcbspRxChan, (void *)&rxFrame[rxFrameIndex]);
558         if (status != MCBSP_STATUS_PENDING)
559         {
560             System_printf ("Debug(Core %d): Error: RX buffer #%d submission FAILED\n", coreNum, init_count);
561             retval = 1;
562         }
563         else
564         {
565 #ifdef MCBSP_APP_VERBOSE
566             System_printf ("Debug(Core %d): RX buffer #%d is submitted to MCBSP driver\n", coreNum, init_count);
567 #endif
568         }
569         rxFrameIndex++;
570         rxFrameIndex = (rxFrameIndex >= (NUM_OF_MCBSP_FRAMES)) ? 0 : rxFrameIndex;
572         rxSubmitCount++;
574         /* TX frame processing */
575         txFrame[txFrameIndex].cmd = Mcbsp_IOBuf_Cmd_WRITE;
576 #ifdef MCBSP_LOOP_PING_PONG
577         txFrame[txFrameIndex].addr = (void*)bufTxPingPong[init_count];
578 #else
579         txFrame[txFrameIndex].addr = (void*)bufTx[init_count];
580 #endif
581         txFrame[txFrameIndex].size = BUFSIZE;
582         txFrame[txFrameIndex].arg = (uint32_t)hMcbspTxChan;
583         txFrame[txFrameIndex].status = MCBSP_STATUS_COMPLETED;
584         txFrame[txFrameIndex].misc = 1;   /* reserved - used in callback to indicate asynch packet */
586         status = mcbspSubmitChan(hMcbspTxChan, (void *)&txFrame[txFrameIndex]);
587         if (status != MCBSP_STATUS_PENDING)
588         {
589             System_printf ("Debug(Core %d): Error: TX buffer  #%d submission FAILED\n", coreNum, init_count);
590             retval = 1;
591         }
592         else
593         {
594 #ifdef MCBSP_APP_VERBOSE
595             System_printf ("Debug(Core %d): TX buffer  #%d submission is submitted to MCBSP driver\n", coreNum, init_count);
596 #endif
597         }
598         txFrameIndex++;
599         txFrameIndex = (txFrameIndex >=(NUM_OF_MCBSP_FRAMES)) ? 0 : txFrameIndex;
601         txSubmitCount++;
602     }
604     /* Wait for TX and RX processing to complete */
605     while (1)
606     {
607         if (edmaTxDone == 1)
608         {
609 #ifdef MCBSP_APP_VERBOSE
610             System_printf ("Debug(Core %d): EDMA -> Iteration-%d frames are transmitted to TX path\n", coreNum, count);
611 #endif
612             edmaTxDone = 0; /* Reset for next iteration */
613             mcbspTxDone = 1;
614         }
615         if (edmaRxDone == 1)
616         {
617 #ifdef MCBSP_APP_VERBOSE
618             System_printf ("Debug(Core %d): EDMA -> Iteration-%d frames are received from RX path\n", coreNum, count);
619 #endif
620             edmaRxDone = 0;  /* Reset for next iteration */
621             mcbspRxDone = 1;
622         }
623         if ((mcbspTxDone == 1) && (mcbspRxDone == 1))
624         {
625             mcbspTxDone = 0;  /* Reset for next iteration */
626             mcbspRxDone = 0;  /* Reset for next iteration */
627             break;
628         }
629     }
630 #ifdef MCBSP_LOOP_PING_PONG
631     /* Change ping Pong Index */
632     init_count=0;
633 #endif
634 #endif /* MCBSP_EXTERNAL_CLOCK */
636     /* Start main loop to iterate through frames */
637     while(debugVar)
638     {
639         /* submit frames to the driver */
640         for (count = init_count; count < NUM_BUFS; count++)
641         {
642 #ifdef MCBSP_EXTERNAL_CLOCK
643 /*   With External clock the data coming from the RX side is copied to loop back to the Tx side */
644             memcpy((uint8_t *)bufTx[count], (uint8_t *)bufRx[count], BUFSIZE);
645 #endif
646 #ifdef MCBSP_LOOP_PING_PONG
647             memset((uint8_t *)bufRxPingPong[pingPongIndex], 0, BUFSIZE);
648 #else
649             memset((uint8_t *)bufRx[count], 0, BUFSIZE);
650             /* RX frame processing */
651             rxFrame[rxFrameIndex].cmd = Mcbsp_IOBuf_Cmd_READ;
652             rxFrame[rxFrameIndex].addr = (void*)getGlobalAddr(bufRx[count]);
653             rxFrame[rxFrameIndex].size = BUFSIZE;
654             rxFrame[rxFrameIndex].arg = (uint32_t) hMcbspRxChan;
655             rxFrame[rxFrameIndex].status = MCBSP_STATUS_COMPLETED;
656             rxFrame[rxFrameIndex].misc = 1;   /* reserved - used in callback to indicate asynch packet */
658             status = mcbspSubmitChan(hMcbspRxChan, (void *)&rxFrame[rxFrameIndex]);
659             if (status != MCBSP_STATUS_PENDING)
660             {
661                 System_printf ("Debug(Core %d): Error: RX buffer #%d submission FAILED\n", coreNum, count);
662                 retval = 1;
663             }
664             else
665             {
666 #ifdef MCBSP_APP_VERBOSE
667                 System_printf ("Debug(Core %d): RX buffer #%d is submitted to MCBSP driver\n", coreNum, count);
668 #endif
669             }
670             rxFrameIndex++;
671             rxFrameIndex = (rxFrameIndex >= (NUM_OF_MCBSP_FRAMES)) ? 0 : rxFrameIndex;
672 #endif
673             rxSubmitCount++;
674 #ifdef MCBSP_LOOP_PING_PONG
675             /* Copy buffer from buffer to ping pong buffer*/
676             memcpy((uint8_t *)bufTxPingPong[pingPongIndex], (uint8_t *)bufTx[count],BUFSIZE);
677 #else
678             /* TX frame processing */
679             txFrame[txFrameIndex].cmd = Mcbsp_IOBuf_Cmd_WRITE;
680             txFrame[txFrameIndex].addr = (void*)getGlobalAddr(bufTx[count]);
681             txFrame[txFrameIndex].size = BUFSIZE;
682             txFrame[txFrameIndex].arg = (uint32_t)hMcbspTxChan;
683             txFrame[txFrameIndex].status = MCBSP_STATUS_COMPLETED;
684             txFrame[txFrameIndex].misc = 1;   /* reserved - used in callback to indicate asynch packet */
686             status = mcbspSubmitChan(hMcbspTxChan, (void *)&txFrame[txFrameIndex]);
687             if (status != MCBSP_STATUS_PENDING)
688             {
689                 System_printf ("Debug(Core %d): Error: TX buffer  #%d submission FAILED\n", coreNum, count);
690                 retval = 1;
691             }
692             else
693             {
694 #ifdef MCBSP_APP_VERBOSE
695                 System_printf ("Debug(Core %d): TX buffer  #%d is submitted to MCBSP driver\n", coreNum, count);
696 #endif
697             }
698             txFrameIndex++;
699             txFrameIndex = (txFrameIndex >= (NUM_OF_MCBSP_FRAMES)) ? 0 : txFrameIndex;
700 #endif
701             txSubmitCount++;
703             /* Wait for TX and RX processing to complete */
704             while (1)
705             {
706                 if (edmaTxDone == 1)
707                 {
708 #ifdef MCBSP_APP_VERBOSE
709                     System_printf ("Debug(Core %d): EDMA -> Buffer #-%d is transmitted to TX path\n", coreNum, count);
710 #endif
711                     edmaTxDone = 0; /* Reset for next iteration */
712                     mcbspTxDone = 1;
713                 }
714                 if (edmaRxDone == 1)
715                 {
716 #ifdef MCBSP_APP_VERBOSE
717                     System_printf ("Debug(Core %d): EDMA -> Buffer #-%d is received from RX path\n", coreNum, count);
718 #endif
719                     edmaRxDone = 0;  /* Reset for next iteration */
720                     mcbspRxDone = 1;
721                 }
722                 if ((mcbspTxDone == 1) && (mcbspRxDone == 1))
723                 {
724                     mcbspTxDone = 0;  /* Reset for next iteration */
725                                     mcbspRxDone = 0;  /* Reset for next iteration */
726                                     break;
727                 }
728             }
729 #ifdef MCBSP_LOOP_PING_PONG
730             /* Change ping Pong Index */
731             pingPongIndex=(pingPongIndex)?0:1;
733             /* Copy buffer from buffer to other buffer*/
734             memcpy((void*)bufRx[count], (uint8_t *)bufRxPingPong[pingPongIndex],BUFSIZE);
735 #endif
736             /* compare buffer contents */
737             for (tempCount = 0; tempCount < BUFSIZE; tempCount++)
738             {
739                 if (((char *)bufTx[count])[tempCount] != ((char *)bufRx[count])[tempCount])
740                 {
741 #ifdef MCBSP_APP_VERBOSE
742                     System_printf("Debug(Core %d): Error: TX and RX frame data DOES NOT match in Buffer #-%d\n",
743                         coreNum, count);
744                     System_printf("Debug(Core %d): Error: Buffer index = %d, Tx data = %d, Rx data = %d\n", coreNum,
745                         tempCount, ((char *)bufTx[count])[tempCount], ((char *)bufRx[count])[tempCount]);
746 #endif
747                     errBuffCount++;
748                     break;
749                 }
750             }
751             if (tempCount >= BUFSIZE)
752             {
753 #ifdef MCBSP_APP_VERBOSE
754                 System_printf("Debug(Core %d): TX and RX frames data match in iteration-%d !!!\n", coreNum, count);
755 #endif
756             }
757         }
758         init_count=0;
759         num_iterations++;
760 #ifndef   MCBSP_EXTERNAL_CLOCK
761         if(num_iterations >= NUM_OF_ITERATIONS)
762             break;
763 #endif
764         switch(debugCommand)
765         {
766         case DEBUG_COMMAND_RESTART_CHANNELS:
767             debugCommand=0;
768             /* Close channel and reopen */
769             /* Delete  RX channel */
770             status = mcbspDeleteChan(hMcbspRxChan);
771             if (MCBSP_STATUS_COMPLETED != status)
772             {
773                 System_printf ("Debug(Core %d): Error: Delete Channel (RX) failed\n", coreNum);
774                 return;
775             }
777             /* Delete TX channel*/
778             status = mcbspDeleteChan(hMcbspTxChan);
779             if (MCBSP_STATUS_COMPLETED != status)
780             {
781                 System_printf ("Debug(Core %d): Error: Delete Channel (TX) failed\n", coreNum);
782                 return;
783             }
784             /* Create a RX channel for receiving */
785             status = mcbspCreateChan(&hMcbspRxChan, hMcbspDev, MCBSP_MODE_INPUT, &mcbspChanparamRx, mcbspAppCallback, &rxChanMode);
786             if (MCBSP_STATUS_COMPLETED != status)
787             {
788                 System_printf ("Debug(Core %d): Error: Create Channel (RX) failed\n", coreNum);
789                 return;
790             }
792             /* Create a TX channel for the transmission */
793             status = mcbspCreateChan(&hMcbspTxChan, hMcbspDev, MCBSP_MODE_OUTPUT, &mcbspChanparamTx, mcbspAppCallback, &txChanMode);
794             if (MCBSP_STATUS_COMPLETED != status)
795             {
796                 System_printf ("Debug(Core %d): Error: Create Channel (TX) failed\n", coreNum);
797                 return;
798             }
799             edmaTxDone = 0;   /* Reset for next iteration */
800             edmaRxDone = 0;   /* Reset for next iteration */
801             mcbspTxDone = 0;  /* Reset for next iteration */
802             mcbspRxDone = 0;  /* Reset for next iteration */
803             goto restart_mcbsp_point;
805         default:
806             debugCommand=0;
807             break;
809         }
811     }
813     if ((errBuffCount == 0 ) & (retval ==0))
814     {
815         System_printf("Debug(Core %d): MCBSP Digital Loopback Application completed successfully : "\
816             "Num iterations %d  Num buffers per iteration %d!!!\n",
817             coreNum, num_iterations, NUM_BUFS);
818     }
819     else
820     {
821         System_printf("Debug(Core %d): MCBSP Digital Loopback application FAILED :  "\
822             "Num iterations %d  Num buffers per iteration %d Failed buffers %d!!!\n",
823             coreNum, num_iterations, NUM_BUFS, errBuffCount);
824     }
826     /* Delete  RX channel */
827     status = mcbspDeleteChan(hMcbspRxChan);
828     if (MCBSP_STATUS_COMPLETED != status)
829     {
830         System_printf ("Debug(Core %d): Error: Delete Channel (RX) failed\n", coreNum);
831         return;
832     }
834     /* Delete TX channel*/
835     status = mcbspDeleteChan(hMcbspTxChan);
836     if (MCBSP_STATUS_COMPLETED != status)
837     {
838         System_printf ("Debug(Core %d): Error: Delete Channel (TX) failed\n", coreNum);
839         return;
840     }
841     return;
844 /*
845  * \brief  Void main(Void)
846  *
847  *         Main function of the sample application. This function calls the
848  *         function to configure the mcbsp instance.
849  *
850  * \param  None
851  *
852  * \return None
853  */
854 #include "ti/sysbios/hal/Cache.h"
856 Void main(Void)
858     Task_Params taskParams;
859     EDMA3_DRV_Result edmaResult = 0;
860 #ifdef SIMULATOR_SUPPORT
861     uint8_t uchValue, uchReadValue;
862 #endif
864     Board_initCfg arg = BOARD_INIT_MODULE_CLOCK | BOARD_INIT_PINMUX_CONFIG | BOARD_INIT_UART_STDIO;
865     Board_init(arg);
867     uint32_t temp;
868     /* Get the core number. */
869     coreNum = 0; //CSL_chipReadReg (CSL_CHIP_DNUM);
871 #ifdef SIMULATOR_SUPPORT
872 #warn MCBSP Digital Loopback example is not supported on SIMULATOR !!!
873     System_printf ("MCBSP Digital Loopback example is not supported on SIMULATOR. Exiting!\n");
874     return;
875 #else
876     System_printf ("Debug(Core %d): Running MCBSP Digital Loopback example on the DEVICE\n", coreNum);
877 #endif
879     /* Initialize the system only if the core was configured to do so. */
880     if (coreNum == CORE_SYS_INIT)
881     {
882 #if 0
883         System_printf ("Debug(Core %d): System Initialization for MCBSP\n", coreNum);
884         /* Read FPGA register */
885         if (0 != (platform_fpgaReadConfigReg(MCBSP_FPGA_MISC_REG_OFFSET, &uchReadValue)))
886         {
887             System_printf ("Debug(Core %d): FPGA McBSP_AMC_EN# register READ failed \n", coreNum);
888             return;
889         }
890         /* Clear field for configuration */
891         uchValue = (uchReadValue & (~0x3));
892 #ifndef PLATFORM_FPGA_MCBSP_AMC_EN
893         uchValue |=  0x3;
894 #endif
895         /* Drive McBSP_AMC_EN# high. Output SLCLKs, TxCLKs, RxCLKs, FSTs, FSRs as Hi-Z. 
896          * These clocks and syncs are tri-stated and McBSP is accessed over 80-pin header */
897         if (0 != (platform_fpgaWriteConfigReg(MCBSP_FPGA_MISC_REG_OFFSET, (uchValue))))
898         {
899             System_printf ("Debug(Core %d): FPGA McBSP_AMC_EN# register WRITE failed \n", coreNum);
900             return;
901         }
903         /* DEBUG: Verify if FPGA register is configured correctly */
904         if (0 != (platform_fpgaReadConfigReg(MCBSP_FPGA_MISC_REG_OFFSET, &uchReadValue)))
905         {
906             System_printf ("Debug(Core %d): FPGA McBSP_AMC_EN# register READ failed \n", coreNum);
907             return;
908         }
910         if (uchValue != uchReadValue)
911         {
912             System_printf ("Debug(Core %d): FPGA McBSP_AMC_EN# register setting failed \n", coreNum);
913             return;
914         }
915         else
916         {
917             System_printf ("Debug(Core %d): FPGA McBSP_AMC_EN# register is set to %d \n", coreNum, uchValue);
918         }
919 #endif
920         /* MCBSP Driver Initialization: This should always be called before
921          * invoking the MCBSP Driver. */
922         mcbspInit();
924         /* Device Specific MCBSP Initializations */
925         McbspDevice_init();
926         
927         /* MCBSP Driver is operational at this time. */
928         System_printf ("Debug(Core %d): MCBSP Driver Initialization Done\n", coreNum);
930         /* Write to the SHARED memory location at this point in time. The other cores cannot execute
931          * till the MCBSP Driver is up and running. */
932         isMCBSPInitialized[0] = 1;
934         /* The MCBSP IP block has been initialized. We need to writeback the cache here because it will
935          * ensure that the rest of the cores which are waiting for MCBSP to be initialized would now be
936          * woken up. */
937         //CACHE_wbL1d ((void *) &isMCBSPInitialized[0], MCBSP_MAX_CACHE_ALIGN, CACHE_FENCE_WAIT);
938         Cache_wb ((void *) &isMCBSPInitialized[0], MCBSP_CACHE_LENGTH,0x7fff, 1);
939     }
940     else
941     {
942         /* All other cores need to wait for the MCBSP to be initialized before they proceed with the test. */ 
943         System_printf ("Debug(Core %d): Waiting for MCBSP to be initialized.\n", coreNum);
945         /* All other cores loop around forever till the MCBSP is up and running. 
946          * We need to invalidate the cache so that we always read this from the memory. */
947         while (isMCBSPInitialized[0] == 0)
948             //CACHE_invL1d ((void *) &isMCBSPInitialized[0], MCBSP_MAX_CACHE_ALIGN, CACHE_FENCE_WAIT);
949                 Cache_inv ((void *) &isMCBSPInitialized[0], MCBSP_CACHE_LENGTH, 0x7fff, 1);
952         System_printf ("Debug(Core %d): MCBSP can now be used.\n", coreNum);
953     }
954     /* Enabling the dmaChannel MCBSP Events to EDMA (36-40) */
955     temp=sampleEdma3GblCfgParams[0].dmaChannelHwEvtMap[1];
956     sampleEdma3GblCfgParams[0].dmaChannelHwEvtMap[1]= temp | 0x000000F0;
958     /* Let RM Own the dmaChannels (36-40) */
959      temp=sampleInstInitConfig[0][0].ownDmaChannels[1];
960      sampleInstInitConfig[0][0].ownDmaChannels[1]=temp | 0x000000F0;
962      /* Let RM Own the TCCs (36-40) */
963      temp=sampleInstInitConfig[0][0].ownTccs[1];
964      sampleInstInitConfig[0][0].ownTccs[1]= temp | 0x000000F0;
966     /* Initialize EDMA3 library */
967     hEdma[0] = edma3init(0, &edmaResult);
969     if (edmaResult != EDMA3_DRV_SOK)
970     {
971         /* Report EDMA Error */
972         System_printf("Debug(Core %d): EDMA Driver Initialization FAILED\n", coreNum);
973     }
974     else
975     {
976         System_printf("Debug(Core %d): EDMA Driver Initialization Done\n", coreNum);
977     }
979     /* Create the Digital Loopback Application Task */
980     Task_Params_init(&taskParams);
981     Task_create(mcbspDigLpbkApp, &taskParams, NULL);
983     /* Start BIOS */
984     BIOS_start();
986     return;
989 /* ========================================================================== */
990 /*                                END OF FILE                                 */
991 /* ========================================================================== */