This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

TDA4VM: MCAN9 Communication error

Part Number: TDA4VM
Other Parts Discussed in Thread: TCA6424,

Hi Ti Team,

I took mcan_evm_loopback_app_main_k3.c from ti-processor-sdk-rtos-j721e-evm-08_01_00_11/pdk_jacinto_08_01_00_33/packages/ti/csl/example/mcan/mcanEvmLoopback and placed it in ti-processor-sdk-rtos-j721e-evm-08_01_00_11/vision_apps/platform/j721e/rtos/mcu2_1.

I changed function name from main to mcan_test_evm() in mcan_evm_loopback_app_main_k3.c and added new name to mcu2_1/main.c.

i am testing MCAN9 channel on Main domain RTOS MCU2_1 core in QNX+RTOS mode. Canoe is connected with gesi board for MCAN9 communication. we can see conoe 

loopback mode works fine but transmitter or receiver mode is not working that is code stuck at while loop waiting for interrupt flag to be cleared. Please suggest possible causes of this issue.

please find below transmitter mode logs, receiver mode logs and code we trying..

Transmitter Side application logs:
[MCU2_1] 4.387855 s: Starting Application...
[MCU2_1] 4.387895 s: Available MCAN Module for usage:
[MCU2_1] 4.387959 s: 0. BA: 0x2798000 - MAIN_MCAN9 (GESI Exp Board).
[MCU2_1] 4.388016 s: 1. BA: 0x2708000 - MAIN_MCAN0.
[MCU2_1] 4.388061 s: 2. BA: 0x2728000 - MAIN_MCAN2.
[MCU2_1] 4.388097 s: Enter MCAN Module to use:
[MCU2_1] 4.388205 s: gMcanModAddr = gMcanMods[0] = 0x2798000
[MCU2_1] 4.388253 s: MCAN Clock Configuration Successful.
[MCU2_1] 4.388292 s: MCAN Node Type:
[MCU2_1] 4.388324 s: 1. Transmitter Side.
[MCU2_1] 4.388357 s: 2. Receiver Side.
[MCU2_1] 4.388395 s: 3. Loopback - no external transmission/reception
[MCU2_1] 4.388436 s: Enter type of the node:
[MCU2_1] 4.388537 s: CrossBar/Interrupt Configuration done.
[MCU2_1] 4.388591 s: Initialize message to transmit.. Done..
[MCU2_1] 4.388640 s: txMsg.data[0] = 0:
[MCU2_1] 4.388683 s: txMsg.data[1] = 1:
[MCU2_1] 4.388723 s: txMsg.data[2] = 2:
[MCU2_1] 4.388763 s: txMsg.data[3] = 3:
[MCU2_1] 4.388804 s: txMsg.data[4] = 4:
[MCU2_1] 4.388844 s: txMsg.data[5] = 5:
[MCU2_1] 4.388884 s: txMsg.data[6] = 6:
[MCU2_1] 4.388922 s: txMsg.data[7] = 7:
[MCU2_1] 4.388971 s: txMsg.data[8] = 8:
[MCU2_1] 4.389013 s: txMsg.data[9] = 9:
[MCU2_1] 4.389053 s: txMsg.data[10] = 10:
[MCU2_1] 4.389094 s: txMsg.data[11] = 11:
[MCU2_1] 4.389133 s: txMsg.data[12] = 12:
[MCU2_1] 4.389172 s: txMsg.data[13] = 13:
[MCU2_1] 4.389212 s: txMsg.data[14] = 14:
[MCU2_1] 4.389250 s: txMsg.data[15] = 15:
[MCU2_1] 4.389289 s: txMsg.data[16] = 16:
[MCU2_1] 4.389327 s: txMsg.data[17] = 17:
[MCU2_1] 4.389367 s: txMsg.data[18] = 18:
[MCU2_1] 4.389406 s: txMsg.data[19] = 19:
[MCU2_1] 4.389444 s: txMsg.data[20] = 20:
[MCU2_1] 4.389485 s: txMsg.data[21] = 21:
[MCU2_1] 4.389523 s: txMsg.data[22] = 22:
[MCU2_1] 4.389562 s: txMsg.data[23] = 23:
[MCU2_1] 4.389601 s: txMsg.data[24] = 24:
[MCU2_1] 4.389642 s: txMsg.data[25] = 25:
[MCU2_1] 4.389680 s: txMsg.data[26] = 26:
[MCU2_1] 4.389719 s: txMsg.data[27] = 27:
[MCU2_1] 4.389758 s: txMsg.data[28] = 28:
[MCU2_1] 4.389798 s: txMsg.data[29] = 29:
[MCU2_1] 4.389837 s: txMsg.data[30] = 30:
[MCU2_1] 4.389877 s: txMsg.data[31] = 31:
[MCU2_1] 4.389917 s: txMsg.data[32] = 32:
[MCU2_1] 4.389960 s: txMsg.data[33] = 33:
[MCU2_1] 4.390000 s: txMsg.data[34] = 34:
[MCU2_1] 4.390040 s: txMsg.data[35] = 35:
[MCU2_1] 4.390079 s: txMsg.data[36] = 36:
[MCU2_1] 4.390117 s: txMsg.data[37] = 37:
[MCU2_1] 4.390158 s: txMsg.data[38] = 38:
[MCU2_1] 4.390197 s: txMsg.data[39] = 39:
[MCU2_1] 4.390236 s: txMsg.data[40] = 40:
[MCU2_1] 4.390274 s: txMsg.data[41] = 41:
[MCU2_1] 4.390313 s: txMsg.data[42] = 42:
[MCU2_1] 4.390354 s: txMsg.data[43] = 43:
[MCU2_1] 4.390392 s: txMsg.data[44] = 44:
[MCU2_1] 4.390433 s: txMsg.data[45] = 45:
[MCU2_1] 4.390472 s: txMsg.data[46] = 46:
[MCU2_1] 4.390512 s: txMsg.data[47] = 47:
[MCU2_1] 4.390552 s: txMsg.data[48] = 48:
[MCU2_1] 4.390592 s: txMsg.data[49] = 49:
[MCU2_1] 4.390631 s: txMsg.data[50] = 50:
[MCU2_1] 4.390670 s: txMsg.data[51] = 51:
[MCU2_1] 4.390709 s: txMsg.data[52] = 52:
[MCU2_1] 4.390749 s: txMsg.data[53] = 53:
[MCU2_1] 4.390787 s: txMsg.data[54] = 54:
[MCU2_1] 4.390825 s: txMsg.data[55] = 55:
[MCU2_1] 4.390865 s: txMsg.data[56] = 56:
[MCU2_1] 4.390904 s: txMsg.data[57] = 57:
[MCU2_1] 4.390945 s: txMsg.data[58] = 58:
[MCU2_1] 4.390988 s: txMsg.data[59] = 59:
[MCU2_1] 4.391029 s: txMsg.data[60] = 60:
[MCU2_1] 4.391069 s: txMsg.data[61] = 61:
[MCU2_1] 4.391107 s: txMsg.data[62] = 62:
[MCU2_1] 4.391145 s: txMsg.data[63] = 63:
[MCU2_1] 4.391193 s: gMcanModAddr:0x2798000
[MCU2_1] 4.391230 s: MCANSS Revision ID:
[MCU2_1] 4.391267 s: scheme:0x1
[MCU2_1] 4.391299 s: Business Unit:0x2
[MCU2_1] 4.391333 s: Module ID:0x8e0
[MCU2_1] 4.391366 s: RTL Revision:0x9
[MCU2_1] 4.391401 s: Major Revision:0x1
[MCU2_1] 4.391436 s: Custom Revision:0x0
[MCU2_1] 4.391472 s: Minor Revision:0x1
[MCU2_1] 4.391510 s: CAN-FD operation is enabled through E-Fuse.
[MCU2_1] 4.391557 s: Endianess Value: 0x87654321
[MCU2_1] 4.391633 s:
[MCU2_1] 4.391668 s: Transmitter Side application:
[MCU2_1] 4.391721 s: This test will send 15 messages with various payload varying from 1byte to 64bytes.
[MCU2_1] 4.391771 s: Message Object:
[MCU2_1] 4.391806 s:
[MCU2_1] 4.391839 s: Message ID: 0x100000
[MCU2_1] 4.391881 s: Message Remote Transmission Request: 0x0
[MCU2_1] 4.391930 s: Message Extended Frame ID(0:11Bit ID/1:29bit ID): 0x0
[MCU2_1] 4.391990 s: Message Error State Indicator(0:Error Active/1:Error Passive): 0x0
[MCU2_1] 4.392042 s: Message Data Length Code: 0xf
[MCU2_1] 4.392081 s: Message BRS: 0x1
[MCU2_1] 4.392117 s: Message CAN FD format: 0x1
[MCU2_1] 4.392156 s: Message Store Tx Events: 0x1
[MCU2_1] 4.392195 s: Message Marker: 0xaa
[MCU2_1] 4.392236 s: Message DataByte0: 0x0
[MCU2_1] 4.392277 s: Message DataByte1: 0x1
[MCU2_1] 4.392318 s: Message DataByte2: 0x2
[MCU2_1] 4.392361 s: Message DataByte3: 0x3
[MCU2_1] 4.392401 s: Message DataByte4: 0x4
[MCU2_1] 4.392442 s: Message DataByte5: 0x5
[MCU2_1] 4.392481 s: Message DataByte6: 0x6
[MCU2_1] 4.392522 s: Message DataByte7: 0x7
[MCU2_1] 4.392562 s: Message DataByte8: 0x8
[MCU2_1] 4.392602 s: Message DataByte9: 0x9
[MCU2_1] 4.392642 s: Message DataByte10: 0xa
[MCU2_1] 4.392682 s: Message DataByte11: 0xb
[MCU2_1] 4.392723 s: Message DataByte12: 0xc
[MCU2_1] 4.392764 s: Message DataByte13: 0xd
[MCU2_1] 4.392804 s: Message DataByte14: 0xe
[MCU2_1] 4.392845 s: Message DataByte15: 0xf
[MCU2_1] 4.392887 s: Message DataByte16: 0x10
[MCU2_1] 4.392930 s: Message DataByte17: 0x11
[MCU2_1] 4.392978 s: Message DataByte18: 0x12
[MCU2_1] 4.393021 s: Message DataByte19: 0x13
[MCU2_1] 4.393065 s: Message DataByte20: 0x14
[MCU2_1] 4.393107 s: Message DataByte21: 0x15
[MCU2_1] 4.393149 s: Message DataByte22: 0x16
[MCU2_1] 4.393189 s: Message DataByte23: 0x17
[MCU2_1] 4.393229 s: Message DataByte24: 0x18
[MCU2_1] 4.393270 s: Message DataByte25: 0x19
[MCU2_1] 4.393312 s: Message DataByte26: 0x1a
[MCU2_1] 4.393352 s: Message DataByte27: 0x1b
[MCU2_1] 4.393395 s: Message DataByte28: 0x1c
[MCU2_1] 4.393435 s: Message DataByte29: 0x1d
[MCU2_1] 4.393477 s: Message DataByte30: 0x1e
[MCU2_1] 4.393518 s: Message DataByte31: 0x1f
[MCU2_1] 4.393559 s: Message DataByte32: 0x20
[MCU2_1] 4.393600 s: Message DataByte33: 0x21
[MCU2_1] 4.393642 s: Message DataByte34: 0x22
[MCU2_1] 4.393683 s: Message DataByte35: 0x23
[MCU2_1] 4.393723 s: Message DataByte36: 0x24
[MCU2_1] 4.393764 s: Message DataByte37: 0x25
[MCU2_1] 4.393806 s: Message DataByte38: 0x26
[MCU2_1] 4.393848 s: Message DataByte39: 0x27
[MCU2_1] 4.393890 s: Message DataByte40: 0x28
[MCU2_1] 4.393930 s: Message DataByte41: 0x29
[MCU2_1] 4.393975 s: Message DataByte42: 0x2a
[MCU2_1] 4.394020 s: Message DataByte43: 0x2b
[MCU2_1] 4.394062 s: Message DataByte44: 0x2c
[MCU2_1] 4.394106 s: Message DataByte45: 0x2d
[MCU2_1] 4.394147 s: Message DataByte46: 0x2e
[MCU2_1] 4.394189 s: Message DataByte47: 0x2f
[MCU2_1] 4.394230 s: Message DataByte48: 0x30
[MCU2_1] 4.394272 s: Message DataByte49: 0x31
[MCU2_1] 4.394314 s: Message DataByte50: 0x32
[MCU2_1] 4.394355 s: Message DataByte51: 0x33
[MCU2_1] 4.394396 s: Message DataByte52: 0x34
[MCU2_1] 4.394438 s: Message DataByte53: 0x35
[MCU2_1] 4.394479 s: Message DataByte54: 0x36
[MCU2_1] 4.394519 s: Message DataByte55: 0x37
[MCU2_1] 4.394560 s: Message DataByte56: 0x38
[MCU2_1] 4.394602 s: Message DataByte57: 0x39
[MCU2_1] 4.394644 s: Message DataByte58: 0x3a
[MCU2_1] 4.394686 s: Message DataByte59: 0x3b
[MCU2_1] 4.394727 s: Message DataByte60: 0x3c
[MCU2_1] 4.394770 s: Message DataByte61: 0x3d
[MCU2_1] 4.394811 s: Message DataByte62: 0x3e
[MCU2_1] 4.394852 s: Message DataByte63: 0x3f
...

