]> Gitweb @ Texas Instruments - Open Source Git Repositories - git.TI.com/gitweb - processor-sdk/pdk.git/blob - packages/ti/board/diag/mcan/src/mcan_test.c
board-rtos: add to PDK
[processor-sdk/pdk.git] / packages / ti / board / diag / mcan / src / mcan_test.c
1 /******************************************************************************
2  * Copyright (c) 2018-2019 Texas Instruments Incorporated - http://www.ti.com
3  *
4  *  Redistribution and use in source and binary forms, with or without
5  *  modification, are permitted provided that the following conditions
6  *  are met:
7  *
8  *    Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  *
11  *    Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the
14  *    distribution.
15  *
16  *    Neither the name of Texas Instruments Incorporated nor the names of
17  *    its contributors may be used to endorse or promote products derived
18  *    from this software without specific prior written permission.
19  *
20  *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21  *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22  *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23  *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24  *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25  *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26  *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27  *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28  *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29  *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30  *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31  *
32  *****************************************************************************/
34 /**
35  *  \file     mcan_test.c
36  *
37  *  \brief    This file contains MCAN sample code.
38  *
39  *  Targeted Functionality: Verifying the transmit and receive functionality
40  *    of MCAN module.
41  *
42  *  Operation: MCAN operational mode is set to CAN-FD. This test will need
43  *  two MCAN ports.
44  *
45  *  Supported SoCs: AM65XX & J721E.
46  *
47  *  Supported Platforms: am65xx_idk & j721e_evm.
48  *
49  */
51 #include "mcan_test.h"
53 MCAN_TxBufElement  txMsg;
54 MCAN_RxBufElement  rxMsg;
56 volatile uint32_t gMcanIsrIntr0Flag = 1U;
57 volatile uint32_t gMcanIsrIntr1Flag = 1U;
59 uint32_t expBoardDetect = 0;
60 uint32_t mcanMaxPorts   = 0;
62 #if defined(am65xx_idk)
63 mcanDiagportInfo  gmcanDiagportInfo[MCAN_MAX_PORTS] = {{CSL_MCU_MCAN0_MSGMEM_RAM_BASE, 0, CSL_GIC0_INTR_MCU_MCAN0_BUS_MCANSS_MCAN_LVL_INT_0, CSL_GIC0_INTR_MCU_MCAN0_BUS_MCANSS_MCAN_LVL_INT_1, CSL_GIC0_INTR_MCU_MCAN0_BUS_MCANSS_EXT_TS_ROLLOVER_LVL_INT}, 
64                                                        {CSL_MCU_MCAN1_MSGMEM_RAM_BASE, 1, CSL_GIC0_INTR_MCU_MCAN1_BUS_MCANSS_MCAN_LVL_INT_0, CSL_GIC0_INTR_MCU_MCAN1_BUS_MCANSS_MCAN_LVL_INT_1, CSL_GIC0_INTR_MCU_MCAN1_BUS_MCANSS_EXT_TS_ROLLOVER_LVL_INT},
65                                                       };
66 #else
67 mcanDiagportInfo  gmcanDiagportInfo[MCAN_MAX_PORTS_EXP] = {{CSL_MCU_MCAN0_MSGMEM_RAM_BASE, 0, MCU_MCAN0_TX_INT_NUM,  MCU_MCAN0_RX_INT_NUM,  MCU_MCAN0_TS_INT_NUM},
68                                                        {CSL_MCU_MCAN1_MSGMEM_RAM_BASE, 1, MCU_MCAN1_TX_INT_NUM,  MCU_MCAN1_RX_INT_NUM,  MCU_MCAN1_TS_INT_NUM},
69                                                        {CSL_MCAN0_MSGMEM_RAM_BASE,     0, MAIN_MCAN0_TX_INT_NUM, MAIN_MCAN0_RX_INT_NUM, MAIN_MCAN0_TS_INT_NUM},
70                                                        {CSL_MCAN2_MSGMEM_RAM_BASE,     2, MAIN_MCAN2_TX_INT_NUM, MAIN_MCAN2_RX_INT_NUM, MAIN_MCAN2_TS_INT_NUM},
71                                                        {CSL_MCAN4_MSGMEM_RAM_BASE,     4, MAIN_MCAN4_TX_INT_NUM, MAIN_MCAN4_RX_INT_NUM, MAIN_MCAN4_TS_INT_NUM},
72                                                        {CSL_MCAN5_MSGMEM_RAM_BASE,     5, MAIN_MCAN5_TX_INT_NUM, MAIN_MCAN5_RX_INT_NUM, MAIN_MCAN5_TS_INT_NUM},
73                                                        {CSL_MCAN6_MSGMEM_RAM_BASE,     6, MAIN_MCAN6_TX_INT_NUM, MAIN_MCAN6_RX_INT_NUM, MAIN_MCAN6_TS_INT_NUM},
74                                                        {CSL_MCAN7_MSGMEM_RAM_BASE,     7, MAIN_MCAN7_TX_INT_NUM, MAIN_MCAN7_RX_INT_NUM, MAIN_MCAN7_TS_INT_NUM},
75                                                        {CSL_MCAN9_MSGMEM_RAM_BASE,     9, MAIN_MCAN9_TX_INT_NUM, MAIN_MCAN9_RX_INT_NUM, MAIN_MCAN9_TS_INT_NUM},
76                                                        {CSL_MCAN11_MSGMEM_RAM_BASE,   11, MAIN_MCAN11_TX_INT_NUM, MAIN_MCAN11_RX_INT_NUM, MAIN_MCAN11_TS_INT_NUM},
77                                                       };
78 #endif
80 /**
81  * \brief   This function will configure MCAN module
82  *
83  * \param   index  [IN]  - MCAN index number
84  *
85  * \return  int8_t
86  *             0   - in case of success
87  *            -1   - in case of failure
88  *
89  */
90 static int8_t BoardDiag_mcanConfig(uint8_t index)
91 {
92     uint32_t                   fdoe;
93     uint32_t                   baseAddr;
94     MCAN_RevisionId            revId;
95     MCAN_InitParams            initParams;
96     MCAN_ConfigParams          configParams;
97     MCAN_MsgRAMConfigParams    msgRAMConfigParams;
98     MCAN_StdMsgIDFilterElement stdFiltelem;
99     MCAN_BitTimingParams       bitTimes;
100     
101     /* Set base address */
102     baseAddr = gmcanDiagportInfo[index].mcanBaseAddrs;
104     /* Initialize MCAN Init params */
105     initParams.fdMode          = 0x1U;
106     initParams.brsEnable       = 0x1U;
107     initParams.txpEnable       = 0x0U;
108     initParams.efbi            = 0x0U;
109     initParams.pxhddisable     = 0x0U;
110     initParams.darEnable       = 0x1U;
111     initParams.wkupReqEnable   = 0x1U;
112     initParams.autoWkupEnable  = 0x1U;
113     initParams.emulationEnable = 0x1U;
114     initParams.emulationFAck   = 0x0U;
115     initParams.clkStopFAck     = 0x0U;
116     initParams.wdcPreload      = 0xFFU;
117     initParams.tdcEnable       = 0x1U;
118     initParams.tdcConfig.tdcf  = 0xAU;
119     initParams.tdcConfig.tdco  = 0x6U;
121     /* Initialize MCAN Config params */
122     configParams.monEnable         = 0x0U;
123     configParams.asmEnable         = 0x0U;
124     configParams.tsPrescalar       = 0xFU;
125     configParams.tsSelect          = 0x0U;
126     configParams.timeoutSelect     = MCAN_TIMEOUT_SELECT_CONT;
127     configParams.timeoutPreload    = 0xFFFFU;
128     configParams.timeoutCntEnable  = 0x0U;
129     configParams.filterConfig.rrfs = 0x1U;
130     configParams.filterConfig.rrfe = 0x1U;
131     configParams.filterConfig.anfe = 0x1U;
132     configParams.filterConfig.anfs = 0x1U;
134     /* Initialize Message RAM Sections Configuration Parameters */
135     msgRAMConfigParams.flssa                = APP_MCAN_STD_ID_FILT_START_ADDR;
136     msgRAMConfigParams.lss                  = APP_MCAN_STD_ID_FILTER_NUM;
137     msgRAMConfigParams.flesa                = APP_MCAN_EXT_ID_FILT_START_ADDR;
138     msgRAMConfigParams.lse                  = APP_MCAN_EXT_ID_FILTER_NUM;
140     msgRAMConfigParams.txStartAddr          = APP_MCAN_TX_BUFF_START_ADDR;
141     msgRAMConfigParams.txBufNum             = APP_MCAN_TX_BUFF_SIZE;
142     msgRAMConfigParams.txFIFOSize           = 0U;
143     msgRAMConfigParams.txBufMode            = 0U;
144     msgRAMConfigParams.txBufElemSize        = MCAN_ELEM_SIZE_64BYTES;
145     msgRAMConfigParams.txEventFIFOStartAddr = APP_MCAN_TX_EVENT_START_ADDR;
146     msgRAMConfigParams.txEventFIFOSize      = APP_MCAN_TX_BUFF_SIZE;
147     msgRAMConfigParams.txEventFIFOWaterMark = 3U;
149     msgRAMConfigParams.rxFIFO0startAddr     = APP_MCAN_FIFO_0_START_ADDR;
150     msgRAMConfigParams.rxFIFO0size          = APP_MCAN_FIFO_0_NUM;
151     msgRAMConfigParams.rxFIFO0waterMark     = 3U;
152     msgRAMConfigParams.rxFIFO0OpMode        = 0U;
153     msgRAMConfigParams.rxFIFO1startAddr     = APP_MCAN_FIFO_1_START_ADDR;
154     msgRAMConfigParams.rxFIFO1size          = APP_MCAN_FIFO_1_NUM;
155     msgRAMConfigParams.rxFIFO1waterMark     = 3U;
156     msgRAMConfigParams.rxFIFO1OpMode        = 0U;
157     msgRAMConfigParams.rxBufStartAddr       = APP_MCAN_RX_BUFF_START_ADDR;
158     msgRAMConfigParams.rxBufElemSize        = MCAN_ELEM_SIZE_64BYTES;
159     msgRAMConfigParams.rxFIFO0ElemSize      = MCAN_ELEM_SIZE_64BYTES;
160     msgRAMConfigParams.rxFIFO1ElemSize      = MCAN_ELEM_SIZE_64BYTES;
162     /* Initialize Tx Buffer Config params */
163     stdFiltelem.sfid2 = 0x0U;
164     stdFiltelem.sfid1 = 0x4U;
165     stdFiltelem.sfec  = 0x7U;
166     stdFiltelem.sft   = 0x0U;
168     /* Initialize bit timings
169      * Configuring 1Mbps and 5Mbps as nominal and data bit-rate respectively */
170     bitTimes.nomRatePrescalar   = 0x7U;
171     bitTimes.nomTimeSeg1        = 0x5U;
172     bitTimes.nomTimeSeg2        = 0x2U;
173     bitTimes.nomSynchJumpWidth  = 0x0U;
174     bitTimes.dataRatePrescalar  = 0x1U;
175     bitTimes.dataTimeSeg1       = 0x3U;
176     bitTimes.dataTimeSeg2       = 0x2U;
177     bitTimes.dataSynchJumpWidth = 0x0U;
179     /* Get MCANSS Revision ID */
180     MCAN_getRevisionId(baseAddr, &revId);
181     UART_printf("MCANSS Revision ID:\n");
182     UART_printf("scheme:0x%x\n",revId.scheme);
183     UART_printf("Business Unit:0x%x\n",revId.bu);
184     UART_printf("Module ID:0x%x\n",revId.modId);
185     UART_printf("RTL Revision:0x%x\n",revId.rtlRev);
186     UART_printf("Major Revision:0x%x\n",revId.major);
187     UART_printf("Custom Revision:0x%x\n",revId.custom);
188     UART_printf("Minor Revision:0x%x\n",revId.minor);
190     /* Enable Auto wakeup */
191     fdoe = MCAN_isFDOpEnable(baseAddr);
192     if ((uint32_t)TRUE == fdoe)
193     {
194         UART_printf("CAN-FD operation is enabled through E-Fuse.\n");
195     }
196     else
197     {
198         UART_printf("CAN-FD operation is disabled through E-Fuse.\n");
199     }
201     /* wait for memory initialization to happen */
202     while (FALSE == MCAN_isMemInitDone(baseAddr))
203     {}
205     /* Get endianess value */
206     UART_printf("Endianess Value:0x%x\n",MCAN_getEndianVal(baseAddr));
208     /* Put MCAN in SW initialization mode */
209     MCAN_setOpMode(baseAddr, MCAN_OPERATION_MODE_SW_INIT);
210     while (MCAN_OPERATION_MODE_SW_INIT != MCAN_getOpMode(baseAddr))
211     {}
213     /* Initialize MCAN module */
214     MCAN_init(baseAddr, &initParams);
216     /* Configure MCAN module */
217     MCAN_config(baseAddr, &configParams);
219     /* Configure Bit timings */
220     MCAN_setBitTime(baseAddr, &bitTimes);
222     /* Set Extended ID Mask */
223     MCAN_setExtIDAndMask(baseAddr, APP_MCAN_EXT_ID_AND_MASK);
225     /* Configure Message RAM Sections */
226     MCAN_msgRAMConfig(baseAddr, &msgRAMConfigParams);
228     /* Configure Standard ID filter element */
229     MCAN_addStdMsgIDFilter(baseAddr, 0U, &stdFiltelem);
231     /* Take MCAN out of the SW initialization mode */
232     MCAN_setOpMode(baseAddr, MCAN_OPERATION_MODE_NORMAL);
233     while (MCAN_OPERATION_MODE_NORMAL != MCAN_getOpMode(baseAddr))
234     {}
236     return 0;
239 #if defined(MCAN_DIAG_INTR_ENABLE)
240 /**
241  * \brief   This API will disable the TX and RX interrupts
242  *
243  * \param   baseAddr  [IN]  MCAN base address
244  *
245  */
246 static void BoardDiag_mcanTxIntDisable(uint32_t baseAddr)
248     /* Disable Interrupts */
249     MCAN_enableIntr(baseAddr, MCAN_INTR_MASK_ALL, (uint32_t)FALSE);
250     MCAN_enableIntr(baseAddr,
251                     MCAN_INTR_SRC_RES_ADDR_ACCESS, (uint32_t)FALSE);
252     /* Select Interrupt Line */
253     MCAN_selectIntrLine(baseAddr,
254                         MCAN_INTR_MASK_ALL,
255                         MCAN_INTR_LINE_NUM_0);
256     /* Disable Interrupt Line */
257     MCAN_enableIntrLine(baseAddr,
258                         MCAN_INTR_LINE_NUM_0,
259                         0U);
262 /**
263  * \brief   This API will disable the RX interrupts
264  *
265  * \param   baseAddr  [IN]  MCAN base address
266  *
267  */
268 static void BoardDiag_mcanRxIntDisable(uint32_t baseAddr)
270     /* Disable Interrupts */
271     MCAN_enableIntr(baseAddr, MCAN_INTR_MASK_ALL, (uint32_t)FALSE);
272     MCAN_enableIntr(baseAddr,
273                     MCAN_INTR_SRC_RES_ADDR_ACCESS, (uint32_t)FALSE);
274     /* Select Interrupt Line */
275     MCAN_selectIntrLine(baseAddr,
276                         MCAN_INTR_MASK_ALL,
277                         MCAN_INTR_LINE_NUM_1);
278     /* Disable Interrupt Line */
279     MCAN_enableIntrLine(baseAddr,
280                         MCAN_INTR_LINE_NUM_1,
281                         0U);
283 /**
284  * \brief   This API will enables the RX interrupts
285  *
286  * \param   baseAddr  [IN]  MCAN base address
287  *
288  */
289 static void BoardDiag_mcanRxIntEnable(uint32_t baseAddr)
291     /* Enable Interrupts */
292     MCAN_enableIntr(baseAddr, MCAN_INTR_MASK_ALL, (uint32_t)TRUE);
293     MCAN_enableIntr(baseAddr,
294                     MCAN_INTR_SRC_RES_ADDR_ACCESS, (uint32_t)FALSE);
295     /* Select Interrupt Line */
296     MCAN_selectIntrLine(baseAddr,
297                         MCAN_INTR_MASK_ALL,
298                         MCAN_INTR_LINE_NUM_1);
299     /* Enable Interrupt Line */
300     MCAN_enableIntrLine(baseAddr,
301                         MCAN_INTR_LINE_NUM_1,
302                         1U);
305 /**
306  * \brief   This API will enables the TX interrupts
307  *
308  * \param   baseAddr  [IN]  MCAN base address
309  *
310  */
311 static int32_t BoardDiag_mcanTxIntEnable(uint32_t baseAddr)
313     int32_t  status = 0;
314     MCAN_enableIntr(baseAddr, MCAN_INTR_MASK_ALL, (uint32_t)TRUE);
315     MCAN_enableIntr(baseAddr,
316                     MCAN_INTR_SRC_RES_ADDR_ACCESS, (uint32_t)FALSE);
317     /* Select Interrupt Line */
318     MCAN_selectIntrLine(baseAddr,
319                         MCAN_INTR_MASK_ALL,
320                         MCAN_INTR_LINE_NUM_0);
321     /* Enable Interrupt Line */
322     MCAN_enableIntrLine(baseAddr,
323                         MCAN_INTR_LINE_NUM_0,
324                         1U);
325     /* Enable Transmission interrupt */
326     status = MCAN_txBufTransIntrEnable(baseAddr,
327                                        1U,
328                                        (uint32_t)TRUE);
329     return status;
333 /**
334  * \brief   This is Interrupt Service Routine for MCAN Tx interrupt.
335  *
336  * \param   handle [IN/OUT] mcasp info structure
337  *
338  */
339 static void BoardDiag_mcanTxIntrISR(void *handle)
341     uint32_t intrStatus;
342     uint32_t baseAddrs;
343     mcanDiagportInfo *intrInfo;
345     intrInfo = (mcanDiagportInfo *)handle;
346     baseAddrs = intrInfo -> mcanBaseAddrs;
348     intrStatus = MCAN_getIntrStatus(baseAddrs);
349     MCAN_clearIntrStatus(baseAddrs, intrStatus);
350     if (MCAN_INTR_SRC_TRANS_COMPLETE ==
351         (intrStatus & MCAN_INTR_SRC_TRANS_COMPLETE))
352     {
353         gMcanIsrIntr0Flag = 0U;
354     }
359 /**
360  * \brief   This is Interrupt Service Routine for MCAN Rx interrupt.
361  *
362  * \param   handle [IN/OUT] mcasp info structure
363  *
364  */
365 static void BoardDiag_mcanRxIntrISR(void *handle)
367     uint32_t intrStatus;
368     uint32_t baseAddrs;
369     mcanDiagportInfo *intrInfo;
371     intrInfo = (mcanDiagportInfo *)handle;
372     baseAddrs = intrInfo -> mcanBaseAddrs;
374     intrStatus = MCAN_getIntrStatus(baseAddrs);
375     MCAN_clearIntrStatus(baseAddrs, intrStatus);
376     if (MCAN_INTR_SRC_DEDICATED_RX_BUFF_MSG ==
377         (intrStatus & MCAN_INTR_SRC_DEDICATED_RX_BUFF_MSG))
378     {
379         gMcanIsrIntr1Flag = 0U;
380     }
383 /**
384  * \brief   This function will configure MCAN Tx interrupts
385  *
386  * \param   index  [IN]  - MCAN index number
387  *
388  */
389 static void BoardDiag_mcanTxIntrConfig(uint32_t index)
391 #if defined (__aarch64__)
392     Intc_Init(0);
394     /* Enable CPU Interrupts and register ISR - MCAN Intr0 */
395     Intc_IntRegister(gmcanDiagportInfo[index].mcanTxIntNum,
396                     (IntrFuncPtr) BoardDiag_mcanTxIntrISR, (void*)(&gmcanDiagportInfo[index]));
397     Intc_IntPrioritySet(gmcanDiagportInfo[index].mcanTxIntNum, 1U, 0U);
398     Intc_SystemEnable(gmcanDiagportInfo[index].mcanTxIntNum);
399     UART_printf("Tx Interrupt Configuration done.\n");
400 #endif
403 /**
404  * \brief   This function will configure MCAN Rx interrupts
405  *
406  * \param   index  [IN]  - MCAN index number
407  *
408  */
409 static void BoardDiag_mcanRxIntrConfig(uint32_t index)
411 #if defined (__aarch64__)
412     Intc_Init(0);
414     /* Enable CPU Interrupts and register ISR - MCAN Intr0 */
415     Intc_IntRegister(gmcanDiagportInfo[index].mcanRxIntNum,
416                     (IntrFuncPtr) BoardDiag_mcanRxIntrISR, (void*)(&gmcanDiagportInfo[index]));
417     Intc_IntPrioritySet(gmcanDiagportInfo[index].mcanRxIntNum, 1U, 0U);
418     Intc_SystemEnable(gmcanDiagportInfo[index].mcanRxIntNum);
419     UART_printf("Rx Interrupt Configuration done.\n");
420 #endif
423 #if defined(TS_INT_ENABLE)
424 /**
425  * \brief   This is Interrupt Service Routine for MCAN TimeStamp interrupt.
426  *
427  * \param   handle [IN/OUT] mcasp info structure
428  *
429  */
430 static void BoardDiag_mcanTsIntrISR(void *handle)
432     uint32_t baseAddrs;
433     mcanDiagportInfo *intrInfo;
435     intrInfo = (mcanDiagportInfo *)handle;
436     baseAddrs = intrInfo -> mcanBaseAddrs;
437     if(MCAN_extTSIsIntrEnable(baseAddrs) == (uint32_t)TRUE)
438     {
439         UART_printf("MCAN Time Stamp overflow happened.\n");
440     }
442     MCAN_extTSClearRawStatus(baseAddrs);
443     MCAN_extTSWriteEOI(baseAddrs);
446 /**
447  * \brief   This function will configure MCAN Rx interrupts
448  *
449  * \param   index  [IN]  - MCAN index number
450  *
451  */
452 static void BoardDiag_mcanTsIntrConfig(uint32_t index)
454 #if defined (__aarch64__)
455     Intc_Init(0);
457     /* Enable CPU Interrupts and register ISR - MCAN Intr0 */
458     Intc_IntRegister(gmcanDiagportInfo[index].mcanTsIntNum,
459                     (IntrFuncPtr) BoardDiag_mcanTsIntrISR, (void*)(&gmcanDiagportInfo[index]));
460     Intc_IntPrioritySet(gmcanDiagportInfo[index].mcanTsIntNum, 1U, 0U);
461     Intc_SystemEnable(gmcanDiagportInfo[index].mcanTsIntNum);
462     UART_printf("Tx Interrupt Configuration done.\n");
463 #endif
465 #endif
466 #endif  /* #if defined(MCAN_DIAG_INTR_ENABLE) */
468 #if defined(BOARD_DEBUG_MCAN)
469 /**
470  * \brief   This API will print MCAN Tx Msg.
471  *
472  */
473 static void BoardDiag_mcanPrintTxMsg(void)
475     uint32_t loopCnt;
477     UART_printf("\nMessage ID:0x%x\n", txMsg.id);
479     UART_printf("\nMessage Remote Transmission Request:0x%x\n",txMsg.rtr);
481     UART_printf("\nMessage Extended Frame ID(0:11Bit ID/1:29bit ID):0x%x\n",
482                                                               txMsg.xtd);
484     UART_printf("\nMessage Error State Indicator(0:Error Active/1:Error Passive):0x%x\n",txMsg.esi);
486     UART_printf("\nMessage Data Length Code:0x%x\n",txMsg.dlc);
488     UART_printf("\nMessage BRS:0x%x\n",txMsg.brs);
490     UART_printf("\nMessage CAN FD format:0x%x\n",txMsg.fdf);
492     UART_printf("\nMessage Store Tx Events:0x%x\n",txMsg.efc);
494     UART_printf("\nMessage Marker:0x%x\n",txMsg.mm);
496     for (loopCnt = 0U; loopCnt < txMsg.dlc; loopCnt++)
497     {
498         UART_printf("\nMessage DataByte%d:0x%x\n",loopCnt,txMsg.data[loopCnt]);
499     }
502 /**
503  * \brief   This API will print MCAN Rx Msg.
504  *
505  */
506 static void BoardDiag_mcanPrintRxMsg(void)
508     uint32_t loopCnt;
510     UART_printf("\nReceived last message with following details:");
512     UART_printf("\nMessage ID:0x%x\n",rxMsg.id);
514     UART_printf("\nMessage Remote Transmission Request:0x%x\n",rxMsg.rtr);
515     
516     UART_printf("\nMessage Extended Frame ID(0:11Bit ID/1:29bit ID):0x%x\n",
517                                                                    rxMsg.xtd);
518     
519     UART_printf("\nMessage Error State Indicator(0:Error Active/1:Error Passive):0x%x\n", rxMsg.esi);
520     
521     UART_printf("\nMessage TimeStamp:0x%x\n",rxMsg.rxts);
523     UART_printf("\nMessage Data Length Code:0x%x\n",rxMsg.dlc);
525     UART_printf("\nMessage BRS:0x%x\n",rxMsg.brs);
527     UART_printf("\nMessage CAN FD format:0x%x\n",rxMsg.fdf);
529     UART_printf("\nMessage Filter Index:0x%x\n",rxMsg.fidx);
531     UART_printf("\nMessage Accept Non-matching Frame:0x%x\n",rxMsg.anmf);
533     for (loopCnt = 0U; loopCnt < rxMsg.dlc; loopCnt++)
534     {
535         UART_printf("\nMessage DataByte%d:0x%x\n",loopCnt,rxMsg.data[loopCnt]);
536     }
538 #endif
540 /**
541  * \brief   This API will load the data to the message ram and checking
542  *          the error status
543  *
544  * \param   instance  [IN]  - MCAN instance number
545  *
546  * \return  int8_t
547  *             0   - in case of success
548  *            -1   - in case of failure
549  *
550  */
551 static int8_t BoardDiag_mcanTxTest(uint8_t instance)
553     int8_t   configStatus = 0;
554     uint32_t baseAddr;
555     MCAN_ProtocolStatus protStatus;
556     
557     /* Set base address */
558     baseAddr = gmcanDiagportInfo[instance].mcanBaseAddrs;
559   
560 #if defined(MCAN_DIAG_INTR_ENABLE)
561     BoardDiag_mcanTxIntrConfig(instance);
562     configStatus = BoardDiag_mcanTxIntEnable(baseAddr);
563 #endif
565     /* Write message to Msg RAM */
566     MCAN_writeMsgRam(baseAddr,
567                      MCAN_MEM_TYPE_BUF,
568                      APP_MCAN_TX_BUF_NUM,
569                      &txMsg);
571     /* Add request for transmission */
572     configStatus += MCAN_txBufAddReq(baseAddr, APP_MCAN_TX_BUF_NUM);
573     if (configStatus != 0)
574     {
575         UART_printf("\nError in Adding Transmission Request...\n");
576         return -1;
577     }
580 #if defined(MCAN_DIAG_INTR_ENABLE)
581     while (gMcanIsrIntr0Flag)
582     {}
583     gMcanIsrIntr0Flag = 1U;
584 #else   
585     /* Waiting for Transmission Complete */
586     while(((MCAN_getTxBufReqPend(baseAddr) >>
587             APP_MCAN_TX_BUF_NUM) & 0x1) == 0x1);
588 #endif
590     MCAN_getProtocolStatus(baseAddr, &protStatus);
591     /* Checking for Errors */
592     if (((MCAN_ERR_CODE_NO_ERROR == protStatus.lastErrCode) ||
593          (MCAN_ERR_CODE_NO_CHANGE == protStatus.lastErrCode)) &&
594         ((MCAN_ERR_CODE_NO_ERROR == protStatus.dlec) ||
595          (MCAN_ERR_CODE_NO_CHANGE == protStatus.dlec)) &&
596         (0U == protStatus.pxe))
597     {
598         UART_printf("\nMessage successfully transferred with payload Bytes:0x%x\n",txMsg.dlc);
599     }
600     else
601     {
602         UART_printf("\nError in transmission with payload Bytes:0x%x\n", txMsg.dlc);
603         configStatus = -1;
604     }
606     return configStatus;
609 /**
610  * \brief   This API will receive the data and compares with the transmit data
611  *
612  * \param   instance  [IN]  - MCAN instance number
613  *
614  * \return  int8_t
615  *             0   - in case of success
616  *            -1   - in case of failure
617  *
618  */
619 static int8_t BoardDiag_mcanRxTest(uint8_t index)
621     uint32_t chkCnt     = 0U;
622     uint32_t errFlag    = 0U;
623     uint32_t baseAddr;
624     int8_t  testStatus  = 0;
625     MCAN_RxNewDataStatus newDataStatus;
626     MCAN_ErrCntStatus    errCounter;
628     /* Set base address */
629     baseAddr = gmcanDiagportInfo[index].mcanBaseAddrs;
631 #if defined(MCAN_DIAG_INTR_ENABLE)
632     BoardDiag_mcanRxIntrConfig(index);
633     BoardDiag_mcanRxIntEnable(baseAddr);
634 #endif
636 #if defined(MCAN_DIAG_INTR_ENABLE)
637     while (gMcanIsrIntr1Flag)
638     {}
639     gMcanIsrIntr1Flag = 1U;
640 #else
641     /* Waiting for Transmission Complete */
642     while(MCAN_INTR_SRC_DEDICATED_RX_BUFF_MSG !=
643         (MCAN_getIntrStatus(baseAddr) &
644         MCAN_INTR_SRC_DEDICATED_RX_BUFF_MSG));
645     
646 #endif
647     /* Checking for Errors */
648     MCAN_getErrCounters(baseAddr, &errCounter);
649     if ((0U == errCounter.recErrCnt) &&
650         (0U == errCounter.canErrLogCnt))
651     {
652         MCAN_getNewDataStatus(baseAddr, &newDataStatus);
653         MCAN_clearNewDataStatus(baseAddr, &newDataStatus);
654         MCAN_readMsgRam(baseAddr,
655                         MCAN_MEM_TYPE_BUF,
656                         0U,
657                         0U,
658                         &rxMsg);
660         errFlag = 0U;
662         for (chkCnt = 0U; chkCnt < rxMsg.dlc; chkCnt++)
663         {
664             if (txMsg.data[chkCnt] != rxMsg.data[chkCnt])
665             {
666                 errFlag = 1U;
667                 break;
668             }
669         }
671         if (0U == errFlag)
672         {
673             UART_printf("\nMessage successfully received with payload Bytes:0x%x\n",rxMsg.dlc);
674         }
675         else
676         {
677             UART_printf("\nWrong data received in message with payload Bytes:0x%x\n",rxMsg.dlc);
678             testStatus = -1;
679         }
680     }
681     else
682     {
683         UART_printf("\nError in reception with payload Bytes:0x%x\n", txMsg.dlc);
684         testStatus = -1;
685     }
686 #if defined(BOARD_DEBUG_MCAN)
687     BoardDiag_mcanPrintRxMsg();
688 #endif
689     return testStatus;
692 #if defined(SOC_J721E)
693 /**
694  * \brief   This function enables the Main CAN module and transceiver by setting
695  *          the Enable and STB Pins
696  *
697  */
698 static void BoardDiag_mcanMainconfigs(void)
700     Board_IoExpCfg_t ioExpCfg;
701     Board_STATUS status = BOARD_SOK;
703     ioExpCfg.i2cInst     = BOARD_I2C_IOEXP_DEVICE2_INSTANCE;
704     ioExpCfg.socDomain   = BOARD_SOC_DOMAIN_MAIN;
705     ioExpCfg.slaveAddr   = BOARD_I2C_IOEXP_DEVICE2_ADDR;
706     ioExpCfg.enableIntr  = false;    
707     ioExpCfg.ioExpType   = THREE_PORT_IOEXP;
708     ioExpCfg.portNum     = PORTNUM_0;
709     ioExpCfg.pinNum      = PIN_NUM_6;
710     ioExpCfg.signalLevel = GPIO_SIGNAL_LEVEL_HIGH;
711     
712     status = Board_control(BOARD_CTRL_CMD_SET_IO_EXP_PIN_OUT, &ioExpCfg);
713     if(status != BOARD_SOK)
714     {
715         UART_printf("Failed to enable the main MCAN0 \n");
716     }
718     ioExpCfg.i2cInst     = BOARD_I2C_IOEXP_DEVICE2_INSTANCE;
719     ioExpCfg.socDomain   = BOARD_SOC_DOMAIN_MAIN;
720     ioExpCfg.slaveAddr   = BOARD_I2C_IOEXP_DEVICE2_ADDR;
721     ioExpCfg.enableIntr  = false;    
722     ioExpCfg.ioExpType   = THREE_PORT_IOEXP;
723     ioExpCfg.portNum     = PORTNUM_0;
724     ioExpCfg.pinNum      = PIN_NUM_7;
725     ioExpCfg.signalLevel = GPIO_SIGNAL_LEVEL_HIGH;
726     
727     status = Board_control(BOARD_CTRL_CMD_SET_IO_EXP_PIN_OUT, &ioExpCfg);
728     if(status != BOARD_SOK)
729     {
730         UART_printf("Failed to set the mcan0 stb pin to normal mode\n");
731     }
733     ioExpCfg.i2cInst     = BOARD_I2C_IOEXP_DEVICE2_INSTANCE;
734     ioExpCfg.socDomain   = BOARD_SOC_DOMAIN_MAIN;
735     ioExpCfg.slaveAddr   = BOARD_I2C_IOEXP_DEVICE2_ADDR;
736     ioExpCfg.enableIntr  = false;    
737     ioExpCfg.ioExpType   = THREE_PORT_IOEXP;
738     ioExpCfg.portNum     = PORTNUM_1;
739     ioExpCfg.pinNum      = PIN_NUM_4;
740     ioExpCfg.signalLevel = GPIO_SIGNAL_LEVEL_LOW;
741     
742     status = Board_control(BOARD_CTRL_CMD_SET_IO_EXP_PIN_OUT, &ioExpCfg);
743     if(status != BOARD_SOK)
744     {
745         UART_printf("Failed to enable the MCAN mux selection\n");
746     }
748 #endif
750 /**
751  * \brief   This API Initializes the GPIO module
752  *
753  * \param    gpioBaseAddrs [IN]  GPIO base address to configure
754  * \param    port          [IN]  GPIO Port number
755  *
756  */
757 static void BoardDiag_mcanGpioConfig(uint32_t gpioBaseAddrs,uint32_t port)
759     GPIO_v0_HwAttrs gpioCfg;
760     GPIO_socGetInitCfg(port, &gpioCfg);
761     gpioCfg.baseAddr = gpioBaseAddrs;
762     GPIO_socSetInitCfg(port, &gpioCfg);
763     /* GPIO initialization */
764     GPIO_init();
767 /**
768  * \brief   This API enables the CAN transceivers by setting the STB pins
769  *
770  */
771 static void BoardDiag_mcanEnable(void)
774 #if defined(SOC_J721E)
775     Board_IoExpCfg_t ioExpCfg;
776     Board_STATUS status = BOARD_SOK;
777 #endif
779 #if defined (am65xx_idk)
780     BoardDiag_mcanGpioConfig(CSL_GPIO1_BASE, 1);
781     GPIO_write(0, 1);
782     GPIO_write(1, 1);
783 #else
784     BoardDiag_mcanGpioConfig(CSL_WKUP_GPIO0_BASE,0);
785     /* Enable MCU CAN transceivers by setting the STB pins */
786     GPIO_write(0, 1); /* MCU_CAN0_STB -> WKUP_GPIO0_54 */
787     GPIO_write(1, 0); /* MCU_CAN1_STB -> WKUP_GPIO0_2  */
788     /* MCU_MCAN0_EN */
789     GPIO_write(2, 1); /* WKUP_GPIO0_0 */
791     /* Enable CP board MAIN CAN transceivers by setting the STB pins */
792     BoardDiag_mcanMainconfigs();
794     /* MAIN CAN2 STB */
795     BoardDiag_mcanGpioConfig(CSL_GPIO0_BASE, 0);
796     GPIO_write(3, 0); /* GPIO0_127 */
798     if(expBoardDetect)
799     {
800         UART_printf("GESI board Detected\n");
801         ioExpCfg.i2cInst     = BOARD_I2C_IOEXP_DEVICE1_INSTANCE;
802         ioExpCfg.socDomain   = BOARD_SOC_DOMAIN_MAIN;
803         ioExpCfg.slaveAddr   = BOARD_I2C_IOEXP_DEVICE1_ADDR;
804         ioExpCfg.enableIntr  = false;    
805         ioExpCfg.ioExpType   = TWO_PORT_IOEXP;
806         ioExpCfg.portNum     = PORTNUM_1;
807         ioExpCfg.pinNum      = PIN_NUM_4;
808         ioExpCfg.signalLevel = GPIO_SIGNAL_LEVEL_LOW;
809         
810         status = Board_control(BOARD_CTRL_CMD_SET_IO_EXP_PIN_OUT, &ioExpCfg);
811         if(status != BOARD_SOK)
812         {
813             UART_printf("Failed to set the GESI board mcan stb pin to normal mode \n");
814         }
815         /* GPIO0_60 */
816         BoardDiag_mcanGpioConfig(CSL_GPIO0_BASE, 0);
817         GPIO_write(4, 0);
818     }
819 #endif
822 /**
823  * \brief  This function executes MCAN Diagnostic test
824  *
825  * \return  int8_t
826  *           0  - in case of success
827  *          -1  - in case of failure
828  *
829  */
830 int8_t BoardDiag_McanTest(void)
832     int8_t    ret     = 0;
833     uint32_t  index;
834     uint32_t  portNum;
836 #if defined(DIAG_STRESS_TEST) && (defined(am65xx_idk) || defined(SOC_J721E))
837     char rdBuf = 'y';
838 #endif
840 #if defined(DIAG_STRESS_TEST) && ((defined(am65xx_idk)) || defined(SOC_J721E))
841     UART_printf  ("***********************************************\n");
842     UART_printf  ("*                MCAN Stress Test             *\n");
843     UART_printf  ("***********************************************\n");
844 #else
845     UART_printf  ("***********************************************\n");
846     UART_printf  ("*                MCAN Test                    *\n");
847     UART_printf  ("***********************************************\n");
848 #endif
850     BoardDiag_mcanEnable();
851 #if defined(am65xx_idk)
852     mcanMaxPorts = MCAN_MAX_PORTS;
853 #else
854     if(expBoardDetect)
855     {
856         mcanMaxPorts = MCAN_MAX_PORTS_EXP;
857     }
858     else
859     {
860         mcanMaxPorts = MCAN_MAX_PORTS_CP;
861     }
862 #endif
864     /* Initialize message to transmit */
865     txMsg.id  = (uint32_t)((uint32_t)(0x4U) << 18U);
866     txMsg.rtr = 0U;
867     txMsg.xtd = 0U;
868     txMsg.esi = 0U;
869     txMsg.dlc = 0xFU;
870     txMsg.brs = 1U;
871     txMsg.fdf = 1U;
872     txMsg.efc = 1U;
873     txMsg.mm  = 0xAAU;
875     for(portNum=0; portNum<mcanMaxPorts;)
876     {
877         /* Configure MCAN */
878         ret = BoardDiag_mcanConfig(portNum);
879         if(ret == 0)
880         {
881             UART_printf("Successfully configured MCAN%d\n",portNum);
882         }
884         ret = BoardDiag_mcanConfig(portNum+1);
885         if(ret == 0)
886         {
887             UART_printf("Successfully configured MCAN%d\n",portNum+1);
888         }
890         UART_printf("\n\nTransmitting Data on MCAN Port%d and Receiving on MCAN port%d\n",portNum, portNum+1);
892         for(index = 0; index < PKT_SEND_COUNT; index++)
893         {
894             UART_printf("\nSending Packet - %d\n", (index + 1));
895             /* Fill the Tx buffer with random data */
896             BoardDiag_genPattern(txMsg.data, MCAN_MAX_PAYLOAD_BYTES,
897                                  BOARD_DIAG_TEST_PATTERN_RANDOM);
899             /* Transmiting port */
900             ret = BoardDiag_mcanTxTest(portNum);
901             if(ret != 0)
902             {
903                 UART_printf("Failed to transmit data on port%d\n",portNum);
904                 return (-1);
905             }
906 #if defined(BOARD_DEBUG_MCAN)
907             BoardDiag_mcanPrintTxMsg();
908 #endif
909             /* Receiving port*/
910             ret = BoardDiag_mcanRxTest(portNum+1);
911             if(ret != 0)
912             {
913                 UART_printf("Failed to receive data on port%d",portNum);
914                 return (-1);
915             }
917             UART_printf("\nReceived Packet - %d\n\n", (index + 1));
918 #if defined(DIAG_STRESS_TEST) && ((defined(am65xx_idk)) || defined(SOC_J721E))
919             /* Check if there a input from console to break the test */
920             rdBuf = (char)BoardDiag_getUserInput(BOARD_UART_INSTANCE);
921             if((rdBuf == 'b') || (rdBuf == 'B'))
922             {
923                 UART_printf("Received Test Termination... Exiting the Test\n\n");
924                 UART_printf("MCAN Stress Test Status\n");
925                 UART_printf("============================================\n");
926                 UART_printf("Total Number of Packets sent: %d\nTotal Number of Packets Received: %d\n",index + 1,index + 1);
927                 break;
928             }
929 #endif
930 #if defined(MCAN_DIAG_INTR_ENABLE)
931             /* Disable the TX and RX interrupts */
932             BoardDiag_mcanTxIntDisable(gmcanDiagportInfo[portNum].mcanBaseAddrs);
933             BoardDiag_mcanRxIntDisable(gmcanDiagportInfo[portNum+1].mcanBaseAddrs);
934 #endif
935         }
937         UART_printf("\n\nTransmitting Data on MCAN Port%d and Receiving on MCAN port%d\n",portNum+1, portNum);
938         for(index = 0; index < PKT_SEND_COUNT; index++)
939         {
940             UART_printf("\nSending Packet - %d\n", (index + 1));
941             /* Fill the Tx buffer with random data */
942             BoardDiag_genPattern(txMsg.data, MCAN_MAX_PAYLOAD_BYTES,
943                                  BOARD_DIAG_TEST_PATTERN_RANDOM);
945             /* Transmitting port*/
946             ret = BoardDiag_mcanTxTest(portNum+1);
947             if(ret != 0)
948             {
949                 UART_printf("Failed to transmit data on port%d",portNum+1);
950                 return -1;
951             }
952 #if defined(BOARD_DEBUG_MCAN)
953             BoardDiag_mcanPrintTxMsg();
954             UART_printf("Receiving data on port%d\n", portNum);
955 #endif
957             /* Receiving port */
958             ret = BoardDiag_mcanRxTest(portNum);
959             if(ret != 0)
960             {
961                 UART_printf("Failed to receive data on port%d\n",portNum);
962                 return (-1);
963             }
965             UART_printf("\nReceived Packet - %d\n\n", (index + 1));
966 #if defined(DIAG_STRESS_TEST) && ((defined(am65xx_idk)) || defined(SOC_J721E))
967             /* Check if there a input from console to break the test */
968             rdBuf = (char)BoardDiag_getUserInput(BOARD_UART_INSTANCE);
969             if((rdBuf == 'b') || (rdBuf == 'B'))
970             {
971                 UART_printf("Received Test Termination... Exiting the Test\n\n");
972                 UART_printf("MCAN Stress Test Status\n");
973                 UART_printf("============================================\n");
974                 UART_printf("Total Number of Packets sent: %d\nTotal Number of Packets Received: %d\n",index + 1,index + 1);
975                 break;
976             }
977 #endif
978 #if defined(MCAN_DIAG_INTR_ENABLE)
979             /* Disable the TX and RX interrupts */
980             BoardDiag_mcanTxIntDisable(gmcanDiagportInfo[portNum+1].mcanBaseAddrs);
981             BoardDiag_mcanRxIntDisable(gmcanDiagportInfo[portNum].mcanBaseAddrs);
982 #endif
983         }
985         portNum +=2;
986     }
987     UART_printf("\n MCAN diagnostic test completed.\n");
989     return  0;
993 /**
994  * \brief  main function
995  *
996  *  This function performs board initializations and calls MCAN test
997  *
998  * \return  int
999  *           0  - in case of success
1000  *          -1  - in case of failure
1001  *
1002  */
1003 int main(void)
1005     Board_STATUS status;
1006     Board_initCfg boardCfg;
1007 #if defined(SOC_J721E)
1008     Board_PinmuxConfig_t gesiIcssgPinmux;
1009     if(Board_detectBoard(BOARD_ID_GESI) == TRUE)
1010     {
1011         Board_pinmuxGetCfg(&gesiIcssgPinmux);
1012         gesiIcssgPinmux.autoCfg = BOARD_PINMUX_CUSTOM;
1013         gesiIcssgPinmux.gesiExp = BOARD_PINMUX_GESI_ICSSG;
1014         Board_pinmuxSetCfg(&gesiIcssgPinmux);
1015         expBoardDetect = 1;
1016     }
1017 #endif
1019 #ifdef PDK_RAW_BOOT
1020     boardCfg = BOARD_INIT_MODULE_CLOCK |
1021                BOARD_INIT_PINMUX_CONFIG |
1022                BOARD_INIT_UART_STDIO;
1023 #else
1024     boardCfg = BOARD_INIT_UART_STDIO | BOARD_INIT_PINMUX_CONFIG ;
1025 #endif
1027     status = Board_init(boardCfg);
1028     if(status != BOARD_SOK)
1029     {
1030         return -1;
1031     }
1033     return BoardDiag_McanTest();