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