Receiver Side application logs:
[MCU2_1] 4.380850 s:
[MCU2_1] 4.380885 s: Starting Application...
[MCU2_1] 4.382142 s: Available MCAN Module for usage:
[MCU2_1] 4.382690 s: 0. BA: 0x40500000 - MCU_MCAN0.
[MCU2_1] 4.387455 s: 1. BA: 0x40540000 - MCU_MCAN1.
[MCU2_1] 4.387552 s: 2. BA: 0x40500000 - MCU_MCAN0.
[MCU2_1] 4.387612 s: 3. BA: 0x2708000 - MAIN_MCAN0.
[MCU2_1] 4.387667 s: 4. BA: 0x2728000 - MAIN_MCAN2.
[MCU2_1] 4.387707 s: Enter MCAN Module to use:
[MCU2_1] 4.387829 s: gMcanModAddr = gMcanMods[0] = 0x40500000
[MCU2_1] 4.387889 s: MCAN Clock Configuration Successful.
[MCU2_1] 4.387932 s: MCAN Node Type:
[MCU2_1] 4.387966 s: 1. Transmitter Side.
[MCU2_1] 4.387999 s: 2. Receiver Side.
[MCU2_1] 4.388040 s: 3. Loopback - no external transmission/reception
[MCU2_1] 4.388084 s: Enter type of the node:
[MCU2_1] 4.388411 s: SciClient Interrupt Params Configuration passed for offset: 1
[MCU2_1] 4.388679 s: SciClient Interrupt Params Configuration passed for offset: 2
[MCU2_1] 4.388859 s: Error in SciClient Interrupt Params Configuration!!!offset: 0
[MCU2_1] 4.388941 s: CrossBar/Interrupt Configuration failed.
[MCU2_1] 4.388997 s: Initialize message to transmit.. Done..
[MCU2_1] 4.389056 s: txMsg.data[0] = 0:
[MCU2_1] 4.389103 s: txMsg.data[1] = 1:
[MCU2_1] 4.389149 s: txMsg.data[2] = 2:
[MCU2_1] 4.389194 s: txMsg.data[3] = 3:
[MCU2_1] 4.389237 s: txMsg.data[4] = 4:
[MCU2_1] 4.389281 s: txMsg.data[5] = 5:
[MCU2_1] 4.389326 s: txMsg.data[6] = 6:
[MCU2_1] 4.389371 s: txMsg.data[7] = 7:
[MCU2_1] 4.389415 s: txMsg.data[8] = 8:
[MCU2_1] 4.389459 s: txMsg.data[9] = 9:
[MCU2_1] 4.389506 s: txMsg.data[10] = 10:
[MCU2_1] 4.389549 s: txMsg.data[11] = 11:
[MCU2_1] 4.389594 s: txMsg.data[12] = 12:
[MCU2_1] 4.389639 s: txMsg.data[13] = 13:
[MCU2_1] 4.389683 s: txMsg.data[14] = 14:
[MCU2_1] 4.389728 s: txMsg.data[15] = 15:
[MCU2_1] 4.389771 s: txMsg.data[16] = 16:
[MCU2_1] 4.389822 s: txMsg.data[17] = 17:
[MCU2_1] 4.389869 s: txMsg.data[18] = 18:
[MCU2_1] 4.389914 s: txMsg.data[19] = 19:
[MCU2_1] 4.389960 s: txMsg.data[20] = 20:
[MCU2_1] 4.390005 s: txMsg.data[21] = 21:
[MCU2_1] 4.390048 s: txMsg.data[22] = 22:
[MCU2_1] 4.390094 s: txMsg.data[23] = 23:
[MCU2_1] 4.390138 s: txMsg.data[24] = 24:
[MCU2_1] 4.390182 s: txMsg.data[25] = 25:
[MCU2_1] 4.390227 s: txMsg.data[26] = 26:
[MCU2_1] 4.390273 s: txMsg.data[27] = 27:
[MCU2_1] 4.390318 s: txMsg.data[28] = 28:
[MCU2_1] 4.390362 s: txMsg.data[29] = 29:
[MCU2_1] 4.390407 s: txMsg.data[30] = 30:
[MCU2_1] 4.390453 s: txMsg.data[31] = 31:
[MCU2_1] 4.390498 s: txMsg.data[32] = 32:
[MCU2_1] 4.390543 s: txMsg.data[33] = 33:
[MCU2_1] 4.390586 s: txMsg.data[34] = 34:
[MCU2_1] 4.390631 s: txMsg.data[35] = 35:
[MCU2_1] 4.390677 s: txMsg.data[36] = 36:
[MCU2_1] 4.390723 s: txMsg.data[37] = 37:
[MCU2_1] 4.390768 s: txMsg.data[38] = 38:
[MCU2_1] 4.390816 s: txMsg.data[39] = 39:
[MCU2_1] 4.390862 s: txMsg.data[40] = 40:
[MCU2_1] 4.390908 s: txMsg.data[41] = 41:
[MCU2_1] 4.390952 s: txMsg.data[42] = 42:
[MCU2_1] 4.390997 s: txMsg.data[43] = 43:
[MCU2_1] 4.391043 s: txMsg.data[44] = 44:
[MCU2_1] 4.391087 s: txMsg.data[45] = 45:
[MCU2_1] 4.391131 s: txMsg.data[46] = 46:
[MCU2_1] 4.391178 s: txMsg.data[47] = 47:
[MCU2_1] 4.391222 s: txMsg.data[48] = 48:
[MCU2_1] 4.391268 s: txMsg.data[49] = 49:
[MCU2_1] 4.391311 s: txMsg.data[50] = 50:
[MCU2_1] 4.391356 s: txMsg.data[51] = 51:
[MCU2_1] 4.391399 s: txMsg.data[52] = 52:
[MCU2_1] 4.391443 s: txMsg.data[53] = 53:
[MCU2_1] 4.391487 s: txMsg.data[54] = 54:
[MCU2_1] 4.391532 s: txMsg.data[55] = 55:
[MCU2_1] 4.391577 s: txMsg.data[56] = 56:
[MCU2_1] 4.391624 s: txMsg.data[57] = 57:
[MCU2_1] 4.391670 s: txMsg.data[58] = 58:
[MCU2_1] 4.391718 s: txMsg.data[59] = 59:
[MCU2_1] 4.391761 s: txMsg.data[60] = 60:
[MCU2_1] 4.391805 s: txMsg.data[61] = 61:
[MCU2_1] 4.391852 s: txMsg.data[62] = 62:
[MCU2_1] 4.391899 s: txMsg.data[63] = 63:
[MCU2_1] 4.391952 s: gMcanModAddr:0x40500000
[MCU2_1] 4.391993 s: MCANSS Revision ID:
[MCU2_1] 4.392032 s: scheme:0x1
[MCU2_1] 4.392067 s: Business Unit:0x2
[MCU2_1] 4.392106 s: Module ID:0x8e0
[MCU2_1] 4.392144 s: RTL Revision:0x9
[MCU2_1] 4.392182 s: Major Revision:0x1
[MCU2_1] 4.392221 s: Custom Revision:0x0
[MCU2_1] 4.392258 s: Minor Revision:0x1
[MCU2_1] 4.392300 s: CAN-FD operation is enabled through E-Fuse.
[MCU2_1] 4.392350 s: Endianess Value: 0x87654321
[MCU2_1] 4.392421 s:
[MCU2_1] 4.392452 s: Receiver Side application:
[MCU2_1] 4.392506 s: This test will receive 15 messages with various payload varying from 1byte to 64bytes.
[MCU2_1] 4.392563 s:
[MCU2_1] 4.392588 s: TestRx1..
[MCU2_1] 5.271622 s: Time Stamp overflow happened.
[MCU2_1] 5.271898 s: Time Stamp overflow happened.
[MCU2_1] 5.272058 s: Time Stamp overflow happened.
[MCU2_1] 5.272349 s: Time Stamp overflow happened.
[MCU2_1] 5.282736 s: Time Stamp overflow happened.
[MCU2_1] 5.293736 s: Time Stamp overflow happened.
[MCU2_1] 5.294260 s: Time Stamp overflow happened.
[MCU2_1] 5.294566 s: Time Stamp overflow happened.
[MCU2_1] 5.295091 s: Time Stamp overflow happened.
[MCU2_1] 5.295396 s: Time Stamp overflow happened.
[MCU2_1] 5.306052 s: Time Stamp overflow happened.
[MCU2_1] 5.306346 s: Time Stamp overflow happened.
[MCU2_1] 5.307738 s: Time Stamp overflow happened.
[MCU2_1] 5.308043 s: Time Stamp overflow happened.
[MCU2_1] 5.309735 s: Time Stamp overflow happened.
[MCU2_1] 5.321742 s: Time Stamp overflow happened.
[MCU2_1] 5.323739 s: Time Stamp overflow happened.
[MCU2_1] 5.324047 s: Time Stamp overflow happened.
[MCU2_1] 5.325739 s: Time Stamp overflow happened.
[MCU2_1] 5.331566 s: Time Stamp overflow happened.
[MCU2_1] 5.331632 s: Time Stamp overflow happened.
[MCU2_1] 5.331668 s: Time Stamp overflow happened.
[MCU2_1] 5.331729 s: Time Stamp overflow happened.
[MCU2_1] 5.331793 s: Time Stamp overflow happened.
[MCU2_1] 5.331857 s: Time Stamp overflow happened.
[MCU2_1] 5.331893 s: Time Stamp overflow happened.
[MCU2_1] 5.331954 s: Time Stamp overflow happened.
[MCU2_1] 5.332018 s: Time Stamp overflow happened.
[MCU2_1] 5.332082 s: Time Stamp overflow happened.
[MCU2_1] 5.332147 s: Time Stamp overflow happened.
[MCU2_1] 5.332210 s: Time Stamp overflow happened.
[MCU2_1] 5.332246 s: Time Stamp overflow happened.
[MCU2_1] 5.332308 s: Time Stamp overflow happened.
[MCU2_1] 5.332372 s: Time Stamp overflow happened.
[MCU2_1] 5.332436 s: Time Stamp overflow happened.
[MCU2_1] 5.332501 s: Time Stamp overflow happened.
[MCU2_1] 5.332566 s: Time Stamp overflow happened.
[MCU2_1] 5.332631 s: Time Stamp overflow happened.
[MCU2_1] 5.332695 s: Time Stamp overflow happened.
[MCU2_1] 5.332758 s: Time Stamp overflow happened.
[MCU2_1] 5.332794 s: Time Stamp overflow happened.
[MCU2_1] 5.332843 s: Time Stamp overflow happened.
[MCU2_1] 5.335307 s: Time Stamp overflow happened.
[MCU2_1] 5.335704 s: Time Stamp overflow happened.

