888acbeb5269dbdafef05dda79bfa1c7c8eabcbc
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 /* ========================================================================== */
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 Board_STATUS Board_init(Board_initCfg);
87 extern void McbspXmtInterrupt_init(void *mcbspTxChan);
88 extern void McbspRcvInterrupt_init(void *mcbspRxChan);
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 =
173 {
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 333333333, //sys_oscclk or cpu_clk/3
179 0 /* frame sync pulse width (val+1) is used */
180 };
182 /**
183 * \brief Mcbsp device creation default parameters.
184 *
185 */
186 const Mcbsp_Params Mcbsp_PARAMS =
187 {
188 Mcbsp_DevMode_McBSP, /* Use the device as MCBSP */
189 Mcbsp_OpMode_DMAINTERRUPT, /* Use DMA mode of operation */
190 TRUE, /* cache coherency taken care of by driver */
191 Mcbsp_EmuMode_FREE, /* Emulation mode free is to be enabled */
192 #ifdef MCBSP_EXTERNAL_CLOCK
193 Mcbsp_Loopback_DISABLE, /* Loop back mode disabled */
194 #else
195 Mcbsp_Loopback_ENABLE, /* Loop back mode enabled */
196 #endif
197 &mcbspSrgCfg, /* sample rate generator configuration */
198 NULL, /* TX pending buffer queue from application */
199 NULL, /* TX floating buffer queue in DMA */
200 NULL, /* RX pending buffer queue from application */
201 NULL /* RX floating buffer queue in DMA */
202 };
204 #pragma DATA_ALIGN(loopTxJob, MCBSP_MAX_CACHE_ALIGN)
205 static Int32 loopTxJob[16] = {
206 /* Filling with Mu law silence pattern : Can be any user defined pattern */
207 0x7f7f7f7f, 0x7f7f7f7f, 0x7f7f7f7f, 0x7f7f7f7f, 0x7f7f7f7f, 0x7f7f7f7f, 0x7f7f7f7f, 0x7f7f7f7f,
208 0x7f7f7f7f, 0x7f7f7f7f, 0x7f7f7f7f, 0x7f7f7f7f, 0x7f7f7f7f, 0x7f7f7f7f, 0x7f7f7f7f, 0x7f7f7f7f
209 };
210 #pragma DATA_ALIGN(loopRxJob, MCBSP_MAX_CACHE_ALIGN)
211 static Int32 loopRxJob[16] = {
212 0, 0, 0, 0, 0, 0, 0, 0,
213 0, 0, 0, 0, 0, 0, 0, 0
214 };
216 /**< settings to configure the TX or RX hardware sections */
217 Mcbsp_DataConfig mcbspChanConfigTx =
218 {
219 Mcbsp_Phase_SINGLE,
220 Mcbsp_WordLength_8,
221 Mcbsp_WordLength_8, /* Dont care for single phase*/
222 NUM_OF_MAX_CHANNELS,
223 NUM_OF_MAX_CHANNELS, // Only used with dual phase
224 Mcbsp_FrmSync_DETECT,
225 #ifdef MCBSP_EXTERNAL_CLOCK
226 Mcbsp_DataDelay_0_BIT,
227 #else
228 Mcbsp_DataDelay_1_BIT,
229 #endif
230 Mcbsp_Compand_OFF_MSB_FIRST,
231 Mcbsp_BitReversal_DISABLE,
232 Mcbsp_IntMode_ON_SYNCERR,
233 Mcbsp_RxJust_RZF, /* Dont care for TX */
234 Mcbsp_DxEna_OFF
235 };
237 /**< settings to configure the TX or RX hardware sections */
238 Mcbsp_DataConfig mcbspChanConfigRx =
239 {
240 Mcbsp_Phase_SINGLE,
241 Mcbsp_WordLength_8,
242 Mcbsp_WordLength_8, /* Dont care for single phase*/
243 NUM_OF_MAX_CHANNELS,
244 NUM_OF_MAX_CHANNELS, // Only used with dual phase
245 Mcbsp_FrmSync_DETECT,
246 #ifdef MCBSP_EXTERNAL_CLOCK
247 Mcbsp_DataDelay_0_BIT,
248 #else
249 Mcbsp_DataDelay_1_BIT,
250 #endif
251 Mcbsp_Compand_OFF_MSB_FIRST,
252 Mcbsp_BitReversal_DISABLE,
253 Mcbsp_IntMode_ON_SYNCERR,
254 Mcbsp_RxJust_RZF, /* Dont care for TX */
255 Mcbsp_DxEna_OFF
256 };
257 /**< clock setup for the TX section */
258 Mcbsp_ClkSetup mcbspClkConfigTx =
259 {
260 #ifdef MCBSP_EXTERNAL_CLOCK
261 Mcbsp_FsClkMode_EXTERNAL,
262 8000, /* 8KHz */
263 Mcbsp_TxRxClkMode_EXTERNAL,
264 #else
265 Mcbsp_FsClkMode_INTERNAL,
266 8000, /* 8KHz */
267 Mcbsp_TxRxClkMode_INTERNAL,
268 #endif
269 Mcbsp_FsPol_ACTIVE_HIGH,
270 Mcbsp_ClkPol_RISING_EDGE
271 };
273 /**< clock setup for the RX section */
274 Mcbsp_ClkSetup mcbspClkConfigRx =
275 {
276 #ifdef MCBSP_EXTERNAL_CLOCK
277 Mcbsp_FsClkMode_EXTERNAL,
278 8000, /* 8KHz */
279 Mcbsp_TxRxClkMode_EXTERNAL,
280 #else
281 Mcbsp_FsClkMode_INTERNAL,
282 8000, /* 8KHz */
283 Mcbsp_TxRxClkMode_INTERNAL,
284 #endif
285 Mcbsp_FsPol_ACTIVE_HIGH,
286 Mcbsp_ClkPol_FALLING_EDGE
287 };
289 /**< Multi channel setup */
290 Mcbsp_McrSetup mcbspMultiChanCtrl =
291 {
292 Mcbsp_McmMode_ALL_CHAN_DISABLED_UNMASKED,
293 Mcbsp_PartitionMode_CHAN_0_15,
294 Mcbsp_PartitionMode_CHAN_16_31,
295 Mcbsp_PartitionMode_2
296 };
299 Mcbsp_ChanParams mcbspChanparamTx =
300 {
301 Mcbsp_WordLength_8, /* wordlength configured */
302 &loopTxJob[0], /* loop job buffer internal */
303 8, /* user loopjob length */
304 mcbsp_GblErrCallback, /* global error callback */
305 NULL, /* edma Handle */
306 1, /* EDMA event queue */
307 8, /* hwi number */
308 Mcbsp_BufferFormat_MULTISLOT_NON_INTERLEAVED,
309 TRUE, /* FIFO mode enabled */
310 &mcbspChanConfigTx, /* channel configuration */
311 &mcbspClkConfigTx, /* clock configuration */
312 &mcbspMultiChanCtrl, /* multi channel control */
313 0x7531, /* Enabled timeslots: 0, 4, 5, 8, 10, 12, 13, 14 */
314 0x00,
315 0x00,
316 0x00,
317 NUM_OF_ENABLED_CHANNELS /* Total number of channels enabled*/
318 };
320 Mcbsp_ChanParams mcbspChanparamRx =
321 {
322 Mcbsp_WordLength_8, /* wordlength configured */
323 &loopRxJob[0], /* loop job buffer internal */
324 8, /* user loopjob length */
325 mcbsp_GblErrCallback, /* global error callback */
326 NULL, /* edma Handle */
327 1, /* EDMA event queue */
328 8, /* hwi number */
329 Mcbsp_BufferFormat_MULTISLOT_NON_INTERLEAVED,
330 TRUE, /* FIFO mode enabled */
331 &mcbspChanConfigRx, /* channel configuration */
332 &mcbspClkConfigRx, /* clock configuration */
333 &mcbspMultiChanCtrl, /* multi channel control */
334 0x7531, /* Enabled timeslots: 0, 4, 5, 8, 10, 12, 13, 14 */
335 0x00,
336 0x00,
337 0x00,
338 NUM_OF_ENABLED_CHANNELS /* Total number of channels enabled*/
339 };
342 /* ========================================================================== */
343 /* FUNCTION DEFINITIONS */
344 /* ========================================================================== */
346 /*
347 * This is the application's callback function. The driver will
348 * call this function whenever an EDMA I/O operation is over.
349 *
350 */
351 void mcbspAppCallback(void* arg, Mcbsp_IOBuf *ioBuf)
352 {
353 int32_t mode;
354 int32_t *pmode = (int32_t *)arg;
356 mode = *pmode;
357 if (mode == MCBSP_MODE_OUTPUT)
358 {
359 if(ioBuf) {
360 num_tx_Call_backs++;
361 edmaTxDone = 1;
362 }else
363 txunderflowcnt++;
364 }
365 else if (mode == MCBSP_MODE_INPUT)
366 {
367 if(ioBuf) {
368 num_rx_Call_backs++;
369 edmaRxDone = 1;
370 }else
371 rxunderflowcnt++;
372 }else
373 dummy_call_backs++;
374 return;
375 }
377 /*
378 * This is the application's Global error callback function
379 */
380 void mcbsp_GblErrCallback(uint32_t chanHandle,uint32_t spcr_read,uint32_t Arg3)
381 {
382 System_printf ("Debug(Core %d): ERROR callback called SPCR: %x", coreNum, spcr_read);
383 }
385 /*
386 * \brief This function demostrates the use of Mcbsp using digital loopback
387 * communication setup.
388 *
389 * \param None
390 *
391 * \return None
392 */
393 void mcbspDigLpbkApp(UArg arg0, UArg arg1)
394 {
395 /**< Mcbsp device params */
396 Mcbsp_Params mcbspParams;
398 /**< Queue to hold the pending packets received from the application */
399 Queue_Struct txQueuePendingList, rxQueuePendingList;
400 /**< Queue to manage floating packets in DMA */
401 Queue_Struct txQueueFloatingList, rxQueueFloatingList;
403 uint32_t count = 0, tempCount = 0;
404 int32_t status = 0, retval = 0;
405 int32_t txChanMode = MCBSP_MODE_OUTPUT;
406 int32_t rxChanMode = MCBSP_MODE_INPUT;
407 uint32_t mcbspTxDone = 0, mcbspRxDone = 0;
408 Mcbsp_IOBuf txFrame[NUM_OF_MCBSP_FRAMES], rxFrame[NUM_OF_MCBSP_FRAMES];
409 int txFrameIndex=0, rxFrameIndex=0;
410 int init_count=0;
411 #ifdef MCBSP_LOOP_PING_PONG
412 int pingPongIndex=0;
413 #endif
415 /* Initialize the OSAL */
416 if (Osal_dataBufferInitMemory(BUFSIZE) < 0)
417 {
418 System_printf ("Debug(Core %d): Error: Unable to initialize the OSAL. \n", coreNum);
419 return;
420 }
422 /* update EDMA3 handle to channel parameters */
423 mcbspChanparamTx.edmaHandle = hEdma[0];
424 mcbspChanparamRx.edmaHandle = hEdma[0];
426 /* create the pending and floating queue for the TX channel */
427 Queue_construct(&txQueuePendingList, NULL);
428 Queue_construct(&txQueueFloatingList, NULL);
430 /* create the pending and floating queue for the RX channel */
431 Queue_construct(&rxQueuePendingList, NULL);
432 Queue_construct(&rxQueueFloatingList, NULL);
435 mcbspParams = Mcbsp_PARAMS;
436 mcbspParams.txQPendingList = &txQueuePendingList;
437 mcbspParams.txQFloatingList = &txQueueFloatingList;
438 mcbspParams.rxQPendingList = &rxQueuePendingList;
439 mcbspParams.rxQFloatingList = &rxQueueFloatingList;
442 /* Bind the driver instance with device instance */
443 status = mcbspBindDev(&hMcbspDev, coreNum, &mcbspParams);
445 if (status != MCBSP_STATUS_COMPLETED)
446 {
447 System_printf ("Debug(Core %d): MCBSP LLD Bind Device Failed\n", coreNum);
448 return;
449 }
451 /* If the user loopjob buffer is in local L2 memory: Convert into Global memory address space */
452 if(mcbspChanparamRx.userLoopJobBuffer)
453 mcbspChanparamRx.userLoopJobBuffer = (void *)Mcbsp_osalLocal2Global(mcbspChanparamRx.userLoopJobBuffer);
455 /* Create a RX channel for receiving */
456 status = mcbspCreateChan(&hMcbspRxChan, hMcbspDev, MCBSP_MODE_INPUT, &mcbspChanparamRx, mcbspAppCallback, &rxChanMode);
457 if (MCBSP_STATUS_COMPLETED != status)
458 {
459 System_printf ("Debug(Core %d): Error: Create Channel (RX) failed\n", coreNum);
460 return;
461 }
463 /* If the user loopjob buffer is in local L2 memory: Convert into Global memory address space */
464 if(mcbspChanparamTx.userLoopJobBuffer)
465 mcbspChanparamTx.userLoopJobBuffer = Mcbsp_osalLocal2Global(mcbspChanparamTx.userLoopJobBuffer);
467 /* Create a TX channel for the transmission */
468 status = mcbspCreateChan(&hMcbspTxChan, hMcbspDev, MCBSP_MODE_OUTPUT, &mcbspChanparamTx, mcbspAppCallback, &txChanMode);
469 if (MCBSP_STATUS_COMPLETED != status)
470 {
471 System_printf ("Debug(Core %d): Error: Create Channel (TX) failed\n", coreNum);
472 return;
473 }
475 /* Register mcbsp interrupts */
476 //McbspRcvInterrupt_init(hMcbspRxChan);
477 //McbspXmtInterrupt_init(hMcbspTxChan);
479 /* create the buffers required for the TX and RX operations */
480 for (count = 0; count < (NUM_BUFS); count++)
481 {
482 bufTx[count] = (uint8_t *)Osal_mcbspDataBufferMalloc(BUFSIZE);
483 bufRx[count] = (uint8_t *)Osal_mcbspDataBufferMalloc(BUFSIZE);
485 if (bufTx[count] == NULL)
486 {
487 System_printf ("Debug(Core %d): Error: Tx Buffer (%d) Memory Allocation Failed\n", coreNum, count);
488 return;
489 }
490 if (bufRx[count] == NULL)
491 {
492 System_printf ("Debug(Core %d): Error: Rx Buffer (%d) Memory Allocation Failed\n", coreNum, count);
493 return;
494 }
495 }
496 #ifdef MCBSP_LOOP_PING_PONG
497 /* create the ping pong buffers required for the TX and RX operations */
498 for (count = 0; count < (NUM_BUFS); count++)
499 {
500 bufRxPingPong[count] = (uint8_t *)Osal_mcbspDataBufferMalloc(BUFSIZE);
501 bufTxPingPong[count] = (uint8_t *)Osal_mcbspDataBufferMalloc(BUFSIZE);
503 if (bufTxPingPong[count] == NULL)
504 {
505 System_printf ("Debug(Core %d): Error: Tx Ping pong Buffer (%d) Memory Allocation Failed\n", coreNum, count);
506 return;
507 }
508 if (bufRxPingPong[count] == NULL)
509 {
510 System_printf ("Debug(Core %d): Error: Rx Ping pong Buffer (%d) Memory Allocation Failed\n", coreNum, count);
511 return;
512 }
513 }
514 #endif
515 /* Fill the buffers with known data and transmit the same and
516 check if the same pattern is received */
517 for (count = 0; count < (NUM_BUFS); count++)
518 {
519 memset((uint8_t *)bufTx[count], 0, BUFSIZE);
520 for (tempCount = 0; tempCount < BUFSIZE; tempCount++)
521 {
522 ((uint8_t *)bufTx[count])[tempCount] = (tempCount % 0x100);
523 }
524 }
525 System_printf ("Debug(Core %d): If required to restart set debugCommand variable to %d\n", coreNum, DEBUG_COMMAND_RESTART_CHANNELS);
527 restart_mcbsp_point:
528 txFrameIndex=0;
529 rxFrameIndex=0;
530 init_count=0;
531 #ifdef MCBSP_EXTERNAL_CLOCK
532 /* Initial loading of ping ping buffers */
533 for(init_count =0 ; init_count < INIT_SUBMIT_Q_CNT; init_count++)
534 {
535 #ifdef MCBSP_LOOP_PING_PONG
536 memset((uint8_t *)bufRxPingPong[init_count], 0, BUFSIZE);
538 /* RX frame processing */
539 rxFrame[rxFrameIndex].cmd = Mcbsp_IOBuf_Cmd_READ;
540 rxFrame[rxFrameIndex].addr = (void*)bufRxPingPong[init_count];
541 #else
542 memset((uint8_t *)bufRx[init_count], 0, BUFSIZE);
545 /* RX frame processing */
546 rxFrame[rxFrameIndex].cmd = Mcbsp_IOBuf_Cmd_READ;
547 rxFrame[rxFrameIndex].addr = (void*)bufRx[init_count];
548 #endif
550 rxFrame[rxFrameIndex].size = BUFSIZE;
551 rxFrame[rxFrameIndex].arg = (uint32_t) hMcbspRxChan;
552 rxFrame[rxFrameIndex].status = MCBSP_STATUS_COMPLETED;
553 rxFrame[rxFrameIndex].misc = 1; /* reserved - used in callback to indicate asynch packet */
555 status = mcbspSubmitChan(hMcbspRxChan, (void *)&rxFrame[rxFrameIndex]);
556 if (status != MCBSP_STATUS_PENDING)
557 {
558 System_printf ("Debug(Core %d): Error: RX buffer #%d submission FAILED\n", coreNum, init_count);
559 retval = 1;
560 }
561 else
562 {
563 #ifdef MCBSP_APP_VERBOSE
564 System_printf ("Debug(Core %d): RX buffer #%d is submitted to MCBSP driver\n", coreNum, init_count);
565 #endif
566 }
567 rxFrameIndex++;
568 rxFrameIndex = (rxFrameIndex >= (NUM_OF_MCBSP_FRAMES)) ? 0 : rxFrameIndex;
570 rxSubmitCount++;
572 /* TX frame processing */
573 txFrame[txFrameIndex].cmd = Mcbsp_IOBuf_Cmd_WRITE;
574 #ifdef MCBSP_LOOP_PING_PONG
575 txFrame[txFrameIndex].addr = (void*)bufTxPingPong[init_count];
576 #else
577 txFrame[txFrameIndex].addr = (void*)bufTx[init_count];
578 #endif
579 txFrame[txFrameIndex].size = BUFSIZE;
580 txFrame[txFrameIndex].arg = (uint32_t)hMcbspTxChan;
581 txFrame[txFrameIndex].status = MCBSP_STATUS_COMPLETED;
582 txFrame[txFrameIndex].misc = 1; /* reserved - used in callback to indicate asynch packet */
584 status = mcbspSubmitChan(hMcbspTxChan, (void *)&txFrame[txFrameIndex]);
585 if (status != MCBSP_STATUS_PENDING)
586 {
587 System_printf ("Debug(Core %d): Error: TX buffer #%d submission FAILED\n", coreNum, init_count);
588 retval = 1;
589 }
590 else
591 {
592 #ifdef MCBSP_APP_VERBOSE
593 System_printf ("Debug(Core %d): TX buffer #%d submission is submitted to MCBSP driver\n", coreNum, init_count);
594 #endif
595 }
596 txFrameIndex++;
597 txFrameIndex = (txFrameIndex >=(NUM_OF_MCBSP_FRAMES)) ? 0 : txFrameIndex;
599 txSubmitCount++;
600 }
602 /* Wait for TX and RX processing to complete */
603 while (1)
604 {
605 if (edmaTxDone == 1)
606 {
607 #ifdef MCBSP_APP_VERBOSE
608 System_printf ("Debug(Core %d): EDMA -> Iteration-%d frames are transmitted to TX path\n", coreNum, count);
609 #endif
610 edmaTxDone = 0; /* Reset for next iteration */
611 mcbspTxDone = 1;
612 }
613 if (edmaRxDone == 1)
614 {
615 #ifdef MCBSP_APP_VERBOSE
616 System_printf ("Debug(Core %d): EDMA -> Iteration-%d frames are received from RX path\n", coreNum, count);
617 #endif
618 edmaRxDone = 0; /* Reset for next iteration */
619 mcbspRxDone = 1;
620 }
621 if ((mcbspTxDone == 1) && (mcbspRxDone == 1))
622 {
623 mcbspTxDone = 0; /* Reset for next iteration */
624 mcbspRxDone = 0; /* Reset for next iteration */
625 break;
626 }
627 }
628 #ifdef MCBSP_LOOP_PING_PONG
629 /* Change ping Pong Index */
630 init_count=0;
631 #endif
632 #endif /* MCBSP_EXTERNAL_CLOCK */
634 /* Start main loop to iterate through frames */
635 while(debugVar)
636 {
637 /* submit frames to the driver */
638 for (count = init_count; count < NUM_BUFS; count++)
639 {
640 #ifdef MCBSP_EXTERNAL_CLOCK
641 /* With External clock the data coming from the RX side is copied to loop back to the Tx side */
642 memcpy((uint8_t *)bufTx[count], (uint8_t *)bufRx[count], BUFSIZE);
643 #endif
644 #ifdef MCBSP_LOOP_PING_PONG
645 memset((uint8_t *)bufRxPingPong[pingPongIndex], 0, BUFSIZE);
646 #else
647 memset((uint8_t *)bufRx[count], 0, BUFSIZE);
648 /* RX frame processing */
649 rxFrame[rxFrameIndex].cmd = Mcbsp_IOBuf_Cmd_READ;
650 rxFrame[rxFrameIndex].addr = (void*)getGlobalAddr(bufRx[count]);
651 rxFrame[rxFrameIndex].size = BUFSIZE;
652 rxFrame[rxFrameIndex].arg = (uint32_t) hMcbspRxChan;
653 rxFrame[rxFrameIndex].status = MCBSP_STATUS_COMPLETED;
654 rxFrame[rxFrameIndex].misc = 1; /* reserved - used in callback to indicate asynch packet */
656 status = mcbspSubmitChan(hMcbspRxChan, (void *)&rxFrame[rxFrameIndex]);
657 if (status != MCBSP_STATUS_PENDING)
658 {
659 System_printf ("Debug(Core %d): Error: RX buffer #%d submission FAILED\n", coreNum, count);
660 retval = 1;
661 }
662 else
663 {
664 #ifdef MCBSP_APP_VERBOSE
665 System_printf ("Debug(Core %d): RX buffer #%d is submitted to MCBSP driver\n", coreNum, count);
666 #endif
667 }
668 rxFrameIndex++;
669 rxFrameIndex = (rxFrameIndex >= (NUM_OF_MCBSP_FRAMES)) ? 0 : rxFrameIndex;
670 #endif
671 rxSubmitCount++;
672 #ifdef MCBSP_LOOP_PING_PONG
673 /* Copy buffer from buffer to ping pong buffer*/
674 memcpy((uint8_t *)bufTxPingPong[pingPongIndex], (uint8_t *)bufTx[count],BUFSIZE);
675 #else
676 /* TX frame processing */
677 txFrame[txFrameIndex].cmd = Mcbsp_IOBuf_Cmd_WRITE;
678 txFrame[txFrameIndex].addr = (void*)getGlobalAddr(bufTx[count]);
679 txFrame[txFrameIndex].size = BUFSIZE;
680 txFrame[txFrameIndex].arg = (uint32_t)hMcbspTxChan;
681 txFrame[txFrameIndex].status = MCBSP_STATUS_COMPLETED;
682 txFrame[txFrameIndex].misc = 1; /* reserved - used in callback to indicate asynch packet */
684 status = mcbspSubmitChan(hMcbspTxChan, (void *)&txFrame[txFrameIndex]);
685 if (status != MCBSP_STATUS_PENDING)
686 {
687 System_printf ("Debug(Core %d): Error: TX buffer #%d submission FAILED\n", coreNum, count);
688 retval = 1;
689 }
690 else
691 {
692 #ifdef MCBSP_APP_VERBOSE
693 System_printf ("Debug(Core %d): TX buffer #%d is submitted to MCBSP driver\n", coreNum, count);
694 #endif
695 }
696 txFrameIndex++;
697 txFrameIndex = (txFrameIndex >= (NUM_OF_MCBSP_FRAMES)) ? 0 : txFrameIndex;
698 #endif
699 txSubmitCount++;
701 /* Wait for TX and RX processing to complete */
702 while (1)
703 {
704 if (edmaTxDone == 1)
705 {
706 #ifdef MCBSP_APP_VERBOSE
707 System_printf ("Debug(Core %d): EDMA -> Buffer #-%d is transmitted to TX path\n", coreNum, count);
708 #endif
709 edmaTxDone = 0; /* Reset for next iteration */
710 mcbspTxDone = 1;
711 }
712 if (edmaRxDone == 1)
713 {
714 #ifdef MCBSP_APP_VERBOSE
715 System_printf ("Debug(Core %d): EDMA -> Buffer #-%d is received from RX path\n", coreNum, count);
716 #endif
717 edmaRxDone = 0; /* Reset for next iteration */
718 mcbspRxDone = 1;
719 }
720 if ((mcbspTxDone == 1) && (mcbspRxDone == 1))
721 {
722 mcbspTxDone = 0; /* Reset for next iteration */
723 mcbspRxDone = 0; /* Reset for next iteration */
724 break;
725 }
726 }
727 #ifdef MCBSP_LOOP_PING_PONG
728 /* Change ping Pong Index */
729 pingPongIndex=(pingPongIndex)?0:1;
731 /* Copy buffer from buffer to other buffer*/
732 memcpy((void*)bufRx[count], (uint8_t *)bufRxPingPong[pingPongIndex],BUFSIZE);
733 #endif
734 /* compare buffer contents */
735 for (tempCount = 0; tempCount < BUFSIZE; tempCount++)
736 {
737 if (((char *)bufTx[count])[tempCount] != ((char *)bufRx[count])[tempCount])
738 {
739 #ifdef MCBSP_APP_VERBOSE
740 System_printf("Debug(Core %d): Error: TX and RX frame data DOES NOT match in Buffer #-%d\n",
741 coreNum, count);
742 System_printf("Debug(Core %d): Error: Buffer index = %d, Tx data = %d, Rx data = %d\n", coreNum,
743 tempCount, ((char *)bufTx[count])[tempCount], ((char *)bufRx[count])[tempCount]);
744 #endif
745 errBuffCount++;
746 break;
747 }
748 }
749 if (tempCount >= BUFSIZE)
750 {
751 #ifdef MCBSP_APP_VERBOSE
752 System_printf("Debug(Core %d): TX and RX frames data match in iteration-%d !!!\n", coreNum, count);
753 #endif
754 }
755 }
756 init_count=0;
757 num_iterations++;
758 #ifndef MCBSP_EXTERNAL_CLOCK
759 if(num_iterations >= NUM_OF_ITERATIONS)
760 break;
761 #endif
762 switch(debugCommand)
763 {
764 case DEBUG_COMMAND_RESTART_CHANNELS:
765 debugCommand=0;
766 /* Close channel and reopen */
767 /* Delete RX channel */
768 status = mcbspDeleteChan(hMcbspRxChan);
769 if (MCBSP_STATUS_COMPLETED != status)
770 {
771 System_printf ("Debug(Core %d): Error: Delete Channel (RX) failed\n", coreNum);
772 return;
773 }
775 /* Delete TX channel*/
776 status = mcbspDeleteChan(hMcbspTxChan);
777 if (MCBSP_STATUS_COMPLETED != status)
778 {
779 System_printf ("Debug(Core %d): Error: Delete Channel (TX) failed\n", coreNum);
780 return;
781 }
782 /* Create a RX channel for receiving */
783 status = mcbspCreateChan(&hMcbspRxChan, hMcbspDev, MCBSP_MODE_INPUT, &mcbspChanparamRx, mcbspAppCallback, &rxChanMode);
784 if (MCBSP_STATUS_COMPLETED != status)
785 {
786 System_printf ("Debug(Core %d): Error: Create Channel (RX) failed\n", coreNum);
787 return;
788 }
790 /* Create a TX channel for the transmission */
791 status = mcbspCreateChan(&hMcbspTxChan, hMcbspDev, MCBSP_MODE_OUTPUT, &mcbspChanparamTx, mcbspAppCallback, &txChanMode);
792 if (MCBSP_STATUS_COMPLETED != status)
793 {
794 System_printf ("Debug(Core %d): Error: Create Channel (TX) failed\n", coreNum);
795 return;
796 }
797 edmaTxDone = 0; /* Reset for next iteration */
798 edmaRxDone = 0; /* Reset for next iteration */
799 mcbspTxDone = 0; /* Reset for next iteration */
800 mcbspRxDone = 0; /* Reset for next iteration */
801 goto restart_mcbsp_point;
803 default:
804 debugCommand=0;
805 break;
807 }
809 }
811 if ((errBuffCount == 0 ) & (retval ==0))
812 {
813 System_printf("Debug(Core %d): MCBSP Digital Loopback Application completed successfully : "\
814 "Num iterations %d Num buffers per iteration %d!!!\n",
815 coreNum, num_iterations, NUM_BUFS);
816 }
817 else
818 {
819 System_printf("Debug(Core %d): MCBSP Digital Loopback application FAILED : "\
820 "Num iterations %d Num buffers per iteration %d Failed buffers %d!!!\n",
821 coreNum, num_iterations, NUM_BUFS, errBuffCount);
822 }
824 /* Delete RX channel */
825 status = mcbspDeleteChan(hMcbspRxChan);
826 if (MCBSP_STATUS_COMPLETED != status)
827 {
828 System_printf ("Debug(Core %d): Error: Delete Channel (RX) failed\n", coreNum);
829 return;
830 }
832 /* Delete TX channel*/
833 status = mcbspDeleteChan(hMcbspTxChan);
834 if (MCBSP_STATUS_COMPLETED != status)
835 {
836 System_printf ("Debug(Core %d): Error: Delete Channel (TX) failed\n", coreNum);
837 return;
838 }
839 return;
840 }
842 /*
843 * \brief Void main(Void)
844 *
845 * Main function of the sample application. This function calls the
846 * function to configure the mcbsp instance.
847 *
848 * \param None
849 *
850 * \return None
851 */
852 #include "ti/sysbios/hal/Cache.h"
854 Void main(Void)
855 {
856 Task_Params taskParams;
857 EDMA3_DRV_Result edmaResult = 0;
858 #ifdef SIMULATOR_SUPPORT
859 uint8_t uchValue, uchReadValue;
860 #endif
862 Board_initCfg arg = BOARD_INIT_MODULE_CLOCK | BOARD_INIT_PINMUX_CONFIG | BOARD_INIT_UART_STDIO;
863 Board_init(arg);
865 /* Get the core number. */
866 coreNum = 0; //CSL_chipReadReg (CSL_CHIP_DNUM);
868 #ifdef SIMULATOR_SUPPORT
869 #warn MCBSP Digital Loopback example is not supported on SIMULATOR !!!
870 System_printf ("MCBSP Digital Loopback example is not supported on SIMULATOR. Exiting!\n");
871 return;
872 #else
873 System_printf ("Debug(Core %d): Running MCBSP Digital Loopback example on the DEVICE\n", coreNum);
874 #endif
876 /* Initialize the system only if the core was configured to do so. */
877 if (coreNum == CORE_SYS_INIT)
878 {
879 #if 0
880 System_printf ("Debug(Core %d): System Initialization for MCBSP\n", coreNum);
881 /* Read FPGA register */
882 if (0 != (platform_fpgaReadConfigReg(MCBSP_FPGA_MISC_REG_OFFSET, &uchReadValue)))
883 {
884 System_printf ("Debug(Core %d): FPGA McBSP_AMC_EN# register READ failed \n", coreNum);
885 return;
886 }
887 /* Clear field for configuration */
888 uchValue = (uchReadValue & (~0x3));
889 #ifndef PLATFORM_FPGA_MCBSP_AMC_EN
890 uchValue |= 0x3;
891 #endif
892 /* Drive McBSP_AMC_EN# high. Output SLCLKs, TxCLKs, RxCLKs, FSTs, FSRs as Hi-Z.
893 * These clocks and syncs are tri-stated and McBSP is accessed over 80-pin header */
894 if (0 != (platform_fpgaWriteConfigReg(MCBSP_FPGA_MISC_REG_OFFSET, (uchValue))))
895 {
896 System_printf ("Debug(Core %d): FPGA McBSP_AMC_EN# register WRITE failed \n", coreNum);
897 return;
898 }
900 /* DEBUG: Verify if FPGA register is configured correctly */
901 if (0 != (platform_fpgaReadConfigReg(MCBSP_FPGA_MISC_REG_OFFSET, &uchReadValue)))
902 {
903 System_printf ("Debug(Core %d): FPGA McBSP_AMC_EN# register READ failed \n", coreNum);
904 return;
905 }
907 if (uchValue != uchReadValue)
908 {
909 System_printf ("Debug(Core %d): FPGA McBSP_AMC_EN# register setting failed \n", coreNum);
910 return;
911 }
912 else
913 {
914 System_printf ("Debug(Core %d): FPGA McBSP_AMC_EN# register is set to %d \n", coreNum, uchValue);
915 }
916 #endif
917 /* MCBSP Driver Initialization: This should always be called before
918 * invoking the MCBSP Driver. */
919 mcbspInit();
921 /* Device Specific MCBSP Initializations */
922 McbspDevice_init();
924 /* MCBSP Driver is operational at this time. */
925 System_printf ("Debug(Core %d): MCBSP Driver Initialization Done\n", coreNum);
927 /* Write to the SHARED memory location at this point in time. The other cores cannot execute
928 * till the MCBSP Driver is up and running. */
929 isMCBSPInitialized[0] = 1;
931 /* The MCBSP IP block has been initialized. We need to writeback the cache here because it will
932 * ensure that the rest of the cores which are waiting for MCBSP to be initialized would now be
933 * woken up. */
934 //CACHE_wbL1d ((void *) &isMCBSPInitialized[0], MCBSP_MAX_CACHE_ALIGN, CACHE_FENCE_WAIT);
935 Cache_wb ((void *) &isMCBSPInitialized[0], MCBSP_CACHE_LENGTH,0x7fff, 1);
936 }
937 else
938 {
939 /* All other cores need to wait for the MCBSP to be initialized before they proceed with the test. */
940 System_printf ("Debug(Core %d): Waiting for MCBSP to be initialized.\n", coreNum);
942 /* All other cores loop around forever till the MCBSP is up and running.
943 * We need to invalidate the cache so that we always read this from the memory. */
944 while (isMCBSPInitialized[0] == 0)
945 //CACHE_invL1d ((void *) &isMCBSPInitialized[0], MCBSP_MAX_CACHE_ALIGN, CACHE_FENCE_WAIT);
946 Cache_inv ((void *) &isMCBSPInitialized[0], MCBSP_CACHE_LENGTH, 0x7fff, 1);
949 System_printf ("Debug(Core %d): MCBSP can now be used.\n", coreNum);
950 }
952 /* Initialize EDMA3 library */
953 hEdma[0] = edma3init(0, &edmaResult);
955 if (edmaResult != EDMA3_DRV_SOK)
956 {
957 /* Report EDMA Error */
958 System_printf("Debug(Core %d): EDMA Driver Initialization FAILED\n", coreNum);
959 }
960 else
961 {
962 System_printf("Debug(Core %d): EDMA Driver Initialization Done\n", coreNum);
963 }
965 /* Create the Digital Loopback Application Task */
966 Task_Params_init(&taskParams);
967 Task_create(mcbspDigLpbkApp, &taskParams, NULL);
969 /* Start BIOS */
970 BIOS_start();
972 return;
973 }
975 /* ========================================================================== */
976 /* END OF FILE */
977 /* ========================================================================== */