PRSDK-4301 Add UART print console support
[keystone-rtos/mcbsp-lld.git] / example / k2g / 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>
54 #include <MCBSP_log.h>
56 /* Include EDMA3 Driver */
57 #include <ti/sdo/edma3/drv/edma3_drv.h>
59 /* CSL Chip Functional Layer */
60 //#include <ti/csl/csl_chip.h>
62 /* CSL Cache Functional Layer */
63 //#include <ti/csl/csl_cacheAux.h>
65 /* CSL CPINTC Include Files. */
66 //#include<ti/csl/csl_cpIntc.h>
68 /* MCBSP Driver Include File. */
69 #include <ti/drv/mcbsp/mcbsp_drv.h>
70 #include <ti/drv/mcbsp/mcbsp_osal.h>
72 /* PlatformLib Include File */
73 //#include <ti/platform/platform.h>
76 /* ========================================================================== */
77 /*                        EXTERNAL FUNCTIONS                                  */
78 /* ========================================================================== */
80 extern EDMA3_DRV_Handle edma3init(unsigned int edma3Id, EDMA3_DRV_Result *);
82 extern void McbspDevice_init(void);
84 extern int32_t Osal_dataBufferInitMemory(uint32_t dataBufferSize);
86 extern Board_STATUS Board_init(Board_initCfg);
88 extern void McbspXmtInterrupt_init(void *mcbspTxChan);
89 extern void McbspRcvInterrupt_init(void *mcbspRxChan);
91 /* FPGA Configuration Misc-1 Register offset */
92 #define MCBSP_FPGA_MISC_REG_OFFSET (0x0C)
94 /* ========================================================================== */
95 /*                           MACRO DEFINTIONS                                 */
96 /* ========================================================================== */
98 #define NUM_BUFS                     2          /* Max of buffers used in each direction */
99 #define FRAMESIZE                   40          /* e.g 5 ms 8 KHz samples         */
100 #define NUM_OF_ENABLED_CHANNELS      8          /* Number of slots to be used     */
101 #define NUM_OF_MAX_CHANNELS            128                      /* Maximum number of time slots available based on clock settings   */
102 #define BUFSIZE                   (NUM_OF_ENABLED_CHANNELS * FRAMESIZE)        /* Total buffer size per frame */
104 /* Defines the core number responsible for system initialization. */
105 #define CORE_SYS_INIT         0
106 /* Number of iterations to execute test: Only applicable to INTERNAL CLOCK Loopback test */
107 #define NUM_OF_ITERATIONS 10
109 /* Number of MCBSP Frame structures used for submit channel */
110 #define NUM_OF_MCBSP_FRAMES 2
112 /* Number of buffers initially submitted to Mcbsp lld: Only applicable to
113    External clock test ; Note: This should be set to 2*/
114 #define INIT_SUBMIT_Q_CNT 2
116 /*============================================================================*/
117 /*                            GLOBAL VARIABLES                                */
118 /*============================================================================*/
120 /* Shared Memory Variable to ensure synchronizing MCBSP initialization
121  * with all the other cores. */
122 /* Created an array to pad the cache line with MCBSP_CACHE_LENGTH size */
123 #pragma DATA_ALIGN   (isMCBSPInitialized, MCBSP_MAX_CACHE_ALIGN)
124 #pragma DATA_SECTION (isMCBSPInitialized, ".mcbspSharedMem");
125 volatile Uint32 isMCBSPInitialized[(MCBSP_CACHE_LENGTH / sizeof(Uint32))] = { 0 };
127 /* Handle to the EDMA driver instance */
128 #pragma DATA_ALIGN   (hEdma, MCBSP_MAX_CACHE_ALIGN)
129 EDMA3_DRV_Handle hEdma[(MCBSP_CACHE_LENGTH / sizeof(EDMA3_DRV_Handle))] = { NULL };
131 /* Handle to MCBSP driver instance */
132 typedef void* Mcbsp_DevHandle;
133 Mcbsp_DevHandle  hMcbspDev;
135 /* Handle to MCBSP driver channel instance */
136 typedef void* Mcbsp_ChanHandle;
137 Mcbsp_ChanHandle  hMcbspTxChan;
138 Mcbsp_ChanHandle  hMcbspRxChan;
140 /* Core Number Identifier */
141 UInt32 coreNum = 0xFFFF;
143 /* Array to hold the pointer to the allocated buffers     */
144 void* bufRx[NUM_BUFS];
145 void* bufTx[NUM_BUFS];
147 #ifdef MCBSP_LOOP_PING_PONG
148 /* Ping pong buffers used to submit to Mcbsp lld, which will be used in a loop */
149 void* bufRxPingPong[INIT_SUBMIT_Q_CNT];
150 void* bufTxPingPong[INIT_SUBMIT_Q_CNT];
151 #endif
152 /* Global Error call back function prototype */
153 void mcbsp_GblErrCallback(uint32_t chanHandle,uint32_t spcr_read,uint32_t Arg3);
155 /* Variables to indicate status of EDMA TX and RX requests */
156 volatile uint32_t edmaTxDone = 0;
157 volatile uint32_t edmaRxDone = 0;
158 /* Global variables to track number of buffers submitted, number of iterations, error counts etc */
159 int rxSubmitCount=0, txSubmitCount=0;
160 uint32_t num_iterations=0;
161 uint32_t num_rx_Call_backs=0, num_tx_Call_backs=0, dummy_call_backs=0;
162 uint32_t rxunderflowcnt=0, txunderflowcnt=0;
163 uint32_t errBuffCount=0;
164 /* Debug variables */
165 volatile int debugVar=1;  /* This can be used to maintain a while loop, If set to 0 will exit loop */
166 volatile int debugCommand=1;  /* This can be used to set to value below to send command to restart channel  */
168 #define DEBUG_COMMAND_RESTART_CHANNELS 1
169 /**
170  * \brief    Mcbsp Sample rate generator default parameters.
171  *
172  */
173 Mcbsp_srgConfig mcbspSrgCfg =
175     FALSE,                     /* No gsync to be used as input is not CLKS    */
176     Mcbsp_ClkSPol_RISING_EDGE, /* Dont care as input clock is not clks        */
177     Mcbsp_SrgClk_CLKCPU,       /* McBSP internal clock to be used             */
178     //166666667,                 /* Mcbsp internal clock frequency(PLL-SYSCLK6) */
179     333333333, //sys_oscclk or cpu_clk/3
180     0                          /* frame sync pulse width (val+1) is used      */
181 };
183 /**
184  * \brief    Mcbsp device creation default parameters.
185  *
186  */
187 const Mcbsp_Params Mcbsp_PARAMS =
189     Mcbsp_DevMode_McBSP,       /* Use the device as MCBSP                     */
190     Mcbsp_OpMode_DMAINTERRUPT, /* Use DMA mode of operation                   */
191     TRUE,                      /* cache coherency taken care of by driver     */
192     Mcbsp_EmuMode_FREE,        /* Emulation mode free is to be enabled        */
193 #ifdef    MCBSP_EXTERNAL_CLOCK
194     Mcbsp_Loopback_DISABLE,    /* Loop back mode disabled                     */
195 #else
196     Mcbsp_Loopback_ENABLE,     /* Loop back mode enabled                      */
197 #endif
198     &mcbspSrgCfg,              /* sample rate generator configuration         */
199     NULL,                      /* TX pending buffer queue from application    */
200     NULL,                      /* TX floating buffer queue in DMA             */
201     NULL,                      /* RX pending buffer queue from application    */
202     NULL                       /* RX floating buffer queue in DMA             */
203 };
205 #pragma DATA_ALIGN(loopTxJob, MCBSP_MAX_CACHE_ALIGN)
206 static Int32 loopTxJob[16] = {
207     /* Filling with Mu law silence pattern : Can be any user defined pattern */
208     0x7f7f7f7f, 0x7f7f7f7f, 0x7f7f7f7f, 0x7f7f7f7f, 0x7f7f7f7f, 0x7f7f7f7f, 0x7f7f7f7f, 0x7f7f7f7f,
209     0x7f7f7f7f, 0x7f7f7f7f, 0x7f7f7f7f, 0x7f7f7f7f, 0x7f7f7f7f, 0x7f7f7f7f, 0x7f7f7f7f, 0x7f7f7f7f
210 };
211 #pragma DATA_ALIGN(loopRxJob, MCBSP_MAX_CACHE_ALIGN)
212 static Int32 loopRxJob[16] = {
213     0, 0, 0, 0, 0, 0, 0, 0,
214     0, 0, 0, 0, 0, 0, 0, 0
215 };
217 /**< settings to configure the TX or RX hardware sections                 */
218 Mcbsp_DataConfig mcbspChanConfigTx =
220     Mcbsp_Phase_SINGLE,
221     Mcbsp_WordLength_8,
222     Mcbsp_WordLength_8,    /* Dont care for single phase*/
223     NUM_OF_MAX_CHANNELS,
224     NUM_OF_MAX_CHANNELS,      // Only used with dual phase
225     Mcbsp_FrmSync_DETECT,
226 #ifdef MCBSP_EXTERNAL_CLOCK
227     Mcbsp_DataDelay_0_BIT,
228 #else
229     Mcbsp_DataDelay_1_BIT,
230 #endif
231     Mcbsp_Compand_OFF_MSB_FIRST,
232     Mcbsp_BitReversal_DISABLE,
233     Mcbsp_IntMode_ON_SYNCERR,
234     Mcbsp_RxJust_RZF,  /* Dont care for TX         */
235     Mcbsp_DxEna_OFF
236 };
238 /**< settings to configure the TX or RX hardware sections                 */
239 Mcbsp_DataConfig mcbspChanConfigRx =
241     Mcbsp_Phase_SINGLE,
242     Mcbsp_WordLength_8,
243     Mcbsp_WordLength_8,    /* Dont care for single phase*/
244     NUM_OF_MAX_CHANNELS,
245     NUM_OF_MAX_CHANNELS,      // Only used with dual phase
246     Mcbsp_FrmSync_DETECT,
247 #ifdef MCBSP_EXTERNAL_CLOCK
248     Mcbsp_DataDelay_0_BIT,
249 #else
250     Mcbsp_DataDelay_1_BIT,
251 #endif
252     Mcbsp_Compand_OFF_MSB_FIRST,
253     Mcbsp_BitReversal_DISABLE,
254     Mcbsp_IntMode_ON_SYNCERR,
255     Mcbsp_RxJust_RZF,  /* Dont care for TX         */
256     Mcbsp_DxEna_OFF
257 };
258 /**< clock setup for the TX section                     */
259 Mcbsp_ClkSetup mcbspClkConfigTx =
261 #ifdef MCBSP_EXTERNAL_CLOCK
262     Mcbsp_FsClkMode_EXTERNAL,
263     8000,                   /* 8KHz                   */
264     Mcbsp_TxRxClkMode_EXTERNAL,
265 #else
266     Mcbsp_FsClkMode_INTERNAL,
267     8000,                   /* 8KHz                   */
268     Mcbsp_TxRxClkMode_INTERNAL,
269 #endif
270     Mcbsp_FsPol_ACTIVE_HIGH,
271     Mcbsp_ClkPol_RISING_EDGE
272 };
274 /**< clock setup for the RX section                     */
275 Mcbsp_ClkSetup mcbspClkConfigRx =
277 #ifdef MCBSP_EXTERNAL_CLOCK
278     Mcbsp_FsClkMode_EXTERNAL,
279     8000,                   /* 8KHz                   */
280     Mcbsp_TxRxClkMode_EXTERNAL,
281 #else
282     Mcbsp_FsClkMode_INTERNAL,
283     8000,                   /* 8KHz                   */
284     Mcbsp_TxRxClkMode_INTERNAL,
285 #endif
286     Mcbsp_FsPol_ACTIVE_HIGH,
287     Mcbsp_ClkPol_FALLING_EDGE
288 };
290 /**< Multi channel setup                                                      */
291 Mcbsp_McrSetup mcbspMultiChanCtrl =
293     Mcbsp_McmMode_ALL_CHAN_DISABLED_UNMASKED,
294     Mcbsp_PartitionMode_CHAN_0_15,
295     Mcbsp_PartitionMode_CHAN_16_31,
296     Mcbsp_PartitionMode_2
297 };
300 Mcbsp_ChanParams mcbspChanparamTx =
302     Mcbsp_WordLength_8,  /* wordlength configured    */
303     &loopTxJob[0],          /* loop job buffer internal */
304     8,                    /* user loopjob length      */
305     mcbsp_GblErrCallback, /* global error callback    */
306     NULL,                 /* edma Handle              */
307     1,                    /* EDMA event queue         */
308     8,                    /* hwi number               */
309     Mcbsp_BufferFormat_MULTISLOT_NON_INTERLEAVED,
310     TRUE,                 /* FIFO mode enabled        */
311     &mcbspChanConfigTx,   /* channel configuration    */
312     &mcbspClkConfigTx,    /* clock configuration      */
313     &mcbspMultiChanCtrl,  /* multi channel control    */
314     0x7531,  /* Enabled timeslots: 0, 4, 5, 8, 10, 12, 13, 14 */
315     0x00,
316     0x00,
317     0x00,
318     NUM_OF_ENABLED_CHANNELS    /* Total number of channels enabled*/
319 };
321 Mcbsp_ChanParams mcbspChanparamRx =
323     Mcbsp_WordLength_8,  /* wordlength configured    */
324     &loopRxJob[0],          /* loop job buffer internal */
325     8,                    /* user loopjob length      */
326     mcbsp_GblErrCallback, /* global error callback    */
327     NULL,                 /* edma Handle              */
328     1,                    /* EDMA event queue         */
329     8,                    /* hwi number               */
330     Mcbsp_BufferFormat_MULTISLOT_NON_INTERLEAVED,
331     TRUE,                 /* FIFO mode enabled        */
332     &mcbspChanConfigRx,   /* channel configuration    */
333     &mcbspClkConfigRx,    /* clock configuration      */
334     &mcbspMultiChanCtrl,  /* multi channel control    */
335     0x7531,  /* Enabled timeslots: 0, 4, 5, 8, 10, 12, 13, 14 */
336     0x00,
337     0x00,
338     0x00,
339     NUM_OF_ENABLED_CHANNELS    /* Total number of channels enabled*/
340 };
343 /* ========================================================================== */
344 /*                           FUNCTION DEFINITIONS                             */
345 /* ========================================================================== */
347 /*
348  *   This is the application's callback function. The driver will
349  *   call this function whenever an EDMA I/O operation is over.
350  *
351  */
352 void mcbspAppCallback(void* arg, Mcbsp_IOBuf *ioBuf)
354     int32_t mode;
355     int32_t *pmode = (int32_t *)arg;
357     mode = *pmode;
358     if (mode == MCBSP_MODE_OUTPUT)
359     {
360         if(ioBuf) {
361             num_tx_Call_backs++;
362             edmaTxDone = 1;
363         }else
364             txunderflowcnt++;
365     }
366     else if (mode == MCBSP_MODE_INPUT)
367     {
368         if(ioBuf) {
369             num_rx_Call_backs++;
370             edmaRxDone = 1;
371         }else
372             rxunderflowcnt++;
373     }else
374         dummy_call_backs++;
375     return;
378 /*
379  *   This is the application's Global error callback function 
380  */
381 void mcbsp_GblErrCallback(uint32_t chanHandle,uint32_t spcr_read,uint32_t Arg3)
383     MCBSP_log ("Debug(Core %d): ERROR callback called SPCR: %x", coreNum, spcr_read);
386 /*
387  * \brief   This function demostrates the use of Mcbsp using digital loopback
388  *          communication setup.
389  *
390  * \param   None
391  *
392  * \return  None
393  */
394 void mcbspDigLpbkApp(UArg arg0, UArg arg1)
396     /**< Mcbsp device params                                                  */
397     Mcbsp_Params  mcbspParams;
399     /**< Queue to hold the pending packets received from the application      */
400     Queue_Struct  txQueuePendingList, rxQueuePendingList;
401     /**< Queue to manage floating packets in DMA                              */
402     Queue_Struct  txQueueFloatingList, rxQueueFloatingList;
404     uint32_t count   = 0, tempCount = 0;
405     int32_t  status  = 0, retval = 0;
406     int32_t  txChanMode = MCBSP_MODE_OUTPUT;
407     int32_t  rxChanMode = MCBSP_MODE_INPUT;
408     uint32_t mcbspTxDone = 0, mcbspRxDone = 0;
409     Mcbsp_IOBuf txFrame[NUM_OF_MCBSP_FRAMES], rxFrame[NUM_OF_MCBSP_FRAMES];
410     int txFrameIndex=0, rxFrameIndex=0;
411     int init_count=0;
412 #ifdef MCBSP_LOOP_PING_PONG
413     int pingPongIndex=0;
414 #endif
416     /* Initialize the OSAL */
417     if (Osal_dataBufferInitMemory(BUFSIZE) < 0)
418     {
419         MCBSP_log ("Debug(Core %d): Error: Unable to initialize the OSAL. \n", coreNum);
420         return;
421     }
423     /* update EDMA3 handle to channel parameters */
424     mcbspChanparamTx.edmaHandle = hEdma[0];
425     mcbspChanparamRx.edmaHandle = hEdma[0];
427     /* create the pending and floating queue for the TX channel           */
428     Queue_construct(&txQueuePendingList, NULL);
429     Queue_construct(&txQueueFloatingList, NULL);
431     /* create the pending and floating queue for the RX channel           */
432     Queue_construct(&rxQueuePendingList, NULL);
433     Queue_construct(&rxQueueFloatingList, NULL);
436     mcbspParams                 = Mcbsp_PARAMS;
437     mcbspParams.txQPendingList  = &txQueuePendingList;
438     mcbspParams.txQFloatingList = &txQueueFloatingList;
439     mcbspParams.rxQPendingList  = &rxQueuePendingList;
440     mcbspParams.rxQFloatingList = &rxQueueFloatingList;
443     /* Bind the driver instance with device instance */
444     status = mcbspBindDev(&hMcbspDev, coreNum, &mcbspParams);
446     if (status != MCBSP_STATUS_COMPLETED)
447     {
448         MCBSP_log ("Debug(Core %d): MCBSP LLD Bind Device Failed\n", coreNum);
449         return;
450     }
452     /* If the user loopjob buffer is in local L2 memory: Convert into Global memory address space */
453     if(mcbspChanparamRx.userLoopJobBuffer)
454         mcbspChanparamRx.userLoopJobBuffer = (void *)Mcbsp_osalLocal2Global(mcbspChanparamRx.userLoopJobBuffer);
456     /* Create a RX channel for receiving */
457     status = mcbspCreateChan(&hMcbspRxChan, hMcbspDev, MCBSP_MODE_INPUT, &mcbspChanparamRx, mcbspAppCallback, &rxChanMode);
458     if (MCBSP_STATUS_COMPLETED != status)
459     {
460         MCBSP_log ("Debug(Core %d): Error: Create Channel (RX) failed\n", coreNum);
461         return;
462     }
464     /* If the user loopjob buffer is in local L2 memory: Convert into Global memory address space */
465     if(mcbspChanparamTx.userLoopJobBuffer)
466         mcbspChanparamTx.userLoopJobBuffer = Mcbsp_osalLocal2Global(mcbspChanparamTx.userLoopJobBuffer);
468     /* Create a TX channel for the transmission */
469     status = mcbspCreateChan(&hMcbspTxChan, hMcbspDev, MCBSP_MODE_OUTPUT, &mcbspChanparamTx, mcbspAppCallback, &txChanMode);
470     if (MCBSP_STATUS_COMPLETED != status)
471     {
472         MCBSP_log ("Debug(Core %d): Error: Create Channel (TX) failed\n", coreNum);
473         return;
474     }
476     /* Register mcbsp interrupts */
477     //McbspRcvInterrupt_init(hMcbspRxChan);
478     //McbspXmtInterrupt_init(hMcbspTxChan);
480     /* create the buffers required for the TX and RX operations */
481     for (count = 0; count < (NUM_BUFS); count++)
482     {
483         bufTx[count] = (uint8_t *)Osal_mcbspDataBufferMalloc(BUFSIZE);
484         bufRx[count] = (uint8_t *)Osal_mcbspDataBufferMalloc(BUFSIZE);
486         if (bufTx[count] == NULL)
487         {
488             MCBSP_log ("Debug(Core %d): Error: Tx Buffer (%d) Memory Allocation Failed\n", coreNum, count);
489             return;
490         }
491         if (bufRx[count] == NULL)
492         {
493             MCBSP_log ("Debug(Core %d): Error: Rx Buffer (%d) Memory Allocation Failed\n", coreNum, count);
494             return;
495         }
496     }
497 #ifdef MCBSP_LOOP_PING_PONG
498     /* create the ping pong buffers required for the TX and RX operations */
499     for (count = 0; count < (NUM_BUFS); count++)
500     {
501         bufRxPingPong[count] = (uint8_t *)Osal_mcbspDataBufferMalloc(BUFSIZE);
502         bufTxPingPong[count] = (uint8_t *)Osal_mcbspDataBufferMalloc(BUFSIZE);
504         if (bufTxPingPong[count] == NULL)
505         {
506             MCBSP_log ("Debug(Core %d): Error: Tx Ping pong Buffer (%d) Memory Allocation Failed\n", coreNum, count);
507             return;
508         }
509         if (bufRxPingPong[count] == NULL)
510         {
511             MCBSP_log ("Debug(Core %d): Error: Rx Ping pong Buffer (%d) Memory Allocation Failed\n", coreNum, count);
512             return;
513         }
514     }
515 #endif
516     /* Fill the buffers with known data and transmit the same and 
517        check if the same pattern is received */
518     for (count = 0; count < (NUM_BUFS); count++)
519     {
520         memset((uint8_t *)bufTx[count], 0, BUFSIZE);
521         for (tempCount = 0; tempCount < BUFSIZE; tempCount++)
522         {
523             ((uint8_t *)bufTx[count])[tempCount] = (tempCount % 0x100);
524         }
525     }
526     MCBSP_log ("Debug(Core %d): If required to restart set debugCommand variable to %d\n", coreNum, DEBUG_COMMAND_RESTART_CHANNELS);
528 restart_mcbsp_point:
529     txFrameIndex=0;
530     rxFrameIndex=0;
531     init_count=0;
532 #ifdef MCBSP_EXTERNAL_CLOCK
533     /* Initial loading of ping ping buffers */
534     for(init_count =0 ; init_count < INIT_SUBMIT_Q_CNT; init_count++)
535     {
536 #ifdef MCBSP_LOOP_PING_PONG
537         memset((uint8_t *)bufRxPingPong[init_count], 0, BUFSIZE);
539         /* RX frame processing */
540         rxFrame[rxFrameIndex].cmd = Mcbsp_IOBuf_Cmd_READ;
541         rxFrame[rxFrameIndex].addr = (void*)bufRxPingPong[init_count];
542 #else
543         memset((uint8_t *)bufRx[init_count], 0, BUFSIZE);
546         /* RX frame processing */
547         rxFrame[rxFrameIndex].cmd = Mcbsp_IOBuf_Cmd_READ;
548         rxFrame[rxFrameIndex].addr = (void*)bufRx[init_count];
549 #endif
551         rxFrame[rxFrameIndex].size = BUFSIZE;
552         rxFrame[rxFrameIndex].arg = (uint32_t) hMcbspRxChan;
553         rxFrame[rxFrameIndex].status = MCBSP_STATUS_COMPLETED;
554         rxFrame[rxFrameIndex].misc = 1;   /* reserved - used in callback to indicate asynch packet */
556         status = mcbspSubmitChan(hMcbspRxChan, (void *)&rxFrame[rxFrameIndex]);
557         if (status != MCBSP_STATUS_PENDING)
558         {
559             MCBSP_log ("Debug(Core %d): Error: RX buffer #%d submission FAILED\n", coreNum, init_count);
560             retval = 1;
561         }
562         else
563         {
564 #ifdef MCBSP_APP_VERBOSE
565             MCBSP_log ("Debug(Core %d): RX buffer #%d is submitted to MCBSP driver\n", coreNum, init_count);
566 #endif
567         }
568         rxFrameIndex++;
569         rxFrameIndex = (rxFrameIndex >= (NUM_OF_MCBSP_FRAMES)) ? 0 : rxFrameIndex;
571         rxSubmitCount++;
573         /* TX frame processing */
574         txFrame[txFrameIndex].cmd = Mcbsp_IOBuf_Cmd_WRITE;
575 #ifdef MCBSP_LOOP_PING_PONG
576         txFrame[txFrameIndex].addr = (void*)bufTxPingPong[init_count];
577 #else
578         txFrame[txFrameIndex].addr = (void*)bufTx[init_count];
579 #endif
580         txFrame[txFrameIndex].size = BUFSIZE;
581         txFrame[txFrameIndex].arg = (uint32_t)hMcbspTxChan;
582         txFrame[txFrameIndex].status = MCBSP_STATUS_COMPLETED;
583         txFrame[txFrameIndex].misc = 1;   /* reserved - used in callback to indicate asynch packet */
585         status = mcbspSubmitChan(hMcbspTxChan, (void *)&txFrame[txFrameIndex]);
586         if (status != MCBSP_STATUS_PENDING)
587         {
588             MCBSP_log ("Debug(Core %d): Error: TX buffer  #%d submission FAILED\n", coreNum, init_count);
589             retval = 1;
590         }
591         else
592         {
593 #ifdef MCBSP_APP_VERBOSE
594             MCBSP_log ("Debug(Core %d): TX buffer  #%d submission is submitted to MCBSP driver\n", coreNum, init_count);
595 #endif
596         }
597         txFrameIndex++;
598         txFrameIndex = (txFrameIndex >=(NUM_OF_MCBSP_FRAMES)) ? 0 : txFrameIndex;
600         txSubmitCount++;
601     }
603     /* Wait for TX and RX processing to complete */
604     while (1)
605     {
606         if (edmaTxDone == 1)
607         {
608 #ifdef MCBSP_APP_VERBOSE
609             MCBSP_log ("Debug(Core %d): EDMA -> Iteration-%d frames are transmitted to TX path\n", coreNum, count);
610 #endif
611             edmaTxDone = 0; /* Reset for next iteration */
612             mcbspTxDone = 1;
613         }
614         if (edmaRxDone == 1)
615         {
616 #ifdef MCBSP_APP_VERBOSE
617             MCBSP_log ("Debug(Core %d): EDMA -> Iteration-%d frames are received from RX path\n", coreNum, count);
618 #endif
619             edmaRxDone = 0;  /* Reset for next iteration */
620             mcbspRxDone = 1;
621         }
622         if ((mcbspTxDone == 1) && (mcbspRxDone == 1))
623         {
624             mcbspTxDone = 0;  /* Reset for next iteration */
625             mcbspRxDone = 0;  /* Reset for next iteration */
626             break;
627         }
628     }
629 #ifdef MCBSP_LOOP_PING_PONG
630     /* Change ping Pong Index */
631     init_count=0;
632 #endif
633 #endif /* MCBSP_EXTERNAL_CLOCK */
635     /* Start main loop to iterate through frames */
636     while(debugVar)
637     {
638         /* submit frames to the driver */
639         for (count = init_count; count < NUM_BUFS; count++)
640         {
641 #ifdef MCBSP_EXTERNAL_CLOCK
642 /*   With External clock the data coming from the RX side is copied to loop back to the Tx side */
643             memcpy((uint8_t *)bufTx[count], (uint8_t *)bufRx[count], BUFSIZE);
644 #endif
645 #ifdef MCBSP_LOOP_PING_PONG
646             memset((uint8_t *)bufRxPingPong[pingPongIndex], 0, BUFSIZE);
647 #else
648             memset((uint8_t *)bufRx[count], 0, BUFSIZE);
649             /* RX frame processing */
650             rxFrame[rxFrameIndex].cmd = Mcbsp_IOBuf_Cmd_READ;
651             rxFrame[rxFrameIndex].addr = (void*)getGlobalAddr(bufRx[count]);
652             rxFrame[rxFrameIndex].size = BUFSIZE;
653             rxFrame[rxFrameIndex].arg = (uint32_t) hMcbspRxChan;
654             rxFrame[rxFrameIndex].status = MCBSP_STATUS_COMPLETED;
655             rxFrame[rxFrameIndex].misc = 1;   /* reserved - used in callback to indicate asynch packet */
657             status = mcbspSubmitChan(hMcbspRxChan, (void *)&rxFrame[rxFrameIndex]);
658             if (status != MCBSP_STATUS_PENDING)
659             {
660                 MCBSP_log ("Debug(Core %d): Error: RX buffer #%d submission FAILED\n", coreNum, count);
661                 retval = 1;
662             }
663             else
664             {
665 #ifdef MCBSP_APP_VERBOSE
666                 MCBSP_log ("Debug(Core %d): RX buffer #%d is submitted to MCBSP driver\n", coreNum, count);
667 #endif
668             }
669             rxFrameIndex++;
670             rxFrameIndex = (rxFrameIndex >= (NUM_OF_MCBSP_FRAMES)) ? 0 : rxFrameIndex;
671 #endif
672             rxSubmitCount++;
673 #ifdef MCBSP_LOOP_PING_PONG
674             /* Copy buffer from buffer to ping pong buffer*/
675             memcpy((uint8_t *)bufTxPingPong[pingPongIndex], (uint8_t *)bufTx[count],BUFSIZE);
676 #else
677             /* TX frame processing */
678             txFrame[txFrameIndex].cmd = Mcbsp_IOBuf_Cmd_WRITE;
679             txFrame[txFrameIndex].addr = (void*)getGlobalAddr(bufTx[count]);
680             txFrame[txFrameIndex].size = BUFSIZE;
681             txFrame[txFrameIndex].arg = (uint32_t)hMcbspTxChan;
682             txFrame[txFrameIndex].status = MCBSP_STATUS_COMPLETED;
683             txFrame[txFrameIndex].misc = 1;   /* reserved - used in callback to indicate asynch packet */
685             status = mcbspSubmitChan(hMcbspTxChan, (void *)&txFrame[txFrameIndex]);
686             if (status != MCBSP_STATUS_PENDING)
687             {
688                 MCBSP_log ("Debug(Core %d): Error: TX buffer  #%d submission FAILED\n", coreNum, count);
689                 retval = 1;
690             }
691             else
692             {
693 #ifdef MCBSP_APP_VERBOSE
694                 MCBSP_log ("Debug(Core %d): TX buffer  #%d is submitted to MCBSP driver\n", coreNum, count);
695 #endif
696             }
697             txFrameIndex++;
698             txFrameIndex = (txFrameIndex >= (NUM_OF_MCBSP_FRAMES)) ? 0 : txFrameIndex;
699 #endif
700             txSubmitCount++;
702             /* Wait for TX and RX processing to complete */
703             while (1)
704             {
705                 if (edmaTxDone == 1)
706                 {
707 #ifdef MCBSP_APP_VERBOSE
708                     MCBSP_log ("Debug(Core %d): EDMA -> Buffer #-%d is transmitted to TX path\n", coreNum, count);
709 #endif
710                     edmaTxDone = 0; /* Reset for next iteration */
711                     mcbspTxDone = 1;
712                 }
713                 if (edmaRxDone == 1)
714                 {
715 #ifdef MCBSP_APP_VERBOSE
716                     MCBSP_log ("Debug(Core %d): EDMA -> Buffer #-%d is received from RX path\n", coreNum, count);
717 #endif
718                     edmaRxDone = 0;  /* Reset for next iteration */
719                     mcbspRxDone = 1;
720                 }
721                 if ((mcbspTxDone == 1) && (mcbspRxDone == 1))
722                 {
723                     mcbspTxDone = 0;  /* Reset for next iteration */
724                                     mcbspRxDone = 0;  /* Reset for next iteration */
725                                     break;
726                 }
727             }
728 #ifdef MCBSP_LOOP_PING_PONG
729             /* Change ping Pong Index */
730             pingPongIndex=(pingPongIndex)?0:1;
732             /* Copy buffer from buffer to other buffer*/
733             memcpy((void*)bufRx[count], (uint8_t *)bufRxPingPong[pingPongIndex],BUFSIZE);
734 #endif
735             /* compare buffer contents */
736             for (tempCount = 0; tempCount < BUFSIZE; tempCount++)
737             {
738                 if (((char *)bufTx[count])[tempCount] != ((char *)bufRx[count])[tempCount])
739                 {
740 #ifdef MCBSP_APP_VERBOSE
741                     MCBSP_log("Debug(Core %d): Error: TX and RX frame data DOES NOT match in Buffer #-%d\n",
742                         coreNum, count);
743                     MCBSP_log("Debug(Core %d): Error: Buffer index = %d, Tx data = %d, Rx data = %d\n", coreNum,
744                         tempCount, ((char *)bufTx[count])[tempCount], ((char *)bufRx[count])[tempCount]);
745 #endif
746                     errBuffCount++;
747                     break;
748                 }
749             }
750             if (tempCount >= BUFSIZE)
751             {
752 #ifdef MCBSP_APP_VERBOSE
753                 MCBSP_log("Debug(Core %d): TX and RX frames data match in iteration-%d !!!\n", coreNum, count);
754 #endif
755             }
756         }
757         init_count=0;
758         num_iterations++;
759 #ifndef   MCBSP_EXTERNAL_CLOCK
760         if(num_iterations >= NUM_OF_ITERATIONS)
761             break;
762 #endif
763         switch(debugCommand)
764         {
765         case DEBUG_COMMAND_RESTART_CHANNELS:
766             debugCommand=0;
767             /* Close channel and reopen */
768             /* Delete  RX channel */
769             status = mcbspDeleteChan(hMcbspRxChan);
770             if (MCBSP_STATUS_COMPLETED != status)
771             {
772                 MCBSP_log ("Debug(Core %d): Error: Delete Channel (RX) failed\n", coreNum);
773                 return;
774             }
776             /* Delete TX channel*/
777             status = mcbspDeleteChan(hMcbspTxChan);
778             if (MCBSP_STATUS_COMPLETED != status)
779             {
780                 MCBSP_log ("Debug(Core %d): Error: Delete Channel (TX) failed\n", coreNum);
781                 return;
782             }
783             /* Create a RX channel for receiving */
784             status = mcbspCreateChan(&hMcbspRxChan, hMcbspDev, MCBSP_MODE_INPUT, &mcbspChanparamRx, mcbspAppCallback, &rxChanMode);
785             if (MCBSP_STATUS_COMPLETED != status)
786             {
787                 MCBSP_log ("Debug(Core %d): Error: Create Channel (RX) failed\n", coreNum);
788                 return;
789             }
791             /* Create a TX channel for the transmission */
792             status = mcbspCreateChan(&hMcbspTxChan, hMcbspDev, MCBSP_MODE_OUTPUT, &mcbspChanparamTx, mcbspAppCallback, &txChanMode);
793             if (MCBSP_STATUS_COMPLETED != status)
794             {
795                 MCBSP_log ("Debug(Core %d): Error: Create Channel (TX) failed\n", coreNum);
796                 return;
797             }
798             edmaTxDone = 0;   /* Reset for next iteration */
799             edmaRxDone = 0;   /* Reset for next iteration */
800             mcbspTxDone = 0;  /* Reset for next iteration */
801             mcbspRxDone = 0;  /* Reset for next iteration */
802             goto restart_mcbsp_point;
804         default:
805             debugCommand=0;
806             break;
808         }
810     }
812     if ((errBuffCount == 0 ) & (retval ==0))
813     {
814         MCBSP_log("Debug(Core %d): MCBSP Digital Loopback Application completed successfully : "\
815             "Num iterations %d  Num buffers per iteration %d!!!\n",
816             coreNum, num_iterations, NUM_BUFS);
817         MCBSP_log("\n All tests have passed \n");
818     }
819     else
820     {
821         MCBSP_log("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         MCBSP_log ("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         MCBSP_log ("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     /* Get the core number. */
868     coreNum = 0; //CSL_chipReadReg (CSL_CHIP_DNUM);
870 #ifdef SIMULATOR_SUPPORT
871 #warn MCBSP Digital Loopback example is not supported on SIMULATOR !!!
872     MCBSP_log ("MCBSP Digital Loopback example is not supported on SIMULATOR. Exiting!\n");
873     return;
874 #else
875     MCBSP_log ("Debug(Core %d): Running MCBSP Digital Loopback example on the DEVICE\n", coreNum);
876 #endif
878     /* Initialize the system only if the core was configured to do so. */
879     if (coreNum == CORE_SYS_INIT)
880     {
881 #if 0
882         MCBSP_log ("Debug(Core %d): System Initialization for MCBSP\n", coreNum);
883         /* Read FPGA register */
884         if (0 != (platform_fpgaReadConfigReg(MCBSP_FPGA_MISC_REG_OFFSET, &uchReadValue)))
885         {
886             MCBSP_log ("Debug(Core %d): FPGA McBSP_AMC_EN# register READ failed \n", coreNum);
887             return;
888         }
889         /* Clear field for configuration */
890         uchValue = (uchReadValue & (~0x3));
891 #ifndef PLATFORM_FPGA_MCBSP_AMC_EN
892         uchValue |=  0x3;
893 #endif
894         /* Drive McBSP_AMC_EN# high. Output SLCLKs, TxCLKs, RxCLKs, FSTs, FSRs as Hi-Z. 
895          * These clocks and syncs are tri-stated and McBSP is accessed over 80-pin header */
896         if (0 != (platform_fpgaWriteConfigReg(MCBSP_FPGA_MISC_REG_OFFSET, (uchValue))))
897         {
898             MCBSP_log ("Debug(Core %d): FPGA McBSP_AMC_EN# register WRITE failed \n", coreNum);
899             return;
900         }
902         /* DEBUG: Verify if FPGA register is configured correctly */
903         if (0 != (platform_fpgaReadConfigReg(MCBSP_FPGA_MISC_REG_OFFSET, &uchReadValue)))
904         {
905             MCBSP_log ("Debug(Core %d): FPGA McBSP_AMC_EN# register READ failed \n", coreNum);
906             return;
907         }
909         if (uchValue != uchReadValue)
910         {
911             MCBSP_log ("Debug(Core %d): FPGA McBSP_AMC_EN# register setting failed \n", coreNum);
912             return;
913         }
914         else
915         {
916             MCBSP_log ("Debug(Core %d): FPGA McBSP_AMC_EN# register is set to %d \n", coreNum, uchValue);
917         }
918 #endif
919         /* MCBSP Driver Initialization: This should always be called before
920          * invoking the MCBSP Driver. */
921         mcbspInit();
923         /* Device Specific MCBSP Initializations */
924         McbspDevice_init();
925         
926         /* MCBSP Driver is operational at this time. */
927         MCBSP_log ("Debug(Core %d): MCBSP Driver Initialization Done\n", coreNum);
929         /* Write to the SHARED memory location at this point in time. The other cores cannot execute
930          * till the MCBSP Driver is up and running. */
931         isMCBSPInitialized[0] = 1;
933         /* The MCBSP IP block has been initialized. We need to writeback the cache here because it will
934          * ensure that the rest of the cores which are waiting for MCBSP to be initialized would now be
935          * woken up. */
936         //CACHE_wbL1d ((void *) &isMCBSPInitialized[0], MCBSP_MAX_CACHE_ALIGN, CACHE_FENCE_WAIT);
937         Cache_wb ((void *) &isMCBSPInitialized[0], MCBSP_CACHE_LENGTH,0x7fff, 1);
938     }
939     else
940     {
941         /* All other cores need to wait for the MCBSP to be initialized before they proceed with the test. */ 
942         MCBSP_log ("Debug(Core %d): Waiting for MCBSP to be initialized.\n", coreNum);
944         /* All other cores loop around forever till the MCBSP is up and running. 
945          * We need to invalidate the cache so that we always read this from the memory. */
946         while (isMCBSPInitialized[0] == 0)
947             //CACHE_invL1d ((void *) &isMCBSPInitialized[0], MCBSP_MAX_CACHE_ALIGN, CACHE_FENCE_WAIT);
948                 Cache_inv ((void *) &isMCBSPInitialized[0], MCBSP_CACHE_LENGTH, 0x7fff, 1);
951         MCBSP_log ("Debug(Core %d): MCBSP can now be used.\n", coreNum);
952     }
954     /* Initialize EDMA3 library */
955     hEdma[0] = edma3init(0, &edmaResult);
957     if (edmaResult != EDMA3_DRV_SOK)
958     {
959         /* Report EDMA Error */
960         MCBSP_log("Debug(Core %d): EDMA Driver Initialization FAILED\n", coreNum);
961     }
962     else
963     {
964         MCBSP_log("Debug(Core %d): EDMA Driver Initialization Done\n", coreNum);
965     }
967     /* Create the Digital Loopback Application Task */
968     Task_Params_init(&taskParams);
969     Task_create(mcbspDigLpbkApp, &taskParams, NULL);
971     /* Start BIOS */
972     BIOS_start();
974     return;
977 /* ========================================================================== */
978 /*                                END OF FILE                                 */
979 /* ========================================================================== */