code:
/*
* Copyright (c) Texas Instruments Incorporated 2016-2020
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the
* distribution.
*
* Neither the name of Texas Instruments Incorporated nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/

/**
* \file mcan_evm_loopback_app_main.c
*
* \brief This file contains MCAN sample code.
*
* \details This application is expected to be hosted on SoC/cores
* AM65xx / MCU 10
* J721E / MCU 10 and MCU 21
* J7200 / MCU 10 and MCU 21
* AM64x / MCU 10
*
* This application can operate as either an transmitter, receiver
* CAN nodes. Also, supports digital-loop back mode.
*
* This application with 2 board could be used to emulate 2 node
* CAN network. Where 1 node would be the transmitter and other
* would be receiver.
*
* In all modes MCAN operates in CAN-FD. Arbitration bit-rate and
* data phase bit-rate is set to 1Mbit/s and 5Mbit/s receptively.
*
*/

/* ========================================================================== */
/* Include Files */
/* ========================================================================== */

#include <stdint.h>
#include <stdio.h>
#include <ti/csl/csl_types.h>
#include <ti/csl/soc.h>
#include <ti/csl/hw_types.h>
#include <ti/csl/arch/csl_arch.h>
#include <ti/csl/csl_mcan.h>
#include <ti/drv/uart/UART.h>
#include <ti/drv/uart/UART_stdio.h>
#include <ti/osal/osal.h>
#include <ti/drv/gpio/GPIO.h>
#include <ti/drv/gpio/soc/GPIO_soc.h>
#include <ti/csl/csl_gpio.h>
#include <ti/board/board.h>
#include <ti/drv/i2c/I2C.h>
#include <utils/console_io/include/app_log.h>
#if defined (SOC_J721E) || defined (SOC_J7200) || defined (SOC_AM64X)
#include <ti/drv/sciclient/sciclient.h>
#endif

#ifdef UNITY_INCLUDE_CONFIG_H
#include <ti/build/unit-test/Unity/src/unity.h>
#include <ti/build/unit-test/config/unity_config.h>
#endif

/* ========================================================================== */
/* Macros */
/* ========================================================================== */
#if defined (SOC_AM65XX) || defined (SOC_AM64X)
#define APP_ENABLE_UART_PRINT (1U)
#elif defined (SOC_J721E) || defined (SOC_J7200)
#define APP_ENABLE_UART_PRINT (0U)
#endif

#define APP_MCAN_STD_ID_FILT_START_ADDR (0U)
#define APP_MCAN_STD_ID_FILTER_NUM (1U)
#define APP_MCAN_EXT_ID_FILT_START_ADDR (48U)
#define APP_MCAN_EXT_ID_FILTER_NUM (1U)
#define APP_MCAN_TX_EVENT_START_ADDR (100U)
#define APP_MCAN_TX_EVENT_SIZE (5U)
#define APP_MCAN_TX_BUFF_START_ADDR (148U)
#define APP_MCAN_TX_BUFF_SIZE (5U)
#define APP_MCAN_TX_FIFO_SIZE (5U)
#define APP_MCAN_FIFO_0_START_ADDR (548U)
#define APP_MCAN_FIFO_0_NUM (5U)
#define APP_MCAN_FIFO_1_START_ADDR (748U)
#define APP_MCAN_FIFO_1_NUM (5U)
#define APP_MCAN_RX_BUFF_START_ADDR (948U)

#define APP_MCAN_EXT_ID_AND_MASK (0x1FFFFFFFU)

#if defined (SOC_J721E) || defined (SOC_J7200)
#define APP_MCU_MCAN_0_INT0 (CSLR_MCU_R5FSS0_CORE0_INTR_MCU_MCAN0_MCANSS_MCAN_LVL_INT_0)
#define APP_MCU_MCAN_0_INT1 (CSLR_MCU_R5FSS0_CORE0_INTR_MCU_MCAN0_MCANSS_MCAN_LVL_INT_1)
#define APP_MCU_MCAN_0_TS_INT (CSLR_MCU_R5FSS0_CORE0_INTR_MCU_MCAN0_MCANSS_EXT_TS_ROLLOVER_LVL_INT_0)
#define APP_MCU_MCAN_1_INT0 (CSLR_MCU_R5FSS0_CORE0_INTR_MCU_MCAN1_MCANSS_MCAN_LVL_INT_0)
#define APP_MCU_MCAN_1_INT1 (CSLR_MCU_R5FSS0_CORE0_INTR_MCU_MCAN1_MCANSS_MCAN_LVL_INT_1)
#define APP_MCU_MCAN_1_TS_INT (CSLR_MCU_R5FSS0_CORE0_INTR_MCU_MCAN1_MCANSS_EXT_TS_ROLLOVER_LVL_INT_0)
#endif

#if defined (SOC_AM65XX)
#define APP_MCU_MCAN_0_INT0 (0U)
#define APP_MCU_MCAN_0_INT1 (1U)
#define APP_MCU_MCAN_0_TS_INT (4U)
#define APP_MCU_MCAN_1_INT0 (2U)
#define APP_MCU_MCAN_1_INT1 (3U)
#define APP_MCU_MCAN_1_TS_INT (5U)
#endif

#if defined (SOC_J7200)
#if defined (BUILD_MCU2_1)
#define APP_MAIN_MCAN_2_INT0 (CSLR_MCU_R5FSS0_CORE0_INTR_MAIN2MCU_LVL_INTRTR0_OUTL_0 + 28U)
#define APP_MAIN_MCAN_2_INT1 (CSLR_MCU_R5FSS0_CORE0_INTR_MAIN2MCU_LVL_INTRTR0_OUTL_0 + 29U)
#define APP_MAIN_MCAN_2_TS_INT (CSLR_MCU_R5FSS0_CORE0_INTR_MAIN2MCU_LVL_INTRTR0_OUTL_0 + 30U)
#else
/* Main Domain Instances */
#define APP_MAIN_MCAN_0_INT0 (CSLR_R5FSS0_CORE0_INTR_MCAN0_MCANSS_MCAN_LVL_INT_0)
#define APP_MAIN_MCAN_0_INT1 (CSLR_R5FSS0_CORE0_INTR_MCAN0_MCANSS_MCAN_LVL_INT_1)
#define APP_MAIN_MCAN_0_TS_INT (CSLR_R5FSS0_CORE0_INTR_MCAN0_MCANSS_EXT_TS_ROLLOVER_LVL_INT_0)
#define APP_MAIN_MCAN_2_INT0 (CSLR_R5FSS0_CORE0_INTR_MCAN2_MCANSS_MCAN_LVL_INT_0)
#define APP_MAIN_MCAN_2_INT1 (CSLR_R5FSS0_CORE0_INTR_MCAN2_MCANSS_MCAN_LVL_INT_1)
#define APP_MAIN_MCAN_2_TS_INT (CSLR_R5FSS0_CORE0_INTR_MCAN2_MCANSS_EXT_TS_ROLLOVER_LVL_INT_0)
#define APP_MAIN_MCAN_4_INT0 (CSLR_R5FSS0_CORE0_INTR_MCAN4_MCANSS_MCAN_LVL_INT_0)
#define APP_MAIN_MCAN_4_INT1 (CSLR_R5FSS0_CORE0_INTR_MCAN4_MCANSS_MCAN_LVL_INT_1)
#define APP_MAIN_MCAN_4_TS_INT (CSLR_R5FSS0_CORE0_INTR_MCAN4_MCANSS_EXT_TS_ROLLOVER_LVL_INT_0)
#define APP_MAIN_MCAN_5_INT0 (CSLR_R5FSS0_CORE0_INTR_MCAN5_MCANSS_MCAN_LVL_INT_0)
#define APP_MAIN_MCAN_5_INT1 (CSLR_R5FSS0_CORE0_INTR_MCAN5_MCANSS_MCAN_LVL_INT_1)
#define APP_MAIN_MCAN_5_TS_INT (CSLR_R5FSS0_CORE0_INTR_MCAN5_MCANSS_EXT_TS_ROLLOVER_LVL_INT_0)
#define APP_MAIN_MCAN_6_INT0 (CSLR_R5FSS0_CORE0_INTR_MCAN6_MCANSS_MCAN_LVL_INT_0)
#define APP_MAIN_MCAN_6_INT1 (CSLR_R5FSS0_CORE0_INTR_MCAN6_MCANSS_MCAN_LVL_INT_1)
#define APP_MAIN_MCAN_6_TS_INT (CSLR_R5FSS0_CORE0_INTR_MCAN6_MCANSS_EXT_TS_ROLLOVER_LVL_INT_0)
#define APP_MAIN_MCAN_7_INT0 (CSLR_R5FSS0_CORE0_INTR_MCAN7_MCANSS_MCAN_LVL_INT_0)
#define APP_MAIN_MCAN_7_INT1 (CSLR_R5FSS0_CORE0_INTR_MCAN7_MCANSS_MCAN_LVL_INT_1)
#define APP_MAIN_MCAN_7_TS_INT (CSLR_R5FSS0_CORE0_INTR_MCAN7_MCANSS_EXT_TS_ROLLOVER_LVL_INT_0)
#define APP_MAIN_MCAN_9_INT0 (CSLR_R5FSS0_CORE0_INTR_MCAN9_MCANSS_MCAN_LVL_INT_0)
#define APP_MAIN_MCAN_9_INT1 (CSLR_R5FSS0_CORE0_INTR_MCAN9_MCANSS_MCAN_LVL_INT_1)
#define APP_MAIN_MCAN_9_TS_INT (CSLR_R5FSS0_CORE0_INTR_MCAN9_MCANSS_EXT_TS_ROLLOVER_LVL_INT_0)
#define APP_MAIN_MCAN_11_INT0 (CSLR_R5FSS0_CORE0_INTR_MCAN11_MCANSS_MCAN_LVL_INT_0)
#define APP_MAIN_MCAN_11_INT1 (CSLR_R5FSS0_CORE0_INTR_MCAN11_MCANSS_MCAN_LVL_INT_1)
#define APP_MAIN_MCAN_11_TS_INT (CSLR_R5FSS0_CORE0_INTR_MCAN11_MCANSS_EXT_TS_ROLLOVER_LVL_INT_0)
#endif /* MCU */
#endif

