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;
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;
237 }
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)
247 {
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);
260 }
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)
269 {
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);
282 }
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)
290 {
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);
303 }
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)
312 {
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;
331 }
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)
340 {
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 }
356 }
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)
366 {
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 }
381 }
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)
390 {
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
401 }
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)
410 {
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
421 }
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)
431 {
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);
444 }
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)
453 {
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
464 }
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)
474 {
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 }
500 }
502 /**
503 * \brief This API will print MCAN Rx Msg.
504 *
505 */
506 static void BoardDiag_mcanPrintRxMsg(void)
507 {
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);
516 UART_printf("\nMessage Extended Frame ID(0:11Bit ID/1:29bit ID):0x%x\n",
517 rxMsg.xtd);
519 UART_printf("\nMessage Error State Indicator(0:Error Active/1:Error Passive):0x%x\n", rxMsg.esi);
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 }
537 }
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)
552 {
553 int8_t configStatus = 0;
554 uint32_t baseAddr;
555 MCAN_ProtocolStatus protStatus;
557 /* Set base address */
558 baseAddr = gmcanDiagportInfo[instance].mcanBaseAddrs;
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;
607 }
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)
620 {
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));
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;
690 }
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)
699 {
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;
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;
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;
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 }
747 }
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)
758 {
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();
765 }
767 /**
768 * \brief This API enables the CAN transceivers by setting the STB pins
769 *
770 */
771 static void BoardDiag_mcanEnable(void)
772 {
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;
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
820 }
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)
831 {
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;
990 }
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)
1004 {
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();
1034 }