#if defined (SOC_J721E)
#if defined (BUILD_MCU2_1)
#define APP_MAIN_MCAN_2_INT0 (CSLR_MCU_R5FSS0_CORE0_INTR_MAIN2MCU_LVL_INTRTR0_OUTL_0 + 28U)
#define APP_MAIN_MCAN_2_INT1 (CSLR_MCU_R5FSS0_CORE0_INTR_MAIN2MCU_LVL_INTRTR0_OUTL_1 + 29U)
#define APP_MAIN_MCAN_2_TS_INT (CSLR_MCU_R5FSS0_CORE0_INTR_MAIN2MCU_LVL_INTRTR0_OUTL_2 + 30U)
#else
#define APP_MAIN_MCAN_0_INT0 (CSLR_R5FSS1_CORE0_INTR_MCAN0_MCANSS_MCAN_LVL_INT_0)
#define APP_MAIN_MCAN_0_INT1 (CSLR_R5FSS1_CORE0_INTR_MCAN0_MCANSS_MCAN_LVL_INT_1)
#define APP_MAIN_MCAN_0_TS_INT (CSLR_R5FSS1_CORE0_INTR_MCAN0_MCANSS_EXT_TS_ROLLOVER_LVL_INT_0)
#define APP_MAIN_MCAN_2_INT0 (CSLR_R5FSS1_CORE0_INTR_MCAN2_MCANSS_MCAN_LVL_INT_0)
#define APP_MAIN_MCAN_2_INT1 (CSLR_R5FSS1_CORE0_INTR_MCAN2_MCANSS_MCAN_LVL_INT_1)
#define APP_MAIN_MCAN_2_TS_INT (CSLR_R5FSS1_CORE0_INTR_MCAN2_MCANSS_EXT_TS_ROLLOVER_LVL_INT_0)
#define APP_MAIN_MCAN_4_INT0 (CSLR_R5FSS1_CORE0_INTR_MCAN4_MCANSS_MCAN_LVL_INT_0)
#define APP_MAIN_MCAN_4_INT1 (CSLR_R5FSS1_CORE0_INTR_MCAN4_MCANSS_MCAN_LVL_INT_1)
#define APP_MAIN_MCAN_4_TS_INT (CSLR_R5FSS1_CORE0_INTR_MCAN4_MCANSS_EXT_TS_ROLLOVER_LVL_INT_0)
#define APP_MAIN_MCAN_5_INT0 (CSLR_R5FSS1_CORE0_INTR_MCAN5_MCANSS_MCAN_LVL_INT_0)
#define APP_MAIN_MCAN_5_INT1 (CSLR_R5FSS1_CORE0_INTR_MCAN5_MCANSS_MCAN_LVL_INT_1)
#define APP_MAIN_MCAN_5_TS_INT (CSLR_R5FSS1_CORE0_INTR_MCAN5_MCANSS_EXT_TS_ROLLOVER_LVL_INT_0)
#define APP_MAIN_MCAN_6_INT0 (CSLR_R5FSS1_CORE0_INTR_MCAN6_MCANSS_MCAN_LVL_INT_0)
#define APP_MAIN_MCAN_6_INT1 (CSLR_R5FSS1_CORE0_INTR_MCAN6_MCANSS_MCAN_LVL_INT_1)
#define APP_MAIN_MCAN_6_TS_INT (CSLR_R5FSS1_CORE0_INTR_MCAN6_MCANSS_EXT_TS_ROLLOVER_LVL_INT_0)
#define APP_MAIN_MCAN_7_INT0 (CSLR_R5FSS1_CORE0_INTR_MCAN7_MCANSS_MCAN_LVL_INT_0)
#define APP_MAIN_MCAN_7_INT1 (CSLR_R5FSS1_CORE0_INTR_MCAN7_MCANSS_MCAN_LVL_INT_1)
#define APP_MAIN_MCAN_7_TS_INT (CSLR_R5FSS1_CORE0_INTR_MCAN7_MCANSS_EXT_TS_ROLLOVER_LVL_INT_0)
#define APP_MAIN_MCAN_9_INT0 (CSLR_R5FSS1_CORE0_INTR_MCAN9_MCANSS_MCAN_LVL_INT_0)
#define APP_MAIN_MCAN_9_INT1 (CSLR_R5FSS1_CORE0_INTR_MCAN9_MCANSS_MCAN_LVL_INT_1)
#define APP_MAIN_MCAN_9_TS_INT (CSLR_R5FSS1_CORE0_INTR_MCAN9_MCANSS_EXT_TS_ROLLOVER_LVL_INT_0)
#define APP_MAIN_MCAN_11_INT0 (CSLR_R5FSS1_CORE0_INTR_MCAN11_MCANSS_MCAN_LVL_INT_0)
#define APP_MAIN_MCAN_11_INT1 (CSLR_R5FSS1_CORE0_INTR_MCAN11_MCANSS_MCAN_LVL_INT_1)
#define APP_MAIN_MCAN_11_TS_INT (CSLR_R5FSS1_CORE0_INTR_MCAN11_MCANSS_EXT_TS_ROLLOVER_LVL_INT_0)
#endif
#endif

#if defined (SOC_AM64X)
#define APP_MCU_MCAN_0_INT0 (CSLR_R5FSS0_CORE0_INTR_MCAN0_MCANSS_MCAN_LVL_INT_0)
#define APP_MCU_MCAN_0_INT1 (CSLR_R5FSS0_CORE0_INTR_MCAN0_MCANSS_MCAN_LVL_INT_1)
#define APP_MCU_MCAN_0_TS_INT (CSLR_R5FSS0_CORE0_INTR_MCAN0_MCANSS_EXT_TS_ROLLOVER_LVL_INT_0)
#define APP_MCU_MCAN_1_INT0 (CSLR_R5FSS0_CORE0_INTR_MCAN1_MCANSS_MCAN_LVL_INT_0)
#define APP_MCU_MCAN_1_INT1 (CSLR_R5FSS0_CORE0_INTR_MCAN1_MCANSS_MCAN_LVL_INT_1)
#define APP_MCU_MCAN_1_TS_INT (CSLR_R5FSS0_CORE0_INTR_MCAN1_MCANSS_EXT_TS_ROLLOVER_LVL_INT_0)
#endif

/* Print buffer character limit for prints- UART or CCS Console */
#define APP_PRINT_BUFFER_SIZE (4000U)

#if defined (SOC_AM65XX)
/* Port and pin number mask for GPIO Load pin.
Bits 7-0: Pin number and Bits 15-8: Port number */
#define AM65XX_IDK_GPIO_CAN0_STB_PIN (0x012F)
#define AM65XX_IDK_GPIO_CAN1_STB_PIN (0x0143)
#endif

#if defined (SOC_J721E)
#define J721E_GPIO_GESI_CAN_STB_PIN (0x003C)
#define J721E_GPIO_MAIN_MCAN2_STB_PIN (0x007F)
#endif

#if defined (SOC_J7200)
#define J721E_GPIO_GESI_CAN_STB_PIN (0x003C)
#define J721E_GPIO_MAIN_MCAN2_STB_PIN (0x007F)
#endif

/* ========================================================================== */
/* Global Variables */
/* ========================================================================== */

uint32_t gMcanAppdataSize[16] =
{0, 1, 2, 3, 4, 5, 6, 7, 8, 12, 16, 20, 24, 32, 48, 64};
volatile uint32_t gMcanIsrIntr0Flag = 1U;
volatile uint32_t gMcanIsrIntr1Flag = 1U;
MCAN_ECCErrStatus gMcaneccErr;

uint32_t gMcanModAddr;
/**< Global variable to hold the address of mcan that's used in example */
/**
* \brief Supported instances in this example for MCU & MAIN Domain */
static uint32_t gMcanMods[] =
{
#if defined(SOC_AM65XX) || ( defined(SOC_J721E) || defined(SOC_J7200) ) && defined(BUILD_MCU2_1)
CSL_MCU_MCAN0_MSGMEM_RAM_BASE,
CSL_MCU_MCAN1_MSGMEM_RAM_BASE,
#endif

#if ( defined(SOC_J721E) || defined(SOC_J7200) )
CSL_MCAN9_MSGMEM_RAM_BASE,
CSL_MCAN0_MSGMEM_RAM_BASE,
CSL_MCAN2_MSGMEM_RAM_BASE,
#endif

#if ( defined(SOC_J721E) || defined(SOC_J7200) ) && defined(BUILD_MCU2_1)
CSL_MCAN9_MSGMEM_RAM_BASE,
CSL_MCAN0_MSGMEM_RAM_BASE,
CSL_MCAN2_MSGMEM_RAM_BASE,
CSL_MCAN4_MSGMEM_RAM_BASE,
CSL_MCAN5_MSGMEM_RAM_BASE,
CSL_MCAN6_MSGMEM_RAM_BASE,
CSL_MCAN7_MSGMEM_RAM_BASE,
CSL_MCAN9_MSGMEM_RAM_BASE,
CSL_MCAN11_MSGMEM_RAM_BASE,
#endif

#if defined(SOC_AM64X)
CSL_MCAN0_MSGMEM_RAM_BASE,
CSL_MCAN1_MSGMEM_RAM_BASE,
#endif
};
static char *gMcanModsNames[] =
{
#if defined(SOC_AM65XX) || ( defined(SOC_J721E) || defined(SOC_J7200) ) && defined(BUILD_MCU2_1)
"MCU_MCAN0",
"MCU_MCAN1",
#endif
#if ( defined(SOC_J721E) || defined(SOC_J7200) )
"MAIN_MCAN9 (GESI Exp Board)",
"MAIN_MCAN0",
"MAIN_MCAN2",
#endif
#if ( defined(SOC_J721E) || defined(SOC_J7200) ) && defined(BUILD_MCU2_1)
"MAIN_MCAN0",
"MAIN_MCAN2",
"MAIN_MCAN4 (GESI Exp Board)",
"MAIN_MCAN5 (GESI Exp Board)",
"MAIN_MCAN6 (GESI Exp Board)",
"MAIN_MCAN7 (GESI Exp Board)",
"MAIN_MCAN9 (GESI Exp Board)",
"MAIN_MCAN11 (GESI Exp Board)",
#endif
#if defined(SOC_AM64X)
"MCAN0",
"MCAN1",
#endif
};

#if defined (SOC_AM65XX)
/* GPIO Driver board specific pin configuration structure */
GPIO_PinConfig gpioPinConfigs[] = {
/* Output pin : AM65XX_IDK */
AM65XX_IDK_GPIO_CAN0_STB_PIN | GPIO_CFG_OUTPUT,
AM65XX_IDK_GPIO_CAN1_STB_PIN | GPIO_CFG_OUTPUT
};
#endif

#if defined(SOC_J721E) || defined(SOC_J7200)
/* GPIO Driver board specific pin configuration structure */
GPIO_PinConfig gpioPinConfigs[] = {
/* Output pin : CAN STB */
J721E_GPIO_GESI_CAN_STB_PIN | GPIO_CFG_OUTPUT,
J721E_GPIO_MAIN_MCAN2_STB_PIN | GPIO_CFG_OUTPUT,
};
#endif

#if defined (SOC_AM65XX) || defined(SOC_J721E) || defined(SOC_J7200)
/* GPIO Driver call back functions */
GPIO_CallbackFxn gpioCallbackFunctions[] = {
NULL
};

/* GPIO Driver configuration structure */
GPIO_v0_Config GPIO_v0_config = {
gpioPinConfigs,
gpioCallbackFunctions,
sizeof(gpioPinConfigs) / sizeof(GPIO_PinConfig),
sizeof(gpioCallbackFunctions) / sizeof(GPIO_CallbackFxn),
0,
};
#endif

/* ========================================================================== */
/* Internal Function Declarations */
/* ========================================================================== */

/**
* \brief This function will configure MCAN module
*
* \param none.
*
* \retval status configuration status.
*/
static int32_t App_mcanConfig(bool enableInternalLpbk);

/**
* \brief This function will configure X-BAR for MCAN interrupts
*
* \param MCAN Instance address
*
* \retval status configuration status.
*/
static int32_t App_mcanRegisterIsr(uint32_t mcanInstAddr);

/**
* \brief This is Interrupt Service Routine for MCAN interrupt 0.
*
* \param none.
*
* \retval none.
*/
static void App_mcanIntr0ISR(uintptr_t arg);

/**
* \brief This is Interrupt Service Routine for MCAN interrupt 1.
*
* \param none.
*
* \retval none.
*/
static void App_mcanIntr1ISR(uintptr_t arg);

/**
* \brief This is Interrupt Service Routine for MCAN TimeStamp interrupt.
*
* \param none.
*
* \retval none.
*/
static void App_mcanTSIntrISR(uintptr_t arg);

/**
* \brief This API will MCAN Rx Msg.
*
* \param rxMsg received message object.
*
* \retval none.
*/
static void App_mcanPrintRxMsg(const MCAN_RxBufElement *rxMsg);

/**
* \brief This API will MCAN Tx Msg.
*
* \param txMsg message object to be transmitted.
*
* \retval none.
*/
static void App_mcanPrintTxMsg(const MCAN_TxBufElement *txMsg);

/**
* \brief This API will load the register from ECC memory bank.
*
* \param txMsg message object to be transmitted.
*
* \return None.
*/
static void APP_mcanTxTest(MCAN_TxBufElement *txMsg);

/**
* \brief This API will load the register from ECC memory bank.
*
* \param txMsg message object to be transmitted
* (Needed for Message validation).
*
* \return None.
*/
static void APP_mcanRxTest(const MCAN_TxBufElement *txMsg);

/**
* \brief This function will transmit fixed pattern and expects to receive
* the same
*
* \param txMsg message object to be transmitted.
*
* \return None.
*/
static void APP_mcanLpbkTest(MCAN_TxBufElement *txMsg);

/**
* \brief This API will print on UART/CCS Console.
*
* \param pcString string to be printed.
*
* \return None.
*/
void App_ConsolePrintf(const char *pcString, ...);

/**
* \brief This API will get a number from UART/CCS Console.
*
* \param num get the user input.
*
* \return None.
*/
static void App_ConsoleGetNum(uint32_t *num);

static int32_t App_mcanRegisterInterrupt(uint32_t intNum, void f(uintptr_t));

#if defined (BUILD_MCU2_1)
#if defined (SOC_J721E) || defined (SOC_J7200)
static int32_t App_mcanCfgIrqRouterMain2Mcu(uint32_t devId, uint32_t offset, uint32_t intNum);
#endif
#endif

#if defined(UNITY_INCLUDE_CONFIG_H)
void test_csl_mcan_evm_loopback_app(void);
void test_csl_mcan_evm_loopback_app_runner(void);
#endif

/* ========================================================================== */
/* Function Definitions */
/* ========================================================================== */
#define TCA6424_CMD_AUTO_INC ((uint8_t) 0x80U)

/* Input status register */
#define TCA6424_REG_INPUT0 ((UInt8) 0x00U)
#define TCA6424_REG_INPUT1 ((UInt8) 0x01U)
#define TCA6424_REG_INPUT2 ((UInt8) 0x02U)

/* Output register to change state of output BIT set to 1, output set HIGH */
#define TCA6424_REG_OUTPUT0 ((uint8_t) 0x04U)
#define TCA6424_REG_OUTPUT1 ((uint8_t) 0x05U)
#define TCA6424_REG_OUTPUT2 ((uint8_t) 0x06U)

/* Configuration register. BIT = '1' sets port to input, BIT = '0' sets
* port to output */
#define TCA6424_REG_CONFIG0 ((uint8_t) 0x0CU)
#define TCA6424_REG_CONFIG1 ((uint8_t) 0x0DU)
#define TCA6424_REG_CONFIG2 ((uint8_t) 0x0EU)

void SetupI2CTransfer(I2C_Handle handle, uint32_t slaveAddr,
uint8_t *writeData, uint32_t numWriteBytes,
uint8_t *readData, uint32_t numReadBytes)
{
bool status;
I2C_Transaction i2cTransaction;

I2C_transactionInit(&i2cTransaction);
i2cTransaction.slaveAddress = slaveAddr;
i2cTransaction.writeBuf = (uint8_t *)&writeData[0];
i2cTransaction.writeCount = numWriteBytes;
i2cTransaction.readBuf = (uint8_t *)&readData[0];
i2cTransaction.readCount = numReadBytes;
status = I2C_transfer(handle, &i2cTransaction);
if(FALSE == status)
{

appLogPrintf("Data Transfer failed. \n");
}
}

void padConfig_prcmEnable()
{
/* UART Init */
Board_initCfg boardCfg;
Board_STATUS boardStatus;
#if 0
#if defined (SOC_J721E) || defined (SOC_J7200) || defined (SOC_AM64X)
I2C_Params i2cParams;
I2C_Handle handle = NULL;
uint8_t dataToSlave[4];
#endif
#endif
boardCfg = BOARD_INIT_MODULE_CLOCK |
BOARD_INIT_PINMUX_CONFIG;
#if (APP_ENABLE_UART_PRINT == 1)
boardCfg |= BOARD_INIT_UART_STDIO;
#endif
boardStatus = Board_init(boardCfg);
appLogPrintf("Board_init Done \n");

if (boardStatus != BOARD_SOK)
{
App_ConsolePrintf("[Error] Board init failed!!\n");
}

#if defined (SOC_J721E) || defined (SOC_J7200)
/* Pin mux for CAN STB used in GESI board */
*(volatile unsigned int *)(0x0011c0f4) = 0x20007;
/* Pinmux for MAIN_MCAN4 */
*(volatile unsigned int *)(0x0011c020) = 0x60006;
*(volatile unsigned int *)(0x0011c024) = 0x60006;
/* Pinmux for MAIN_MCAN5 */
*(volatile unsigned int *)(0x0011c04c) = 0x60006;
*(volatile unsigned int *)(0x0011c050) = 0x60006;
/* Pinmux for MAIN_MCAN6 */
*(volatile unsigned int *)(0x0011c054) = 0x60006;
*(volatile unsigned int *)(0x0011c06C) = 0x60006;
/* Pinmux for MAIN_MCAN7 */
*(volatile unsigned int *)(0x0011c074) = 0x60006;
*(volatile unsigned int *)(0x0011c078) = 0x60006;
/* Pinmux for MAIN_MCAN9 */
*(volatile unsigned int *)(0x0011c0cc) = 0x60006;
*(volatile unsigned int *)(0x0011c0d0) = 0x60006;
/* Pinmux for MAIN_MCAN11 */
*(volatile unsigned int *)(0x0011c11c) = 0x60006;
*(volatile unsigned int *)(0x0011c120) = 0x60006;
#endif

#if defined (SOC_AM65XX) || defined(SOC_J721E) || defined(SOC_J7200)
/* GPIO initialization */
GPIO_init();
appLogPrintf("GPIO_init Done \n");

#endif

/* Enable CAN transceivers by setting the STB pins */
#if defined (SOC_AM65XX)
GPIO_write(0, GPIO_PIN_HIGH);
GPIO_write(1, GPIO_PIN_HIGH);
#elif defined (SOC_J721E) || defined (SOC_J7200)
/* Enable the TCAN on GESI board.
* Main Domain MCAN instances 4,5,6,7,9,11.
*/
GPIO_write(0, GPIO_PIN_LOW);

/* Enable MCU MCAN 1, WKUP_GPIO0_2. */
GPIOSetDirMode_v0(CSL_WKUP_GPIO0_BASE, 2, GPIO_DIRECTION_OUTPUT);
GPIOPinWrite_v0(CSL_WKUP_GPIO0_BASE, 2, GPIO_PIN_LOW);

/* Enable MCU MCAN 0, WKUP_GPIO0_0, WKUP_GPIO0_54 */
GPIOSetDirMode_v0(CSL_WKUP_GPIO0_BASE, 0, GPIO_DIRECTION_OUTPUT);
GPIOPinWrite_v0(CSL_WKUP_GPIO0_BASE, 0, GPIO_PIN_HIGH);
GPIOSetDirMode_v0(CSL_WKUP_GPIO0_BASE, 54, GPIO_DIRECTION_OUTPUT);
GPIOPinWrite_v0(CSL_WKUP_GPIO0_BASE, 54, GPIO_PIN_HIGH);

/* Enable Main MCAN 2, GPIO0_127. */
GPIO_write(1, GPIO_PIN_LOW);

/*
* Configuring TCA6424 IO Exp 2 with addr 0x22
* This io expander is controlled by i2c0
* For Main MCAN2 P13 and P14 should be set to 0, This should route the MCAN2 STB line to transciver.
* For Main MCAN0 P06 and P07 should be set to 1.
*/
/* I2C initialization */
#if 0
I2C_init();

uint8_t test_count = 1;
appLogPrintf("I2C_init (%d)\n", test_count++);

I2C_Params_init(&i2cParams);
i2cParams.transferMode = I2C_MODE_BLOCKING;
i2cParams.bitRate = I2C_400kHz;
i2cParams.transferCallbackFxn = NULL;

appLogPrintf("I2C_init (%d)\n", test_count++);

handle = I2C_open(0U, &i2cParams);

dataToSlave[0] = TCA6424_REG_CONFIG0 | TCA6424_CMD_AUTO_INC;
dataToSlave[1] = 0x0U;
SetupI2CTransfer(handle, 0x22, &dataToSlave[0], 2, NULL, 0);
appLogPrintf("I2C_init (%d)\n", test_count++);

dataToSlave[0] = TCA6424_REG_INPUT0 | TCA6424_CMD_AUTO_INC;
dataToSlave[1] = 0x0U;
dataToSlave[2] = 0x0U;
dataToSlave[3] = 0x0U;
SetupI2CTransfer(handle, 0x22, &dataToSlave[0], 1, &dataToSlave[1], 3);
appLogPrintf("I2C_init (%d)\n", test_count++);

/* Set P06 and P07 to 1.
* Set P13 and P14 to 0.
*/
// dataToSlave[0] = TCA6424_REG_OUTPUT0 | TCA6424_CMD_AUTO_INC;
// dataToSlave[1] |= 0xC0;
// dataToSlave[2] &= ~(0x18);
// SetupI2CTransfer(handle, 0x22, &dataToSlave[0], 1, &dataToSlave[1], 3);
// appLogPrintf("I2C_init (%d)\n", test_count++);
#endif
#elif defined (SOC_AM64X)
/*
* Configuring TCA6424 IO Exp with addr 0x22
* This io expander is controlled by i2c1
* P10 and P11 should be set to 0
*/
/* I2C initialization */
#if 1
I2C_init();
I2C_Params_init(&i2cParams);
i2cParams.transferMode = I2C_MODE_BLOCKING;
i2cParams.bitRate = I2C_400kHz;
i2cParams.transferCallbackFxn = NULL;

handle = I2C_open(1U, &i2cParams);
dataToSlave[0] = TCA6424_REG_CONFIG1 | TCA6424_CMD_AUTO_INC;
dataToSlave[1] = 0x0U;
SetupI2CTransfer(handle, 0x22, &dataToSlave[0], 1, &dataToSlave[1], 1);
appLogPrintf("I2C_init (%d)\n", test_count++);

/* set the P10 and P11 to 0 make them output ports. */
dataToSlave[1] &= ~(0x3U);
SetupI2CTransfer(handle, 0x22, &dataToSlave[0], 2, NULL, 0);
appLogPrintf("I2C_init (%d)\n", test_count++);

/* Get the port values. */
dataToSlave[0] = TCA6424_REG_INPUT1 | TCA6424_CMD_AUTO_INC;
dataToSlave[1] = 0x0U;
SetupI2CTransfer(handle, 0x22, &dataToSlave[0], 1, &dataToSlave[1], 1);
appLogPrintf("I2C_init (%d)\n", test_count++);

/* Set P10 and P11 to 0.
*/
dataToSlave[0] = TCA6424_REG_OUTPUT1 | TCA6424_CMD_AUTO_INC;
dataToSlave[1] &= ~(0x3);
SetupI2CTransfer(handle, 0x22, &dataToSlave[0], 2, NULL, 0);
appLogPrintf("I2C_init (%d)\n", test_count++);
#endif
#endif
}

void test_csl_mcan_evm_loopback_app(void)
{
int32_t configStatus = CSL_PASS;

// MAIN_MCAN0(0), MAIN_MCAN2(1),
uint32_t mcanChNo = 0U;

// loopback mode(3), transmitter(1), receiver(2)
uint32_t mcanChMode = 1U;

uint32_t loopCnt = 0U;
MCAN_TxBufElement txMsg;
uint32_t numInst;

/* Do Pad Config for UART and MCAN */
padConfig_prcmEnable();

App_ConsolePrintf("\n Starting Application...\n");
App_ConsolePrintf("Available MCAN Module for usage:\n");

//numInst is 1;
numInst = sizeof(gMcanMods)/sizeof(gMcanMods[0]);

for (loopCnt = 0U ; loopCnt < numInst ; loopCnt++)
{
App_ConsolePrintf("%d. BA: 0x%x - %s.\n",
loopCnt,
gMcanMods[loopCnt],
gMcanModsNames[loopCnt]);
}

App_ConsolePrintf("Enter MCAN Module to use:\n");
App_ConsoleGetNum(&mcanChNo);

if (mcanChNo >= numInst)
{
App_ConsolePrintf("Read from UART/CCS Console failed\n");
#if defined (UNITY_INCLUDE_CONFIG_H)
TEST_FAIL();
#endif
return;
}
else
{
gMcanModAddr = gMcanMods[mcanChNo];
App_ConsolePrintf("gMcanModAddr = gMcanMods[0] = 0x%x\n", gMcanMods[mcanChNo]);
}

App_ConsolePrintf("MCAN Clock Configuration Successful.\n");

App_ConsolePrintf("MCAN Node Type:\n");
App_ConsolePrintf("1. Transmitter Side.\n");
App_ConsolePrintf("2. Receiver Side.\n");
App_ConsolePrintf("3. Loopback - no external transmission/reception \n");
App_ConsolePrintf("Enter type of the node:\n");
App_ConsoleGetNum(&mcanChNo);

/* CrossBar Configuration */
configStatus = App_mcanRegisterIsr(gMcanModAddr);

/* Initialize message to transmit */
txMsg.id = (uint32_t)((uint32_t)(0x4U) << 18U);
txMsg.rtr = 0U;
txMsg.xtd = 0U;
txMsg.esi = 0U;
txMsg.dlc = 0xFU;
txMsg.brs = 1U;
txMsg.fdf = 1U;
txMsg.efc = 1U;
txMsg.mm = 0xAAU;
App_ConsolePrintf("Initialize message to transmit.. Done..\n");

for (loopCnt = 0; loopCnt < MCAN_MAX_PAYLOAD_BYTES; loopCnt++)
{
txMsg.data[loopCnt] = loopCnt;
App_ConsolePrintf("txMsg.data[%d] = %d:\n", loopCnt, txMsg.data[loopCnt]);
}

if (3 != mcanChMode)
{
configStatus = App_mcanConfig(FALSE);
}
else
{
configStatus = App_mcanConfig(TRUE);
}


if (CSL_PASS == configStatus)
{
switch (mcanChMode)
{
App_ConsolePrintf("Switch mcanChMode %d\n", mcanChMode);
case 1:
/* This is transmitter side application */
App_ConsolePrintf("\nTransmitter Side application:\n");
App_ConsolePrintf(
"This test will send 15 messages with various payload varying from 1byte to 64bytes.\n"
);
App_ConsolePrintf("Message Object:\n");
App_mcanPrintTxMsg(&txMsg);
APP_mcanTxTest(&txMsg);
break;

case 2:
/* This is receiver side application */
App_ConsolePrintf("\nReceiver Side application:\n");
App_ConsolePrintf(
"This test will receive 15 messages with various payload varying from 1byte to 64bytes.\n"
);
APP_mcanRxTest(&txMsg);
break;

case 3:
App_ConsolePrintf("\nLoop back application:\n");
App_ConsolePrintf(
"This test will send 15 messages with various payload varying from 1byte to 64bytes.\n"
);
App_ConsolePrintf(
"This test will attempt to receive 15 messages with various payload varying from 1byte to 64bytes.\n"
);
App_ConsolePrintf("Message Object:\n");
App_mcanPrintTxMsg(&txMsg);
APP_mcanLpbkTest(&txMsg);
break;

default:
App_ConsolePrintf("Wrong option...\n");
break;
}
}
App_ConsolePrintf("\n Application is completed.\n");

#if defined (UNITY_INCLUDE_CONFIG_H)
TEST_PASS();
#endif
return;
}

/* ========================================================================== */
/* Internal Function Definitions */
/* ========================================================================== */
static int32_t App_mcanRegisterInterrupt(uint32_t intNum, void f(uintptr_t))
{
int32_t configStatus = STW_SOK;
OsalRegisterIntrParams_t intrPrms;
OsalInterruptRetCode_e osalRetVal;
HwiP_Handle hwiHandle = NULL;

/* Enable CPU Interrupts and register ISR - MCAN0 Intr0 */
Osal_RegisterInterrupt_initParams(&intrPrms);
/* Populate the interrupt parameters */
intrPrms.corepacConfig.arg = (uintptr_t) NULL;
intrPrms.corepacConfig.isrRoutine = f;
intrPrms.corepacConfig.priority = 0U;
intrPrms.corepacConfig.corepacEventNum = 0U;
intrPrms.corepacConfig.intVecNum = intNum;

/* Register interrupts */
osalRetVal = Osal_RegisterInterrupt(&intrPrms, &hwiHandle);
if(OSAL_INT_SUCCESS != osalRetVal)
{
configStatus = CSL_EFAIL;
}
return configStatus;
}

#if defined (BUILD_MCU2_1)
#if defined (SOC_J721E) || defined (SOC_J7200)
static int32_t App_mcanCfgIrqRouterMain2Mcu(uint32_t devId, uint32_t offset, uint32_t intNum)
{
int32_t retVal;
struct tisci_msg_rm_irq_set_req rmIrqReq;
struct tisci_msg_rm_irq_set_resp rmIrqResp;

rmIrqReq.valid_params = TISCI_MSG_VALUE_RM_DST_ID_VALID;
rmIrqReq.valid_params |= TISCI_MSG_VALUE_RM_DST_HOST_IRQ_VALID;
rmIrqReq.src_id = devId;
rmIrqReq.global_event = 0U;
rmIrqReq.src_index = offset;
rmIrqReq.dst_id = TISCI_DEV_MCU_R5FSS0_CORE0;
rmIrqReq.dst_host_irq = intNum;
rmIrqReq.ia_id = 0U;
rmIrqReq.vint = 0U;
rmIrqReq.vint_status_bit_index = 0U;
rmIrqReq.secondary_host = TISCI_MSG_VALUE_RM_UNUSED_SECONDARY_HOST;
retVal = Sciclient_rmIrqSet(&rmIrqReq, &rmIrqResp, SCICLIENT_SERVICE_WAIT_FOREVER);
if(CSL_PASS != retVal)
{
App_ConsolePrintf("Error in SciClient Interrupt Params Configuration!!!");
App_ConsolePrintf("offset: %d \n", offset);
}
else
{
App_ConsolePrintf("SciClient Interrupt Params Configuration passed for offset: %d \n", offset);
}
return retVal;
}
#endif /* Platform specifc */
#endif /* MCU 10 only */

static int32_t App_mcanRegisterIsr(uint32_t mcanInstAddr)
{
int32_t configStatus = STW_SOK;

#if defined (BUILD_MCU2_1)
App_ConsolePrintf("check BUILD_MCU2_1 App_mcanRegisterIsr()");
/* Running Code from Mcu R5 */
/* MCU MCAN Inst 0 */
configStatus = App_mcanRegisterInterrupt(APP_MCU_MCAN_0_INT0, &App_mcanIntr0ISR);
configStatus += App_mcanRegisterInterrupt(APP_MCU_MCAN_0_INT1, &App_mcanIntr1ISR);
configStatus += App_mcanRegisterInterrupt(APP_MCU_MCAN_0_TS_INT, &App_mcanTSIntrISR);
/* MCU MCAN Inst 1 */
configStatus += App_mcanRegisterInterrupt(APP_MCU_MCAN_1_INT0, &App_mcanIntr0ISR);
configStatus += App_mcanRegisterInterrupt(APP_MCU_MCAN_1_INT1, &App_mcanIntr1ISR);
configStatus += App_mcanRegisterInterrupt(APP_MCU_MCAN_1_TS_INT, &App_mcanTSIntrISR);

#if defined (SOC_J721E) || defined (SOC_J7200)
/* Main MCAN Inst 2 */
/* Src offset 0 - mcanss_ext_ts_rollover_lvl_int,
Src offset 1 - mcanss_mcan_lvl_int Line 0,
Src offset 2 - mcanss_mcan_lvl_int Line 1 */

/* Needs Interrupt router configuration for getting interrupts to Mcu R5. */
configStatus += App_mcanCfgIrqRouterMain2Mcu(TISCI_DEV_MCAN2, 1U, APP_MAIN_MCAN_2_INT0);
configStatus += App_mcanRegisterInterrupt (APP_MAIN_MCAN_2_INT0, &App_mcanIntr0ISR);
configStatus += App_mcanCfgIrqRouterMain2Mcu(TISCI_DEV_MCAN2, 2U, APP_MAIN_MCAN_2_INT1);
configStatus += App_mcanRegisterInterrupt (APP_MAIN_MCAN_2_INT1, &App_mcanIntr1ISR);
configStatus += App_mcanCfgIrqRouterMain2Mcu(TISCI_DEV_MCAN2, 0U, APP_MAIN_MCAN_2_TS_INT);
configStatus += App_mcanRegisterInterrupt (APP_MAIN_MCAN_2_TS_INT, &App_mcanTSIntrISR);
#endif

#else
/* Running Code from Main R5 */
#if defined (SOC_J721E) || defined (SOC_J7200)
App_ConsolePrintf("check non BUILD_MCU2_1 App_mcanRegisterIsr()");
/* Main MCAN Inst 0 */
configStatus = App_mcanRegisterInterrupt(APP_MAIN_MCAN_0_INT0, &App_mcanIntr0ISR);
configStatus += App_mcanRegisterInterrupt(APP_MAIN_MCAN_0_INT1, &App_mcanIntr1ISR);
configStatus += App_mcanRegisterInterrupt(APP_MAIN_MCAN_0_TS_INT, &App_mcanTSIntrISR);
/* Main MCAN Inst 2 */
configStatus = App_mcanRegisterInterrupt(APP_MAIN_MCAN_2_INT0, &App_mcanIntr0ISR);
configStatus += App_mcanRegisterInterrupt(APP_MAIN_MCAN_2_INT1, &App_mcanIntr1ISR);
configStatus += App_mcanRegisterInterrupt(APP_MAIN_MCAN_2_TS_INT, &App_mcanTSIntrISR);
/* Main MCAN Inst 4 */
configStatus = App_mcanRegisterInterrupt(APP_MAIN_MCAN_4_INT0, &App_mcanIntr0ISR);
configStatus += App_mcanRegisterInterrupt(APP_MAIN_MCAN_4_INT1, &App_mcanIntr1ISR);
configStatus += App_mcanRegisterInterrupt(APP_MAIN_MCAN_4_TS_INT, &App_mcanTSIntrISR);
/* Main MCAN Inst 5 */
configStatus = App_mcanRegisterInterrupt(APP_MAIN_MCAN_5_INT0, &App_mcanIntr0ISR);
configStatus += App_mcanRegisterInterrupt(APP_MAIN_MCAN_5_INT1, &App_mcanIntr1ISR);
configStatus += App_mcanRegisterInterrupt(APP_MAIN_MCAN_5_TS_INT, &App_mcanTSIntrISR);
/* Main MCAN Inst 6 */
configStatus = App_mcanRegisterInterrupt(APP_MAIN_MCAN_6_INT0, &App_mcanIntr0ISR);
configStatus += App_mcanRegisterInterrupt(APP_MAIN_MCAN_6_INT1, &App_mcanIntr1ISR);
configStatus += App_mcanRegisterInterrupt(APP_MAIN_MCAN_6_TS_INT, &App_mcanTSIntrISR);
/* Main MCAN Inst 7 */
configStatus = App_mcanRegisterInterrupt(APP_MAIN_MCAN_7_INT0, &App_mcanIntr0ISR);
configStatus += App_mcanRegisterInterrupt(APP_MAIN_MCAN_7_INT1, &App_mcanIntr1ISR);
configStatus += App_mcanRegisterInterrupt(APP_MAIN_MCAN_7_TS_INT, &App_mcanTSIntrISR);
/* Main MCAN Inst 9 */
configStatus = App_mcanRegisterInterrupt(APP_MAIN_MCAN_9_INT0, &App_mcanIntr0ISR);
configStatus += App_mcanRegisterInterrupt(APP_MAIN_MCAN_9_INT1, &App_mcanIntr1ISR);
configStatus += App_mcanRegisterInterrupt(APP_MAIN_MCAN_9_TS_INT, &App_mcanTSIntrISR);
/* Main MCAN Inst 11 */
configStatus = App_mcanRegisterInterrupt(APP_MAIN_MCAN_11_INT0, &App_mcanIntr0ISR);
configStatus += App_mcanRegisterInterrupt(APP_MAIN_MCAN_11_INT1, &App_mcanIntr1ISR);
configStatus += App_mcanRegisterInterrupt(APP_MAIN_MCAN_11_TS_INT, &App_mcanTSIntrISR);
#endif
#endif
if(STW_SOK != configStatus)
{
App_ConsolePrintf("CrossBar/Interrupt Configuration failed.\n");
}
else
{
App_ConsolePrintf("CrossBar/Interrupt Configuration done.\n");
}

return configStatus;
}

static int32_t App_mcanConfig(bool enableInternalLpbk)
{
uint32_t fdoe;
int32_t configStatus = CSL_PASS;
MCAN_RevisionId revId;
MCAN_InitParams initParams;
MCAN_ConfigParams configParams;
MCAN_MsgRAMConfigParams msgRAMConfigParams;
MCAN_StdMsgIDFilterElement stdFiltelem;
MCAN_BitTimingParams bitTimes;

/* Initialize MCAN Init params */
initParams.fdMode = 0x1U;
initParams.brsEnable = 0x1U;
initParams.txpEnable = 0x0U;
initParams.efbi = 0x0U;
initParams.pxhddisable = 0x0U;
initParams.darEnable = 0x1U;
initParams.wkupReqEnable = 0x1U;
initParams.autoWkupEnable = 0x1U;
initParams.emulationEnable = 0x1U;
initParams.emulationFAck = 0x0U;
initParams.clkStopFAck = 0x0U;
initParams.wdcPreload = 0xFFU;
initParams.tdcEnable = 0x1U;
initParams.tdcConfig.tdcf = 0xAU;
initParams.tdcConfig.tdco = 0x6U;
/* Initialize MCAN Config params */
configParams.monEnable = 0x0U;
configParams.asmEnable = 0x0U;
configParams.tsPrescalar = 0xFU;
configParams.tsSelect = 0x0U;
configParams.timeoutSelect = MCAN_TIMEOUT_SELECT_CONT;
configParams.timeoutPreload = 0xFFFFU;
configParams.timeoutCntEnable = 0x0U;
configParams.filterConfig.rrfs = 0x1U;
configParams.filterConfig.rrfe = 0x1U;
configParams.filterConfig.anfe = 0x1U;
configParams.filterConfig.anfs = 0x1U;
/* Initialize Message RAM Sections Configuration Parameters */
msgRAMConfigParams.flssa = APP_MCAN_STD_ID_FILT_START_ADDR;
msgRAMConfigParams.lss = APP_MCAN_STD_ID_FILTER_NUM;
msgRAMConfigParams.flesa = APP_MCAN_EXT_ID_FILT_START_ADDR;
msgRAMConfigParams.lse = APP_MCAN_EXT_ID_FILTER_NUM;
msgRAMConfigParams.txStartAddr = APP_MCAN_TX_BUFF_START_ADDR;
msgRAMConfigParams.txBufNum = APP_MCAN_TX_BUFF_SIZE;
msgRAMConfigParams.txFIFOSize = 0U;
msgRAMConfigParams.txBufMode = 0U;
msgRAMConfigParams.txBufElemSize = MCAN_ELEM_SIZE_64BYTES;
msgRAMConfigParams.txEventFIFOStartAddr = APP_MCAN_TX_EVENT_START_ADDR;
msgRAMConfigParams.txEventFIFOSize = APP_MCAN_TX_BUFF_SIZE;
msgRAMConfigParams.txEventFIFOWaterMark = 3U;
msgRAMConfigParams.rxFIFO0startAddr = APP_MCAN_FIFO_0_START_ADDR;
msgRAMConfigParams.rxFIFO0size = APP_MCAN_FIFO_0_NUM;
msgRAMConfigParams.rxFIFO0waterMark = 3U;
msgRAMConfigParams.rxFIFO0OpMode = 0U;
msgRAMConfigParams.rxFIFO1startAddr = APP_MCAN_FIFO_1_START_ADDR;
msgRAMConfigParams.rxFIFO1size = APP_MCAN_FIFO_1_NUM;
msgRAMConfigParams.rxFIFO1waterMark = 3U;
msgRAMConfigParams.rxFIFO1OpMode = 0U;
msgRAMConfigParams.rxBufStartAddr = APP_MCAN_RX_BUFF_START_ADDR;
msgRAMConfigParams.rxBufElemSize = MCAN_ELEM_SIZE_64BYTES;
msgRAMConfigParams.rxFIFO0ElemSize = MCAN_ELEM_SIZE_64BYTES;
msgRAMConfigParams.rxFIFO1ElemSize = MCAN_ELEM_SIZE_64BYTES;
/* Initialize Tx Buffer Config params */
//stdFiltelem.sfid2 = 0x0U;
stdFiltelem.sfid2 = 0x7FFU;

//stdFiltelem.sfid1 = 0x4U;
stdFiltelem.sfid1 = 0x0U;

stdFiltelem.sfec = 0x7U;
stdFiltelem.sft = 0x0U;
/* Initialize bit timings
* Configuring 1Mbps and 5Mbps as nominal and data bit-rate respectively */
bitTimes.nomRatePrescalar = 0x7U;
bitTimes.nomTimeSeg1 = 0x5U;
bitTimes.nomTimeSeg2 = 0x2U;
bitTimes.nomSynchJumpWidth = 0x0U;
bitTimes.dataRatePrescalar = 0x1U;
bitTimes.dataTimeSeg1 = 0x3U;
bitTimes.dataTimeSeg2 = 0x2U;
bitTimes.dataSynchJumpWidth = 0x0U;

/* Get MCANSS Revision ID */
MCAN_getRevisionId(gMcanModAddr, &revId);
App_ConsolePrintf("gMcanModAddr:0x%x\n", gMcanModAddr);
App_ConsolePrintf("MCANSS Revision ID:\n");
App_ConsolePrintf("scheme:0x%x\n", revId.scheme);
App_ConsolePrintf("Business Unit:0x%x\n", revId.bu);
App_ConsolePrintf("Module ID:0x%x\n", revId.modId);
App_ConsolePrintf("RTL Revision:0x%x\n", revId.rtlRev);
App_ConsolePrintf("Major Revision:0x%x\n", revId.major);
App_ConsolePrintf("Custom Revision:0x%x\n", revId.custom);
App_ConsolePrintf("Minor Revision:0x%x\n", revId.minor);
/* Enable Auto wakeup */
fdoe = MCAN_isFDOpEnable(gMcanModAddr);
if ((uint32_t)TRUE == fdoe)
{
App_ConsolePrintf("CAN-FD operation is enabled through E-Fuse.\n");
}
else
{
App_ConsolePrintf("CAN-FD operation is disabled through E-Fuse.\n");
}
/* wait for memory initialization to happen */
while (FALSE == MCAN_isMemInitDone(gMcanModAddr))
{}
/* Get endianess value */
App_ConsolePrintf("Endianess Value: 0x%x\n",
MCAN_getEndianVal(gMcanModAddr));
/* Put MCAN in SW initialization mode */
MCAN_setOpMode(gMcanModAddr, MCAN_OPERATION_MODE_SW_INIT);
while (MCAN_OPERATION_MODE_SW_INIT != MCAN_getOpMode(gMcanModAddr))
{}
/* Initialize MCAN module */
MCAN_init(gMcanModAddr, &initParams);
/* Configure MCAN module */
MCAN_config(gMcanModAddr, &configParams);
/* Configure Bit timings */
MCAN_setBitTime(gMcanModAddr, &bitTimes);
/* Set Extended ID Mask */
MCAN_setExtIDAndMask(gMcanModAddr, APP_MCAN_EXT_ID_AND_MASK);
/* Configure Message RAM Sections */
MCAN_msgRAMConfig(gMcanModAddr, &msgRAMConfigParams);
/* Configure Standard ID filter element */
MCAN_addStdMsgIDFilter(gMcanModAddr, 0U, &stdFiltelem);

if (TRUE == enableInternalLpbk)
{
MCAN_lpbkModeEnable (gMcanModAddr, MCAN_LPBK_MODE_INTERNAL, TRUE);
}

/* Take MCAN out of the SW initialization mode */
MCAN_setOpMode(gMcanModAddr, MCAN_OPERATION_MODE_NORMAL);

while (MCAN_OPERATION_MODE_NORMAL != MCAN_getOpMode(gMcanModAddr))
{}
return configStatus;
}

static void App_mcanIntr0ISR(uintptr_t arg)
{
uint32_t intrStatus;

intrStatus = MCAN_getIntrStatus(gMcanModAddr);
MCAN_clearIntrStatus(gMcanModAddr, intrStatus);
if (MCAN_INTR_SRC_TRANS_COMPLETE ==
(intrStatus & MCAN_INTR_SRC_TRANS_COMPLETE))
{
gMcanIsrIntr0Flag = 0U;
}

if (MCAN_INTR_SRC_DEDICATED_RX_BUFF_MSG ==
(intrStatus & MCAN_INTR_SRC_DEDICATED_RX_BUFF_MSG))
{
gMcanIsrIntr1Flag = 0U;
}

}

static void App_mcanIntr1ISR(uintptr_t arg)
{
uint32_t intrStatus;

intrStatus = MCAN_getIntrStatus(gMcanModAddr);
MCAN_clearIntrStatus(gMcanModAddr, intrStatus);
if (MCAN_INTR_SRC_DEDICATED_RX_BUFF_MSG ==
(intrStatus & MCAN_INTR_SRC_DEDICATED_RX_BUFF_MSG))
{
gMcanIsrIntr1Flag = 0U;
}

}

static void App_mcanTSIntrISR(uintptr_t arg)
{
App_ConsolePrintf("Time Stamp overflow happened.\n");
}

static void App_mcanPrintTxMsg(const MCAN_TxBufElement *txMsg)
{
uint32_t loopCnt;

App_ConsolePrintf("\nMessage ID: 0x%x", txMsg->id);

App_ConsolePrintf("\nMessage Remote Transmission Request: 0x%x",
txMsg->rtr);

App_ConsolePrintf(
"\nMessage Extended Frame ID(0:11Bit ID/1:29bit ID): 0x%x",
txMsg->xtd);

App_ConsolePrintf(
"\nMessage Error State Indicator(0:Error Active/1:Error Passive): 0x%x",
txMsg->esi);

App_ConsolePrintf("\nMessage Data Length Code: 0x%x", txMsg->dlc);

App_ConsolePrintf("\nMessage BRS: 0x%x", txMsg->brs);

App_ConsolePrintf("\nMessage CAN FD format: 0x%x", txMsg->fdf);

App_ConsolePrintf("\nMessage Store Tx Events: 0x%x", txMsg->efc);

App_ConsolePrintf("\nMessage Marker: 0x%x", txMsg->mm);

for (loopCnt = 0U; loopCnt < gMcanAppdataSize[txMsg->dlc]; loopCnt++)
{
App_ConsolePrintf("\nMessage DataByte%d", loopCnt);
App_ConsolePrintf(": 0x%x", txMsg->data[loopCnt]);
}
}

static void App_mcanPrintRxMsg(const MCAN_RxBufElement *rxMsg)
{
uint32_t loopCnt;

App_ConsolePrintf("\nMessage ID: 0x%x", rxMsg->id);
App_ConsolePrintf("\nMessage Remote Transmission Request: 0x%x", rxMsg->rtr);
App_ConsolePrintf(
"\nMessage Extended Frame ID(0:11Bit ID/1:29bit ID): 0x%x",
rxMsg->xtd);
App_ConsolePrintf(
"\nMessage Error State Indicator(0:Error Active/1:Error Passive): 0x%x",
rxMsg->esi);
App_ConsolePrintf("\nMessage TimeStamp: 0x%x", rxMsg->rxts);
App_ConsolePrintf("\nMessage Data Length Code: 0x%x", rxMsg->dlc);
App_ConsolePrintf("\nMessage BRS: 0x%x", rxMsg->brs);
App_ConsolePrintf("\nMessage CAN FD format: 0x%x", rxMsg->fdf);
App_ConsolePrintf("\nMessage Filter Index: 0x%x", rxMsg->fidx);
App_ConsolePrintf("\nMessage Accept Non-matching Frame: 0x%x", rxMsg->anmf);
for (loopCnt = 0U; loopCnt < gMcanAppdataSize[rxMsg->dlc]; loopCnt++)
{
App_ConsolePrintf("\nMessage DataByte%d", loopCnt);
App_ConsolePrintf(": 0x%x", rxMsg->data[loopCnt]);
}
}

static void APP_mcanTxTest(MCAN_TxBufElement *txMsg)
{
int32_t testStatus = CSL_PASS;
uint32_t loopCnt = 1U;
MCAN_ProtocolStatus protStatus;

/* Enable Interrupts */
MCAN_enableIntr(gMcanModAddr, MCAN_INTR_MASK_ALL, (uint32_t)TRUE);
App_ConsolePrintf("\nTest1..\n");

MCAN_enableIntr(gMcanModAddr,
MCAN_INTR_SRC_RES_ADDR_ACCESS, (uint32_t)FALSE);
App_ConsolePrintf("\nTest2..\n");

/* Select Interrupt Line */
MCAN_selectIntrLine(gMcanModAddr,
MCAN_INTR_MASK_ALL,
MCAN_INTR_LINE_NUM_0);
App_ConsolePrintf("\nTest3..\n");

/* Enable Interrupt Line */
MCAN_enableIntrLine(gMcanModAddr,
MCAN_INTR_LINE_NUM_0,
1U);
App_ConsolePrintf("\nTest4..\n");

/* Enable Transmission interrupt */
testStatus = MCAN_txBufTransIntrEnable(gMcanModAddr,
1U,
(uint32_t)TRUE);
App_ConsolePrintf("\nTest5..\n");

if (CSL_PASS != testStatus)
{
App_ConsolePrintf("\nError in enabling buffer Transmit interrupt...\n");
}
else
{
for (loopCnt = 1U; loopCnt < 16U; loopCnt++)
{
txMsg->dlc = loopCnt;
/* Write message to Msg RAM */
MCAN_writeMsgRam(gMcanModAddr,
MCAN_MEM_TYPE_BUF,
1U,
txMsg);
App_ConsolePrintf("\nTest6..\n");

/* Add request for transmission */
testStatus = MCAN_txBufAddReq(gMcanModAddr, 1U);
if (CSL_PASS != testStatus)
{
App_ConsolePrintf("\nError in Adding Transmission Request...\n");
break;
}
App_ConsolePrintf("\nTest7..\n");

while (gMcanIsrIntr0Flag)
{}
App_ConsolePrintf("\nTest8..\n");

gMcanIsrIntr0Flag = 1U;
MCAN_getProtocolStatus(gMcanModAddr, &protStatus);
/* Checking for Errors */
if (((MCAN_ERR_CODE_NO_ERROR == protStatus.lastErrCode) ||
(MCAN_ERR_CODE_NO_CHANGE == protStatus.lastErrCode)) &&
((MCAN_ERR_CODE_NO_ERROR == protStatus.dlec) ||
(MCAN_ERR_CODE_NO_CHANGE == protStatus.dlec)) &&
(0U == protStatus.pxe))
{
App_ConsolePrintf(
"\nMessage successfully transferred with payload Bytes:%d",
gMcanAppdataSize[txMsg->dlc]);
}
else
{
App_ConsolePrintf(
"\nError in transmission with payload Bytes:%d",
gMcanAppdataSize[txMsg->dlc]);
testStatus = CSL_EFAIL;
break;
}
}
}
if (CSL_EFAIL == testStatus)
{
App_ConsolePrintf("\nTx Test FAILED...\n");
}
else
{
App_ConsolePrintf("\nTx Test PASSED...\n");
}
}

static void APP_mcanRxTest(const MCAN_TxBufElement *txMsg)
{
uint32_t loopCnt = 1U, chkCnt = 0U, errFlag = 0U;
int32_t testStatus = CSL_PASS;
MCAN_RxBufElement rxMsg;
MCAN_RxNewDataStatus newDataStatus;
MCAN_ErrCntStatus errCounter;

/* Enable Interrupts */
MCAN_enableIntr(gMcanModAddr, MCAN_INTR_MASK_ALL, (uint32_t)TRUE);
MCAN_enableIntr(gMcanModAddr,
MCAN_INTR_SRC_RES_ADDR_ACCESS, (uint32_t)FALSE);
/* Select Interrupt Line */
MCAN_selectIntrLine(gMcanModAddr,
MCAN_INTR_MASK_ALL,
MCAN_INTR_LINE_NUM_1);
/* Enable Interrupt Line */
MCAN_enableIntrLine(gMcanModAddr,
MCAN_INTR_LINE_NUM_1,
1U);
for (loopCnt = 1U; loopCnt < 16U; loopCnt++)
{
App_ConsolePrintf("\nTestRx1..\n");
while (gMcanIsrIntr1Flag)
{}
App_ConsolePrintf("\nTestRx2..\n");
gMcanIsrIntr1Flag = 1U;
/* Checking for Errors */
MCAN_getErrCounters(gMcanModAddr, &errCounter);
if ((0U == errCounter.recErrCnt) &&
(0U == errCounter.canErrLogCnt))
{
MCAN_getNewDataStatus(gMcanModAddr, &newDataStatus);
MCAN_clearNewDataStatus(gMcanModAddr, &newDataStatus);
MCAN_readMsgRam(gMcanModAddr,
MCAN_MEM_TYPE_BUF,
0U,
0U,
&rxMsg);
errFlag = 0U;
for (chkCnt = 0U; chkCnt < gMcanAppdataSize[rxMsg.dlc]; chkCnt++)
{
if (txMsg->data[chkCnt] != rxMsg.data[chkCnt])
{
errFlag = 1U;
break;
}
}
if (0U == errFlag)
{
App_ConsolePrintf(
"\nMessage successfully received with payload Bytes: %d",
gMcanAppdataSize[rxMsg.dlc]);
}
else
{
App_ConsolePrintf(
"\nWrong data received in message with payload Bytes: ",
gMcanAppdataSize[rxMsg.dlc]);
testStatus = CSL_EFAIL;
}
}
else
{
App_ConsolePrintf(
"\nError in reception with payload Bytes:%d",
gMcanAppdataSize[txMsg->dlc]);
testStatus = CSL_EFAIL;
}
}
App_ConsolePrintf("\nReceived last message with following details:");
App_mcanPrintRxMsg(&rxMsg);
if (CSL_EFAIL == testStatus)
{
App_ConsolePrintf("\nRx Test FAILED...\n");
}
else
{
App_ConsolePrintf("\nRx Test PASSED...\n");
}
}

static void APP_mcanLpbkTest(MCAN_TxBufElement *txMsg)
{
int32_t testStatus = CSL_PASS;
MCAN_ProtocolStatus protStatus;
MCAN_RxBufElement rxMsg;
MCAN_RxNewDataStatus newDataStatus;
MCAN_ErrCntStatus errCounter;
uint32_t loopCnt, chkCnt, errFlag;

/* Enable Transmission Interrupts */
MCAN_enableIntr(gMcanModAddr, MCAN_INTR_MASK_ALL, (uint32_t)TRUE);
MCAN_enableIntr(gMcanModAddr,
MCAN_INTR_SRC_RES_ADDR_ACCESS, (uint32_t)FALSE);
/* Select Interrupt Line */
MCAN_selectIntrLine(gMcanModAddr,
MCAN_INTR_MASK_ALL,
MCAN_INTR_LINE_NUM_0);
/* Enable Interrupt Line */
MCAN_enableIntrLine(gMcanModAddr,
MCAN_INTR_LINE_NUM_0,
1U);

/* Enable Transmission interrupt */
testStatus = MCAN_txBufTransIntrEnable(gMcanModAddr,
1U,
(uint32_t)TRUE);
#if defined(UNITY_INCLUDE_CONFIG_H)
TEST_ASSERT_EQUAL_INT32(CSL_PASS, testStatus);
#endif

if (CSL_PASS != testStatus)
{
App_ConsolePrintf("\nError in enabling buffer Transmit interrupt...\n");
}
else
{
for (loopCnt = 1U; loopCnt < 16U; loopCnt++)
{
txMsg->dlc = loopCnt;
/* Write message to Msg RAM */
MCAN_writeMsgRam(gMcanModAddr,
MCAN_MEM_TYPE_BUF,
1U,
txMsg);
/* Add request for transmission */
testStatus = MCAN_txBufAddReq(gMcanModAddr, 1U);
#if defined(UNITY_INCLUDE_CONFIG_H)
TEST_ASSERT_EQUAL_INT32(CSL_PASS, testStatus);
#endif
if (CSL_PASS != testStatus)
{
App_ConsolePrintf("\nError in Adding Transmission Request...\n");
break;
}
while (gMcanIsrIntr0Flag)
{}
gMcanIsrIntr0Flag = 1U;
MCAN_getProtocolStatus(gMcanModAddr, &protStatus);
/* Checking for Errors */
if (((MCAN_ERR_CODE_NO_ERROR == protStatus.lastErrCode) ||
(MCAN_ERR_CODE_NO_CHANGE == protStatus.lastErrCode)) &&
((MCAN_ERR_CODE_NO_ERROR == protStatus.dlec) ||
(MCAN_ERR_CODE_NO_CHANGE == protStatus.dlec)) &&
(0U == protStatus.pxe))
{
App_ConsolePrintf(
"\nMessage successfully transferred with payload Bytes:%d",
gMcanAppdataSize[txMsg->dlc]);
}
else
{
App_ConsolePrintf(
"\nError in transmission with payload Bytes:%d",
gMcanAppdataSize[txMsg->dlc]);
testStatus = CSL_EFAIL;
break;
}

while (gMcanIsrIntr1Flag)
{}
gMcanIsrIntr1Flag = 1U;
/* Checking for Errors */
MCAN_getErrCounters(gMcanModAddr, &errCounter);

#if defined(UNITY_INCLUDE_CONFIG_H)
TEST_ASSERT_EQUAL_UINT32(0U, errCounter.recErrCnt);
TEST_ASSERT_EQUAL_UINT32(0U, errCounter.canErrLogCnt);
#endif
if ((0U == errCounter.recErrCnt) &&
(0U == errCounter.canErrLogCnt))
{
MCAN_getNewDataStatus(gMcanModAddr, &newDataStatus);
MCAN_clearNewDataStatus(gMcanModAddr, &newDataStatus);
MCAN_readMsgRam(gMcanModAddr,
MCAN_MEM_TYPE_BUF,
0U,
0U,
&rxMsg);
errFlag = 0U;
for (chkCnt = 0U; chkCnt < gMcanAppdataSize[rxMsg.dlc]; chkCnt++)
{
if (txMsg->data[chkCnt] != rxMsg.data[chkCnt])
{
errFlag = 1U;
break;
}
}
#if defined(UNITY_INCLUDE_CONFIG_H)
TEST_ASSERT_EQUAL_UINT32(0U, errFlag);
#endif
if (0U == errFlag)
{
App_ConsolePrintf(
"\nMessage successfully received with payload Bytes: %d",
gMcanAppdataSize[rxMsg.dlc]);
}
else
{
App_ConsolePrintf(
"\nWrong data received in message with payload Bytes: ",
gMcanAppdataSize[rxMsg.dlc]);
testStatus = CSL_EFAIL;
}
}
else
{
App_ConsolePrintf(
"\nError in reception with payload Bytes:%d",
gMcanAppdataSize[txMsg->dlc]);
testStatus = CSL_EFAIL;
}
}
}

#if defined(UNITY_INCLUDE_CONFIG_H)
TEST_ASSERT_EQUAL_INT32(CSL_PASS, testStatus);
#endif

if (CSL_EFAIL == testStatus)
{
App_ConsolePrintf("\nLoopback Test FAILED...\n");
}
else
{
App_ConsolePrintf("\nLoopback Test PASSED...\n");
}
}


void App_ConsolePrintf(const char *pcString, ...)
{
static char printBuffer[APP_PRINT_BUFFER_SIZE];
va_list arguments;

/* Start the varargs processing. */
va_start(arguments, pcString);
vsnprintf (printBuffer, sizeof(printBuffer), pcString, arguments);
#if (APP_ENABLE_UART_PRINT == 1)
UART_printf(printBuffer);
#else
printf(printBuffer);
#endif

/* End the varargs processing. */
va_end(arguments);
}

static void App_ConsoleGetNum(uint32_t *num)
{
#if (APP_ENABLE_UART_PRINT == 1)
uint32_t status;
status = UART_scanFmt("%d", num);
if (status != S_PASS)
{
App_ConsolePrintf("UART Scan failed \n");
}
#else
scanf("%d", (int32_t *)num);
#endif
}

#ifdef UNITY_INCLUDE_CONFIG_H
/*
* ======== Unity set up and tear down ========
*/
void setUp(void)
{
/* Do nothing */
}

void tearDown(void)
{
/* Do nothing */
}
#endif

void test_csl_mcan_evm_loopback_app_runner(void)
{
/* @description:Test runner for mcan tests

@requirements: PDK-1694

@cores: MCU2_1 mcu2_1 */
#if defined(UNITY_INCLUDE_CONFIG_H)
UNITY_BEGIN();
RUN_TEST (test_csl_mcan_evm_loopback_app);
UNITY_END();
/* Function to print results defined in our unity_config.h file */
print_unityOutputBuffer_usingUARTstdio();
#else
test_csl_mcan_evm_loopback_app();
#endif
return;
}

int mcan_test_evm(void)
{
// wait for 5sec
// appLogWaitMsecs(5000);

(void) test_csl_mcan_evm_loopback_app_runner();

appLogPrintf("mcan_test_evm() completed..");

return TRUE;
}