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.

AM62A7: AM62A7: AM62A7-Q1: mcu i2c slave test

Part Number: AM62A7
Other Parts Discussed in Thread: SYSCONFIG

hi teams:

we need to evaluate the i2c1 slave on MCU r5f on our end,

i2c 1 slave (mcu r5f side),i2c 2 master(a72 linux side)

We have reviewed the link and can implement i2c slave in MCU R5f

AM62A7: AM62A7 Main Domain I2C controller support slave mode? - Processors forum - Processors - TI E2E support forums

void i2c_slave_test() {
	I2C_Params      params;

	I2C_Params_init(&params);
	params.transferMode  = I2C_MODE_BLOCKING;
	I2C_init();
	ggI2cHandle = I2C_open(CONFIG_I2C1, &params);
	if (!ggI2cHandle) {
	DebugP_assert(FALSE);
	}
	int32_t status;
 
    I2C_Transaction i2cTransaction;
    I2C_Transaction_init(&i2cTransaction);
  
    i2cTransaction.writeBuf = NULL;
    i2cTransaction.writeCount = 1U;
  
    i2cTransaction.readBuf = NULL;
    i2cTransaction.readCount = 2U;
	i2cTransaction.slaveAddress = 0x49U;

	i2cTransaction.masterMode = false;
    status = I2C_transfer(ggI2cHandle, &i2cTransaction);
    if (SystemP_SUCCESS != status) {
        DebugP_assert(FALSE);
    }
}	

--- a/mcu_plus_sdk_am62ax_08_06_00_18/examples/drivers/ipc/ipc_rpmsg_echo_linux/am62ax-sk/mcu-r5fss0-0_freertos/example.syscfg
+++ b/mcu_plus_sdk_am62ax_08_06_00_18/examples/drivers/ipc/ipc_rpmsg_echo_linux/am62ax-sk/mcu-r5fss0-0_freertos/example.syscfg
@@ -8,6 +8,9 @@
 /**
  * Import the modules used in this configuration.
  */
+const i2c        = scripting.addModule("/drivers/i2c/i2c", {}, false);
+const i2c0       = i2c.addInstance();
+const i2c1       = i2c.addInstance();
 const ipc             = scripting.addModule("/drivers/ipc/ipc");
 const addr_translate  = scripting.addModule("/kernel/dpl/addr_translate", {}, false);
 const addr_translate1 = addr_translate.addInstance();
@@ -108,3 +111,10 @@ mcan2.MCU_MCAN.TX.$suggestSolution              = "ball.D7";     /* hxh add*/
 debug_log.uartLog.MCU_UART.$suggestSolution     = "MCU_USART0";
 debug_log.uartLog.MCU_UART.RXD.$suggestSolution = "ball.D8";
 debug_log.uartLog.MCU_UART.TXD.$suggestSolution = "ball.F8";
+i2c0.$name                   = "CONFIG_I2C0";
+
+i2c1.$name                   = "CONFIG_I2C1";
+i2c1.useMcuDomainPeripherals = false;
+i2c1.I2C.$assign             = "I2C1";
+i2c1.I2C.SCL.$suggestSolution                   = "ball.C17";
+i2c1.I2C.SDA.$suggestSolution                   = "ball.E17";

Slave has been identified on A72, there are a few issues,a new address was found in A72 i2c2, but when attempting to read or write, a timeout class printing occurred

pinmux is right

root@am62axx-evm:~# devmem2  0x000F41E8
/dev/mem opened.
Memory mapped at address 0xffff82713000.
Read at address  0x000F41E8 (0xffff827131e8): 0x00060000
root@am62axx-evm:~# devmem2  0x000F41EC
/dev/mem opened.
Memory mapped at address 0xffffa236a000.
Read at address  0x000F41EC (0xffffa236a1ec): 0x00060000
root@am62axx-evm:~# 

How to implement interrupt mode slave and master reads and writes to the slave

Can you help me check if there are any issues with my code

or

Can you provide a demo program for implementing the slave mode

 

  • Hello,

    Thanks for reaching out to Texas Instruments E2E support forum.

    I have taken your inputs and working on it. Please allow some time to revert back.

    Regards,

    Tushar

  • thanks 

    It seems that the address was detected for the first time, but later it showed timeout. After measuring the waveform, there was a persistent low phenomenon, probably due to being pulled by slave i2c1

  • Excuse me, have you received a reply

  • Hello,

    Thanks for your patience.

    The code seems okay on MCU R5F core to configure I2C as slave.

    I am routing your query to one of our team member who is more familiar with Linux development.

    Regards,

    Tushar

  • Hello Wu,

    1) Please help me understand what your usecase is. I assume you are not going to have the A53 core and the MCU R5F core connected over I2C on the same processor.

    2) What Linux driver are you using in the Linux devicetree file for the R5F core acting as an I2C slave device?

    Regards,

    Nick

  • Hello Nick:

    1) Please help me understand what your usecase is. I assume you are not going to have the A53 core and the MCU R5F core connected over I2C on the same processor.

    We hope that am62ax Linux A53 supports one of the i2c functions as a slave, but your feedback is that i2c slave is not supported in Linux and can only be supported in r5f MCU. Therefore, we will use the main i2c2 as the i2c master and the main i2c1 as the i2c slave function in debugging the r5f MCU. The main i2c2 will act as the host in a53 Linux

    2) What Linux driver are you using in the Linux devicetree file for the R5F core acting as an I2C slave device?

    I am currently using the i2c tools to communicate with the rf5 MCU acting as the i2c slave, such as i2cdetect, i2cset, and i2cget

    thx

  • Hello Wu,

    Hmm, ok. I am going to pass your thread back over to the MCU+ people. I think what we really need here is a "known good" starting point: MCU+ SDK code that TI has used to test the I2C slave functionality, and exact steps for how to interact with that code to verify that it is working. Then you could take that code, verify that it works, and start making modifications to write your own code.

    I do not actually see any I2C slave examples, either in the MCU+ SDK under examples/drivers/i2c, or in the bitbucket repo under test/drivers/i2c (where the bitbucket repo is here: https://github.com/TexasInstruments/mcupsdk-core-k3 ). I am going to ask the MCU+ guys to provide you that example code.

    Regards,

    Nick

  • Hello:

    1:

    There is currently no sample demo for this link regarding slave. When can it be uploaded

    github.com/.../mcupsdk-core-k3

    2:

    The following code

    Is it necessary to be in a loop at the call of I2C_transfer if continuous communication is required

    void i2c_slave_test() {
    	I2C_Params      params;
    
    	I2C_Params_init(&params);
    	
    	uint8_t         txBuffer[I2C_WRITE_LEN];
    	uint8_t         rxBuffer[2];
    	params.transferMode  = I2C_MODE_BLOCKING;
    	params.transferCallbackFxn = ptransferCallbackFxn;
    	I2C_init();
    	DebugP_log("\r\n -CONFIG_I2C1:%d\n",CONFIG_I2C1);
    	ggI2cHandle = I2C_open(CONFIG_I2C1, &params);
    //	ggI2cHandle = gI2cHandle[CONFIG_I2C1];
    	if (!ggI2cHandle) {
    	DebugP_assert(FALSE);
    	}
    	int32_t status;
     
        I2C_Transaction i2cTransaction;
        I2C_Transaction_init(&i2cTransaction);
      
        i2cTransaction.writeBuf = txBuffer;
        i2cTransaction.writeCount = I2C_WRITE_LEN;
    	txBuffer[0] = 0x15;
    	// txBuffer[1] = 0x12;
      
        i2cTransaction.readBuf = rxBuffer;
        i2cTransaction.readCount = 2U;
    	i2cTransaction.slaveAddress = I2C_SLAVE_ADDR;
    
    	i2cTransaction.masterMode = false;
    //	i2cTransaction.timeout = 10;
    //	status = I2C_transfer(ggI2cHandle, &i2cTransaction);
    
    	for (;;) {
    		
    		txBuffer[0]+=1;
    		if (txBuffer[0] > 28)txBuffer[0] = 0;
    		status = I2C_transfer(ggI2cHandle, &i2cTransaction);
    		
    		DebugP_log("\r\n status %d--------------------------------rxbuf-------------->0x%x-0x%x\n",status,rxBuffer[0],rxBuffer[1]);	
    		if (SystemP_SUCCESS != status) {
    		DebugP_assert(FALSE);
    		}
    
    	}
    //	while (1) {
    //
    //	}
    }

    the following log shows that there seems to be a problem with my code writing. I can keep reading (A53 Linux), but when I suddenly write it, I report an error

  • The above code, if the A53 Linux keeps reading, can read data, but as long as it is written once, the bus is pulled down, and I cannot find the reason

    Later, a count was added to the interrupt ISR function, but the interrupt could not be triggered after a replication issue occurred

    I2C_transfer

    +static uint32_t gcount = 0;
    
     int32_t I2C_transfer(I2C_Handle handle,
                                 I2C_Transaction *transaction)
    @@ -1778,9 +1796,10 @@ int32_t I2C_transfer(I2C_Handle handle,
                       * Wait for the transfer to complete here.
                       * It's OK to block from here because the I2C's Hwi will unblock
                       * upon errors
    -                  */DebugP_log("\r\n -%s:%d transaction->timeout:%d\r\n",__FUNCTION__,__LINE__,transaction->timeout);
    +                  */
    +                DebugP_log("\r\n -%s:%d transaction->timeout:%d gcount:%d\r\n",__FUNCTION__,__LINE__,transaction->timeout,gcount);
                     retVal = SemaphoreP_pend(&object->transferComplete, transaction->timeout);
    -                DebugP_log("\r\n -%s:%d \r\n",__FUNCTION__,__LINE__);
    +                  DebugP_log("\r\n -%s:%d transaction->timeout:%d gcount:%d\r\n",__FUNCTION__,__LINE__,transaction->timeout,gcount);
                     if ( retVal != SystemP_SUCCESS)
    

     void I2C_transferCallback(I2C_Handle handle,
                                         I2C_Transaction *msg,
                                         int32_t transferStatus)
     {
         I2C_Object   *object;
    -
    +       DebugP_log("\r\n -%s:%d transferStatus %d\r\n",__FUNCTION__,__LINE__,transferStatus);
    +    gcount++;
    +    if (gcount > 32)gcount = 0;
         /* Input parameter validation */
         if (handle != NULL)
         {
    

  • May I ask if there is a reply

  • Hello,

    Thanks for your patience.

    I am in a full day training for next few days. So responses to this thread may be delayed. Thanks for your cooperation.

    Regards,

    Tushar

  • hi Tushar:

    When you finish, please help solve this problem

  • Hi Wu,

    Yes sure we will get back on this thread once the trainings are over.

    Thanks for your patience.

    Regards,

    Vaibhav

  • Hi Daiwei:

    If you want AM62Ax Linux side provide I2C slave function. Maybe you can follow those patch modify.

    This is TI Linux I2C slave mode driver for old AM33x device. Believe it can help you enable Linux side I2C slave feature of AM62Ax. It is same family SOC.

    https://github.com/enndubyu/omap_i2c_slave/tree/master

    Best Regards!

    Han Tao

  • Please note that the Linux driver Tao linked is NOT developed, tested, or supported by TI. For the reasons that TI does not support I2C slave on Linux, refer to https://e2e.ti.com/support/processors-group/processors/f/processors-forum/1024619/am6412-i2c-multi-master-mode/3793533#3793533

    For additional information on I2C slave from the Linux standpoint, refer to https://e2e.ti.com/support/processors-group/processors/f/processors-forum/887456/am3354-i2c-slave-mode-support 

    Vaibhav still needs to respond from the MCU+ side.

    Regards,

    Nick

  • hi Vaibhav 

    mcu side i2c1 slave

    static int gslave = 1;
    void i2c_slave_test() {
    	I2C_Params      params;
    
    	I2C_Params_init(&params);
    	
    	uint8_t         txBuffer[I2C_WRITE_LEN];
    	uint8_t         rxBuffer[3];
    	params.transferMode  = I2C_MODE_BLOCKING;
    	params.transferCallbackFxn = ptransferCallbackFxn;
    	I2C_init();
    	DebugP_log("\r\n -CONFIG_I2C1:%d\n",CONFIG_I2C1);
    	ggI2cHandle = I2C_open(CONFIG_I2C1, &params);
    //	ggI2cHandle = gI2cHandle[CONFIG_I2C1];
    	if (!ggI2cHandle) {
    	DebugP_assert(FALSE);
    	}
    	int32_t status;
     
        I2C_Transaction i2cTransaction;
        I2C_Transaction i2cTransactionw;
    
        I2C_Transaction_init(&i2cTransaction);
      
        // i2cTransaction.writeBuf = txBuffer;
        // i2cTransaction.writeCount = I2C_WRITE_LEN;
    	// txBuffer[0] = 0x15;
    	// txBuffer[1] = 0x12;
      
        i2cTransaction.readBuf = rxBuffer;
        i2cTransaction.readCount = 2U;
    	i2cTransaction.slaveAddress = I2C_SLAVE_ADDR;
    
    	i2cTransaction.masterMode = false;
    
    
    	i2cTransactionw = i2cTransaction;
        i2cTransactionw.writeBuf = txBuffer;
        i2cTransactionw.writeCount = I2C_WRITE_LEN;
    	txBuffer[0] = 0x15;
    	txBuffer[1] = 0x12;	// i2cTransaction.timeout = 2;
    //	status = I2C_transfer(ggI2cHandle, &i2cTransaction);
    
    	for (;;) {
    		
    		/*txBuffer[0]+=1;
    		if (txBuffer[0] > 28)txBuffer[0] = 0;*/
    		DebugP_log("\r\n 1txBuffer[0]%d \n",txBuffer[0]);
    		status = I2C_transfer(ggI2cHandle, &i2cTransaction);
    		// if (i2cTransaction.readCount == 1 && i2cTransaction.writeCount == 1){
    		// 	if (rxBuffer[0]==0x40)
    		// 	{
    		// 		DebugP_log("\r\n 2txBuffer[0]%d\n",txBuffer[0]);
    		// 		txBuffer[0]+=1;
    		// 		if (txBuffer[0] > 28)txBuffer[0] = 0;
    		// 	}
    		// }
    		DebugP_log("\r\n status %d--------------------------------rxbuf-------------->0x%x-0x%x r-count:%d w-count%d\n",status,rxBuffer[0],rxBuffer[1],i2cTransaction.readCount,i2cTransaction.writeCount);	
    		status = I2C_transfer(ggI2cHandle, &i2cTransactionw);
    
    		DebugP_log("\r\n status %d--------------------------------txbuf-------------->0x%x-0x%x r-count:%d w-count%d\n",status,txBuffer[0],txBuffer[1],i2cTransaction.readCount,i2cTransaction.writeCount);	
    
    		txBuffer[0]+=1;
    		if (txBuffer[0] > 28)txBuffer[0] = 0;
    		#if 0
    		I2C_Transaction i2cTransaction;
    		I2C_Transaction_init(&i2cTransaction);
    
    		i2cTransaction.writeBuf = txBuffer;
    		i2cTransaction.writeCount = I2C_WRITE_LEN;
    		txBuffer[0] = 0x15;
    		txBuffer[1] = 0x12;
    
    		i2cTransaction.readBuf = rxBuffer;
    		i2cTransaction.readCount = 2U;
    		i2cTransaction.slaveAddress = I2C_SLAVE_ADDR;
    
    		i2cTransaction.masterMode = false;
    		#endif
    //		if (SystemP_SUCCESS != status) {
    //		DebugP_assert(FALSE);
    //		}
    
    	}
    //	while (1) {
    //
    //	}
    }	
    

    linux side i2c2 master 

    while true;do i2cset -f -y 2 0x49 0x0 0x1;sleep 1; i2cget -f -y 2 0x49 0x40;sleep 1;done;
    
    

    Write and read one i2cTransaction each, test the program first and then read it. It seems that the test will not get stuck. At the beginning, it was required that the master read and write in a fixed order to not get stuck, but I don't understand why the same i2cTransaction cannot be used (it will get stuck)

  • Hi Wu,

    Thanks for your patience.

    At the beginning, it was required that the master read and write in a fixed order to not get stuck

    This should not be the case, as the protocol itself asks for either a read operation as a whole or write + read operation as a whole, but not read + write as a compulsory operation.

    mcu side i2c1 slave

    So the code you sent me, one is for MCU_I2C1 as a Peripheral(Slave) and SoC_I2C2 or MAIN_I2C2 as Controller(Master).

    I have gone through the Device Tree Source file and found out that the pinmux configuration for MAIN_I2C2 is incorrect in the Processor SDK Linux for AM62A.

    Currently the defined pinmux configuration for MAIN_I2C2 is as follows in the dts:

        main_i2c2_pins_default: main-i2c2-pins-default {
            pinctrl-single,pins = <
                AM62AX_IOPAD(0x0b0, PIN_INPUT_PULLUP, 1) /* (K22) GPMC0_CSn2.I2C2_SCL */
                AM62AX_IOPAD(0x0b4, PIN_INPUT_PULLUP, 1) /* (K24) GPMC0_CSn3.I2C2_SDA */
            >;
        };

    But instead of K22 and K24 it should be M22 and M20.

    This information can be verified from the SysConfig tool as well as attached below.

    Can you try modifying the pins and trying again?

    Regards,

    Vaibhav

  • about test case

    So there's an issue with the sample I sent. Can you send me a MCU demo of i2c slave2 that can communicate for me to test?

    In the previous code, we shared an i2cTransaction that includes read and write buf, but the read and write of the i2c master cannot coexist and can only be written and read separately after startup, otherwise it will get stuck

    about pinmux

    This is not a pin issue. Although it is marked as K22, the offset of the register is M22

  • Hi Wu,

    Thanks for your patience.

    This is not a pin issue. Although it is marked as K22, the offset of the register is M22

    Thanks for correcting me on this.

    Can you send me a MCU demo of i2c slave2 that can communicate for me to test

    Sure I will write a code for this and send it to you.

    Regards,

    Vaibhav

  • hi Vaibhav

    I didn't receive the sample, so I'm sure it's not a bug, but just an interface usage issue

  • Hi Wu,

    Thanks for your patience.

    I didn't receive the sample, so I'm sure it's not a bug, but just an interface usage issue

    By sample do you mean the sample code which I am supposed to send or the signals on the oscilloscope if you are checking any.

    Looking forward to your response.

    Regards,

    Vaibhav

  • U said:
    Can you send me a MCU demo of i2c slave2 that can communicate for me to test

    Sure I will write a code for this and send it to you.

    -----------------------------------------------------------------------------------------------------------------

    So will you send me this slide demo for my reference?

  • Hi Wu,

    Here is what my action plan is. One or two of the points might be repetitive but here we go.

    So, to demonstrate the I2C slave we currently do not have any MCU PLUS SDK example which explains this.

    But the field while declaring the I2C params has one such attribute called masterMode which can be set to False to operate a specific I2C in slave mode.

    So, a while ago I wrote an implementation of MCSPI Controller and peripheral(Both controller and peripheral are on the same board). Over there I used IPC Notify Synchronization mechanism to make sure there is proper flow for the data being sent out. E2E: https://e2e.ti.com/support/processors-group/processors/f/processors-forum/1305146/sk-am64b-r5f-spi-dma-in-mcspi_ms_mode_peripheral/5064289#5064289

    The flow for MCSPI is as follows:

    • Controller implementation

      • Drivers_open() and Board_driversOpen().

      • IpcNotify_syncAll(SystemP_WAIT_FOREVER)

      • Set up TX and RX Buffers

      • Sleep for 5000 microseconds

      • Initiate MCSPI Transfer
      • Compare the data received in rxBuffer from the MCSPI Peripheral
      • IpcNotify_syncAll(SystemP_WAIT_FOREVER)

      • Drivers_close() and Board_driversClose().




    • Peripheral implementation

      • Drivers_open() and Board_driversOpen().

      • Set up TX and RX Buffers

      • IpcNotify_syncAll(SystemP_WAIT_FOREVER)
      • Initiate MCSPI Transfer

      • IpcNotify_syncAll(SystemP_WAIT_FOREVER)

      • Drivers_close() and Board_driversClose().

    Notice the sync mechanism used using IPC.

    I think a similar implementation can be followed for I2C and it would look as follows:

    The supposed to be flow for I2C is as follows:

    • Controller implementation

      • Drivers_open() and Board_driversOpen().

      • IpcNotify_syncAll(SystemP_WAIT_FOREVER)

      • Set up TX and RX Buffers

      • Sleep for 5000 microseconds

      • Initiate I2C Transfer

      • Compare the data received in rxBuffer from the I2C Peripheral

      • IpcNotify_syncAll(SystemP_WAIT_FOREVER)

      • Drivers_close() and Board_driversClose().




    • Peripheral implementation

      • Drivers_open() and Board_driversOpen().

      • Set up TX and RX Buffers

      • IpcNotify_syncAll(SystemP_WAIT_FOREVER)

      • Initiate I2C Transfer

      • IpcNotify_syncAll(SystemP_WAIT_FOREVER)

      • Drivers_close() and Board_driversClose().

    I am thinking of firstly implementing this on the MCU side, sort of a MCU Controller and Peripheral example.

    Do you have bandwidth for me to allow making a code for this and test it purely based out of MCU PLUS SDK and then if it works we can actually confirm that I2C slave is operating properly. Else if the I2C slave mode fails then we need to raise a bug for it.

    Regards,

    Vaibhav

  • I look forward to testing on your end after implementing the MCU i2c slave routine

  • Hi Wu,

    So I got a chance to sit alongside a dev and make an application for demonstrating the I2C Slave mode.

    Few things we debugged and found out about the driver are as follows: (This was done on AM243-LP, setup: MAIN_I2C0 Controller R5F0_0 and MAIN_I2C1 Peripheral/Slave R5F0_1)

    1. The first run ensures that the master receives the data correctly from the slave.

    2. The second run causes some issues, where the transaction handle becomes null and the semaphore is still pending from slave's application point of view. (NOTE: We are working and debugging closely to understand the driver which handles slave operation and interrupts)

    3. We did not use any sync mechanism, our flow was as follows:
      1. Firstly load the slave application .out to R5F0_1 and hit run.
      2. Secondly load the controller application .out to R5F0_0 and hit run and then you see that you receive the data from the peripheral/slave.
      3. The moment we try to receive data once again, we see the problems as mentioned above in the point 2.

    I am going to attach the application for the Controller and Peripheral despite it being for AM243-LP for you to go through the same.

    i2c slave.zip

    Please note that R50_0 has MAIN_I2C0 as the Controller and R50_1 has MAIN_I2C1 as the Peripheral.

    While you go through the Controller code implementation you will see that the I2C slave mentioned is 0x1C, the reason for this being that the Slave identifies itself at 0x1C slave address. This can be seen from SysConfig as well. I have attached the relevant screenshot below.






    Hope this helps upto some extent meanwhile we continue the debugging.

    Regards,

    Vaibhav

  • ok, Thank you for your support

    We have also encountered this issue here

    The second run causes some issues, where the transaction handle becomes null and the semaphore is still pending from slave's application point of view. (NOTE: We are working and debugging closely to understand the driver which handles slave operation and interrupts)

    Please note that R50_0 has MAIN_I2C0 as the Controller and R50_1 has MAIN_I2C1 as the Peripheral.

    We confirm that the configuration method for this address is consistent, and in addition, this address should be able to be configured through the configuration file

    +I2c1. ownSlaveAddr1=0x49// Slave address configuration


    In addition, what is ultimately required is simultaneous reading and writing

  • Hi Wu,

    Thank you for your response.

    The second run causes some issues, where the transaction handle becomes null and the semaphore is still pending from slave's application point of view.

    Yes this what we also encountered while testing on our end.

    I am going to try to debug this along with the driver owner and see if we can find a fix for this and resolve this bug.

    Regards,

    Vaibhav

  • Hi Wu,

    I am going to raise a JIRA for this to track the official fix for this.

    Good News!! We have been able to debug and make the I2C Slave working for continuous transactions.

    The above code which I shared, so master code will remain the same, only there will be changes in the slave code.

    So, I am attaching the .c file and the SysConfig I2C declaration as well for you to go through.

    Apart from this there are changes in i2c_v0.c and i2c_v0_lld.c, these two files I am attaching as well.

    slave.c file

    /*
     *  Copyright (C) 2021 Texas Instruments Incorporated
     *
     *  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.
     */
    
    #include <stdio.h>
    #include <kernel/dpl/DebugP.h>
    #include "ti_drivers_config.h"
    #include "ti_drivers_open_close.h"
    #include "ti_board_open_close.h"
    #include <kernel/dpl/SemaphoreP.h>
    
    /*
     * This is an empty project provided for all cores present in the device.
     * User can use this project to start their application by adding more SysConfig modules.
     *
     * This application does driver and board init and just prints the pass string on the console.
     * In case of the main core, the print is redirected to the UART console.
     * For all other cores, CCS prints are used.
     */
    
    int32_t         status;
    uint8_t         rxBuffer[1];
    uint8_t         txBuffer[3];
    I2C_Handle      i2cHandle;
    I2C_Transaction i2cTransaction;
    uint32_t transactionID = 0U;
    SemaphoreP_Object   trComp;
    
    static void i2c_read_error_handler(int32_t status);
    
    void My_Callback(I2C_Handle handle,
                     I2C_Transaction *msg,
                     int32_t transferStatus)
    {
    
        (void)SemaphoreP_post(&trComp);
    }
    
    void empty_main(void *args)
    {
    
        // Slave
    
    
        txBuffer[0] = 4U;
        txBuffer[1] = 5U;
        txBuffer[2] = 6U;
    
    
    
        /* Open drivers to open the UART driver for console */
        Drivers_open();
        Board_driversOpen();
    
        i2cHandle = gI2cHandle[CONFIG_I2C0];
        SemaphoreP_constructBinary(&trComp, 0);
    
        while(1)
        {
            /* Set default transaction parameters */
            I2C_Transaction_init(&i2cTransaction);
    
            /* Override with required transaction parameters */
            i2cTransaction.writeBuf      = txBuffer;
            i2cTransaction.writeCount    = 3;
            i2cTransaction.readBuf      = rxBuffer;
            i2cTransaction.readCount    = 1;
            i2cTransaction.controllerMode = FALSE;
    
    
            txBuffer[0] = txBuffer[0] + 1U;
            txBuffer[1] = txBuffer[1] + 1U;
            txBuffer[2] = txBuffer[2] + 1U;
    
            status = I2C_transfer(i2cHandle, &i2cTransaction);
    
            (void)SemaphoreP_pend(&trComp, SystemP_WAIT_FOREVER);
        }
    
    
        Board_driversClose();
        Drivers_close();
    }
    
    static void i2c_read_error_handler(int32_t status)
    {
        switch(status)
        {
            case I2C_STS_ERR:
                DebugP_logError("[I2C] Generic error occurred");
                break;
            case I2C_STS_ERR_TIMEOUT:
                DebugP_logError("[I2C] Timeout error occurred");
                break;
            case I2C_STS_ERR_NO_ACK:
                DebugP_logError("[I2C] No acknowledgement received");
                break;
            case I2C_STS_ERR_ARBITRATION_LOST:
                DebugP_logError("[I2C] Arbitration lost");
                break;
            case I2C_STS_ERR_BUS_BUSY:
                DebugP_logError("[I2C] Bus Bus Busy error occurred");
                break;
        }
    
        return;
    }
    

    Slave SysConfig I2C declaration:

    i2c_v0_lld.c file present under mcu_plus_sdk_path/source/drivers/i2c/v0/lld/i2c_v0_lld.c

    /*
     * Copyright (C) 2024 Texas Instruments Incorporated
     *
     * 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   i2c_v0_lld.c
     *
     *  \brief  File containing I2C LLD Driver APIs implementation for V0.
     */
    
    /* ========================================================================== */
    /*                             Include Files                                  */
    /* ========================================================================== */
    
    #include <drivers/i2c/v0/lld/i2c_lld.h>
    #include <kernel/dpl/HwiP.h>
    #include <drivers/soc.h>
    
    /* ========================================================================== */
    /*                           Macros & Typedefs                                */
    /* ========================================================================== */
    /**
     *  \anchor I2CBufferStatus
     *  \name I2CBufferStatus API Values
     *  @{
     */
    #define I2C_TX_BUFFER_STATUS        ((uint32_t) 0U)
    #define I2C_RX_BUFFER_STATUS        ((uint32_t) 1U)
    /** \brief  Internal FIFO depth flag */
    #define I2C_FIFO_DEPTH              ((uint32_t) 2U)
    /** @} */
    
    /**
     *  \anchor I2CFIFOThresholdConfig/I2CFIFOClear
     *  \name I2CFIFOThresholdConfig/I2CFIFOClear API Values
     *  @{
     */
    #define I2C_TX_MODE                 ((uint32_t) 1U)
    #define I2C_RX_MODE                 ((uint32_t) 0U)
    /** @} */
    
    /**
     *  \anchor I2CControllerIntEnableEx
     *  \name I2CControllerIntEnableEx API Values
     *  @{
     */
    /** \brief Arbitration lost interrupt */
    #define I2C_INT_ARBITRATION_LOST    ((uint32_t) I2C_IRQSTATUS_AL_MASK)
    /** \brief No acknowledgement interrupt */
    #define I2C_INT_NO_ACK              ((uint32_t) I2C_IRQSTATUS_NACK_MASK)
    /** \brief Register access ready interrupt */
    #define I2C_INT_ADRR_READY_ACESS    ((uint32_t) I2C_IRQSTATUS_ARDY_MASK)
    /** \brief Receive data ready interrupt */
    #define I2C_INT_RECV_READY          ((uint32_t) I2C_IRQSTATUS_RRDY_MASK)
    /** \brief Transmit data ready interrupt */
    #define I2C_INT_TRANSMIT_READY      ((uint32_t) I2C_IRQSTATUS_XRDY_MASK)
    /** \brief General call Interrupt */
    #define I2C_INT_GENERAL_CALL        ((uint32_t) I2C_IRQSTATUS_GC_MASK)
    /** \brief Start Condition interrupt */
    #define I2C_INT_START               ((uint32_t) I2C_IRQSTATUS_STC_MASK)
    /** \brief Access Error interrupt */
    #define I2C_INT_ACCESS_ERROR        ((uint32_t) I2C_IRQSTATUS_AERR_MASK)
    /** \brief Bus Free interrupt */
    #define I2C_INT_STOP_CONDITION      ((uint32_t) I2C_IRQSTATUS_BF_MASK)
    /** \brief Addressed as Target interrupt */
    #define I2C_INT_ADRR_TARGET         ((uint32_t) I2C_IRQSTATUS_AAS_MASK)
    /** \brief Transmit underflow interrupt */
    #define I2C_INT_TRANSMIT_UNDER_FLOW ((uint32_t) I2C_IRQSTATUS_XUDF_MASK)
    /** \brief Receive overrun interrupt */
    #define I2C_INT_RECV_OVER_RUN       ((uint32_t) I2C_IRQSTATUS_ROVR_MASK)
    /** \brief Receive Draining interrupt */
    #define I2C_INT_RECV_DRAIN          ((uint32_t) I2C_IRQSTATUS_RDR_MASK)
    /** \brief Transmit Draining interrupt */
    #define I2C_INT_TRANSMIT_DRAIN      ((uint32_t) I2C_IRQSTATUS_XDR_MASK)
    /** \brief Bus busy interrupt raw status */
    #define I2C_INT_BUS_BUSY            ((uint32_t) I2C_IRQSTATUS_RAW_BB_MASK)
    /** \brief Bus free interrupt raw status */
    #define I2C_INT_BUS_FREE            ((uint32_t) I2C_IRQSTATUS_RAW_BF_MASK)
    /** \brief Enable all interrupt */
    #define I2C_INT_ALL                 ((uint32_t) 0x7FFFU)
    /** @} */
    
    
    /**
     *  \anchor I2CControllerControl
     *  \name I2CControllerControl API Values
     *  @{
     */
    /** \brief Controller transmit mode. */
    #define I2C_CFG_MST_TX              (((uint32_t) I2C_CON_TRX_MASK) | \
                                                 (uint32_t) (I2C_CON_MST_MASK))
    /** \brief Controller receive mode. */
    #define I2C_CFG_MST_RX              ((uint32_t) I2C_CON_MST_MASK)
    /** \brief Stop condition. */
    #define I2C_CFG_STOP                ((uint32_t) I2C_CON_STP_MASK)
    /** \brief Normal mode. */
    #define I2C_CFG_N0RMAL_MODE         ((uint32_t) 0 << I2C_CON_STB_SHIFT)
    /** \brief Start byte mode. */
    #define I2C_CFG_SRT_BYTE_MODE       ((uint32_t) I2C_CON_STB_MASK)
    /** \brief 7 bit target address. */
    #define I2C_CFG_7BIT_TARGET_ADDR    ((uint32_t) 0 << I2C_CON_XSA_SHIFT)
    /** \brief 10 bit target address. */
    #define I2C_CFG_10BIT_TARGET_ADDR   ((uint32_t) I2C_CON_XSA_MASK)
    /** \brief Controller mode 10 bit own address 0 */
    #define I2C_CFG_10BIT_OWN_ADDR_0    ((uint32_t) I2C_CON_XOA0_MASK)
    /** \brief Controller mode 10 bit own address 1 */
    #define I2C_CFG_10BIT_OWN_ADDR_1    ((uint32_t) I2C_CON_XOA1_MASK)
    /** \brief Controller mode 10 bit own address 2 */
    #define I2C_CFG_10BIT_OWN_ADDR_2    ((uint32_t) I2C_CON_XOA2_MASK)
    /** \brief Controller mode 10 bit own address 3 */
    #define I2C_CFG_10BIT_OWN_ADDR_3    ((uint32_t) I2C_CON_XOA3_MASK)
    /** \brief Controller mode 7 bit own address 0 */
    #define I2C_CFG_7BIT_OWN_ADDR_0     ((uint32_t) 0 << I2C_CON_XOA0_SHIFT)
    /** \brief Controller mode 7 bit own address 1 */
    #define I2C_CFG_7BIT_OWN_ADDR_1     ((uint32_t) 0 << I2C_CON_XOA1_SHIFT)
    /** \brief Controller mode 7 bit own address 2 */
    #define I2C_CFG_7BIT_OWN_ADDR_2     ((uint32_t) 0 << I2C_CON_XOA2_SHIFT)
    /** \brief Controller mode 7 bit own address 3 */
    #define I2C_CFG_7BIT_OWN_ADDR_3     ((uint32_t) 0 << I2C_CON_XOA3_SHIFT)
    /** \brief I2C module enable */
    #define I2C_CFG_MST_ENABLE          ((uint32_t) I2C_CON_I2C_EN_MASK)
    /** \brief Start condition, initiate I2C transfer */
    #define I2C_CFG_START               ((uint32_t) I2C_CON_STT_MASK)
    /** \brief I2C configure controller mode. */
    #define I2C_CFG_MST                 ((uint32_t) I2C_CON_MST_MASK)
    /** \brief High speed operation mode */
    #define I2C_CFG_HS_MOD              ((uint32_t) CSL_I2C_CON_OPMODE_HSI2C << CSL_I2C_CON_OPMODE_SHIFT)
    /** @} */
    
    /**
     *  \anchor ownAddressSet
     *  \name ownAddressSet API Values
     *  @{
     */
    #define I2C_OWN_ADDR_0              ((uint32_t) 0U)
    #define I2C_OWN_ADDR_1              ((uint32_t) 1U)
    #define I2C_OWN_ADDR_2              ((uint32_t) 2U)
    #define I2C_OWN_ADDR_3              ((uint32_t) 3U)
    /** @} */
    
    /**
     *  \anchor I2C_Prescaler
     *  \name MACROS used to in Prescaling I2C Clock.
     *  @{
     */
    #define I2C_MAX_CLK_PRESCALAR       ((uint32_t) 255U)
    #define I2C_INTERNAL_CLK_STEP       ((uint32_t) 1000000U)
    /** @} */
    
    #define I2C_DELAY_MED               ((uint32_t) 10000U)
    #define I2C_DELAY_BIG               ((uint32_t) 30000U)
    #define I2C_DELAY_SMALL             ((uint32_t) 5000U)
    
    #define I2C_BUS_BUSY_TIMEOUT_IN_US          ((uint32_t) 500U)
    
    #define I2C_MODULE_INTERNAL_CLK_4MHZ        ((uint32_t) 4000000U)
    #define I2C_MODULE_INTERNAL_CLK_12MHZ       ((uint32_t) 12000000U)
    
    #define I2C_MAX_CONSECUTIVE_ISRS            ((uint32_t) 1U)
    
    
    /* ========================================================================== */
    /*                         Structure Declarations                             */
    /* ========================================================================== */
    
    /* Default I2C transaction parameters structure */
    const I2CLLD_Transaction I2C_lld_defaultTransaction = {
    
        NULL,                                       /* writeBuf */
        0,                                          /* writeCount */
        NULL,                                       /* readBuf */
        0,                                          /* readCount */
    };
    
    /* Default I2C Message parameters structure */
    const I2CLLD_Message I2C_lld_defaultMessage = {
        NULL,                                       /* txnArray */
        0,                                          /* txnCount */
        0,                                          /* targetAddress */
        NULL,                                       /* arg */
        I2C_WAIT_FOREVER,                           /* timeout */
        true,                                       /* controllerMode */
        false                                       /* expandSA */
    };
    
    /* ========================================================================== */
    /*                      Internal Function Declarations                        */
    /* ========================================================================== */
    static void I2CControllerInitExpClk(uint32_t baseAddr, uint32_t sysClk,
                                        uint32_t internalClk, uint32_t outputClk);
    static void I2CControllerEnable(uint32_t baseAddr);
    static void I2CControllerDisable(uint32_t baseAddr);
    static void I2CControllerEnableFreeRun(uint32_t baseAddr);
    static void I2CControllerSetSysTest(uint32_t baseAddr, uint32_t sysTest);
    static void I2CControllerControl(uint32_t baseAddr, uint32_t cmd);
    static void I2CControllerStart(uint32_t baseAddr);
    static void I2CControllerStop(uint32_t baseAddr);
    static void I2CControllerIntEnableEx(uint32_t baseAddr, uint32_t intFlag);
    static void I2CTargetIntEnableEx(uint32_t baseAddr, uint32_t intFlag);
    static void I2CControllerIntDisableEx(uint32_t baseAddr, uint32_t intFlag);
    static void I2CTargetIntDisableEx(uint32_t baseAddr, uint32_t intFlag);
    static void I2CControllerIntClearEx(uint32_t baseAddr, uint32_t intFlag);
    static void I2CTargetIntClearEx(uint32_t baseAddr, uint32_t intFlag);
    static void I2CControllerTargetAddrSet(uint32_t baseAddr, uint32_t targetAdd);
    static void I2CSetDataCount(uint32_t baseAddr, uint32_t count);
    static void I2CFIFOClear(uint32_t baseAddr, uint32_t flag);
    static void I2COwnAddressSet(uint32_t baseAddr, uint32_t ownAdd, uint32_t flag);
    static void I2CSoftReset(uint32_t baseAddr);
    static void I2CAutoIdleDisable(uint32_t baseAddr);
    static void I2CControllerDataPut(uint32_t baseAddr, uint8_t data);
    static void I2CSyscInit(uint32_t baseAddr, uint32_t syscFlag);
    static void I2CConfig(uint32_t baseAddr, uint32_t conParams);
    
    static uint32_t I2CControllerGetSysTest(uint32_t baseAddr);
    static uint32_t I2CControllerIntStatus(uint32_t baseAddr);
    static uint32_t I2CControllerIntRawStatus(uint32_t baseAddr);
    static uint32_t I2CTargetIntRawStatus(uint32_t baseAddr);
    static uint32_t I2CControllerIntRawStatusEx(uint32_t baseAddr,
                                                uint32_t intFlag);
    static uint32_t I2CGetEnabledIntStatus(uint32_t baseAddr, uint32_t intFlag);
    static uint32_t I2CDataCountGet(uint32_t baseAddr);
    static uint32_t I2CBufferStatus(uint32_t baseAddr, uint32_t flag);
    static uint32_t I2CSystemStatusGet(uint32_t baseAddr);
    
    static uint8_t I2CControllerDataGet(uint32_t baseAddr);
    static uint8_t I2CTargetDataGet(uint32_t baseAddr);
    
    static int32_t I2CControllerBusBusy(uint32_t baseAddr);
    
    
    static int32_t I2C_waitForBb(   I2CLLD_Handle handle, uint32_t timeout);
    static int32_t I2C_waitForPin(  I2CLLD_Handle handle, uint32_t flag,
                                    uint32_t *pTimeout);
    
    static int32_t I2C_lld_primeTransferPoll(   I2CLLD_Handle handle);
    static int32_t I2C_lld_primeTransferIntr(   I2CLLD_Handle handle);
    static void I2C_lld_completeCurrTransfer(   I2CLLD_Handle handle,
                                                int32_t xferStatus);
    static void I2C_lld_completeCurrTargetTransfer( I2CLLD_Handle handle,
                                                    int32_t xferStatus);
    static int32_t I2C_lld_transferInit(I2CLLD_Handle handle,
                                        I2CLLD_Message *msg);
    
    static int32_t I2C_lld_resetCtrl(I2CLLD_Handle handle);
    static int32_t I2C_lld_ctrlInit(I2CLLD_Handle handle);
    
    /* ========================================================================== */
    /*                       API Function Definitions                             */
    /* ========================================================================== */
    
    int32_t I2C_lld_init(I2CLLD_Handle handle)
    {
        int32_t             status = I2C_STS_SUCCESS;
        I2CLLD_Object       *object = NULL;
        uint32_t            outputClk;
        uint32_t            internalClk;
    
        if(handle != NULL)
        {
            /* Get pointer to driver Object */
            object = (I2CLLD_Object *) handle;
            /* State should be reset before initialization */
            if(object->state != I2C_STATE_RESET)
            {
                status = I2C_STS_ERR;
            }
        }
        else
        {
            status = I2C_STS_ERR_INVALID_PARAM;
        }
    
        if(status == I2C_STS_SUCCESS)
        {
            /* check if the I2C base address is valid or not */
            status = I2C_lld_isBaseAddrValid(object->baseAddr);
        }
    
        if(status == I2C_STS_SUCCESS)
        {
            /* Specify the busy state for this I2C peripheral */
            object->state = I2C_STATE_BUSY;
            /* Clear the current message pointer */
            object->currentMsg = NULL;
            /* Clear the current target transaction pointer */
            object->currentTargetTransaction = NULL;
            /* Set args as null */
            object->args = NULL_PTR;
    
            /* Put i2c in reset/disabled state */
            I2CControllerDisable(object->baseAddr);
            /* Disable Auto Idle functionality */
            I2CAutoIdleDisable(object->baseAddr);
            /* Extract bit rate from the input parameter */
            switch(object->bitRate)
            {
                case I2C_100KHZ:
                {
                    outputClk = 100000U;
                    internalClk = I2C_MODULE_INTERNAL_CLK_4MHZ;
                    break;
                }
    
                case I2C_400KHZ:
                {
                    outputClk = 400000U;
                    internalClk = I2C_MODULE_INTERNAL_CLK_12MHZ;
                    break;
                }
    
                case I2C_1P0MHZ:
                {
                    outputClk = 1000000U;
                    internalClk = I2C_MODULE_INTERNAL_CLK_12MHZ;
                    break;
                }
    
                case I2C_3P4MHZ:
                {
                    outputClk = 3400000U;
                    internalClk = I2C_MODULE_INTERNAL_CLK_12MHZ;
                    break;
                }
    
                default:
                {
                    /* Default case force it to 100 KHZ bit rate */
                    outputClk = 100000U;
                    internalClk = I2C_MODULE_INTERNAL_CLK_4MHZ;
                    break;
                }
            }
    
            /* Set the I2C configuration */
            I2CControllerInitExpClk(object->baseAddr, object->funcClk,
                                    internalClk, outputClk);
            /* Clear any pending interrupts */
            I2CControllerIntClearEx(object->baseAddr, I2C_INT_ALL);
            /* Mask off all interrupts */
            I2CControllerIntDisableEx(object->baseAddr, I2C_INT_ALL);
            /* Enable the I2C Controller for operation */
            I2CControllerEnable(object->baseAddr);
            /* Enable free run mode */
            I2CControllerEnableFreeRun(object->baseAddr);
            /* Specify the idle state for this I2C peripheral */
            object->state = I2C_STATE_IDLE;
        }
    
        return status;
    }
    
    int32_t I2C_lld_deInit(I2CLLD_Handle handle)
    {
        int32_t             status = I2C_STS_SUCCESS;
        I2CLLD_Object       *object = NULL;
    
        /* Input parameter validation */
        if (handle != NULL)
        {
            /* Get the pointer to the object */
            object = (I2CLLD_Object*)handle;
    
            /* Check to see if a I2C transaction is in progress */
            if (object->currentMsg == NULL)
            {
                /* Mask I2C interrupts */
                I2CControllerIntDisableEx(object->baseAddr, I2C_INT_ALL);
                /* Disable the I2C Controller */
                I2CControllerDisable(object->baseAddr);
                /* Change driver state back to RESET */
                object->state = I2C_STATE_RESET;
            }
            else
            {
                status = I2C_STS_ERR;
            }
        }
        else
        {
            status = I2C_STS_ERR_INVALID_PARAM;
        }
    
        return status;
    }
    
    int32_t I2C_lld_Transaction_init(I2CLLD_Transaction *transaction)
    {
        int32_t status = I2C_STS_SUCCESS;
    
        if(transaction != NULL)
        {
            *transaction = I2C_lld_defaultTransaction;
        }
        else
        {
            status = I2C_STS_ERR_INVALID_PARAM;
        }
    
        return status;
    }
    
    int32_t I2C_lld_Message_init(I2CLLD_Message *msg)
    {
        int32_t status = I2C_STS_SUCCESS;
    
        if(msg != NULL)
        {
            *msg = I2C_lld_defaultMessage;
        }
        else
        {
            status = I2C_STS_ERR_INVALID_PARAM;
        }
    
        return status;
    }
    
    int32_t I2C_lld_write(  I2CLLD_Handle handle,
                            I2C_ExtendedParams *extendedParams,
                            uint32_t timeout)
    {
        int32_t                 status = I2C_STS_SUCCESS;
        I2CLLD_Object           *object = NULL;
    
        if ((handle != NULL) && (extendedParams != NULL))
        {
            /* Get the pointer to the object */
            object = (I2CLLD_Object*)handle;
    
            if (object->state == I2C_STATE_IDLE)
            {
                /* No current transfer is going on. */
                /* TODO: This should happen automically. */
                object->state = I2C_STATE_BUSY;
    
                (void)I2C_lld_Transaction_init(&object->i2ctxn);
                object->i2ctxn.writeBuf      = extendedParams->buffer;
                object->i2ctxn.writeCount    = extendedParams->size;
    
                (void)I2C_lld_Message_init(&object->i2cMsg);
                object->i2cMsg.txn              = &object->i2ctxn;
                object->i2cMsg.txnCount         = 1U;
                object->i2cMsg.targetAddress    = extendedParams->deviceAddress;
                object->i2cMsg.expandSA         = extendedParams->expandSA;
                object->i2cMsg.timeout          = timeout;
    
                object->currentMsg = &object->i2cMsg;
                object->currentTxnCount = 0U;
    
                status = I2C_lld_primeTransferPoll(handle);
            }
            else
            {
                status = I2C_STS_ERR_BUS_BUSY;
            }
        }
        else
        {
            status = I2C_STS_ERR_INVALID_PARAM;
        }
    
        return status;
    }
    
    int32_t I2C_lld_writeIntr(  I2CLLD_Handle handle,
                                I2C_ExtendedParams *extendedParams)
    {
        int32_t                 status = I2C_STS_SUCCESS;
        I2CLLD_Object           *object = NULL;
    
        if ((handle != NULL) && (extendedParams != NULL))
        {
            /* Get the pointer to the object */
            object = (I2CLLD_Object*)handle;
    
            if (object->state == I2C_STATE_IDLE)
            {
                /* No current transfer is going on. */
                /* TODO: This should happen automically. */
                object->state = I2C_STATE_BUSY;
    
                (void)I2C_lld_Transaction_init(&object->i2ctxn);
                object->i2ctxn.writeBuf      = extendedParams->buffer;
                object->i2ctxn.writeCount    = extendedParams->size;
    
                (void)I2C_lld_Message_init(&object->i2cMsg);
                object->i2cMsg.txn              = &object->i2ctxn;
                object->i2cMsg.txnCount         = 1U;
                object->i2cMsg.targetAddress    = extendedParams->deviceAddress;
                object->i2cMsg.expandSA         = extendedParams->expandSA;
    
                object->currentMsg = &object->i2cMsg;
                object->currentTxnCount = 0U;
    
                status = I2C_lld_primeTransferIntr(handle);
            }
            else
            {
                status = I2C_STS_ERR_BUS_BUSY;
            }
        }
        else
        {
            status = I2C_STS_ERR_INVALID_PARAM;
        }
    
        return status;
    }
    
    int32_t I2C_lld_read(   I2CLLD_Handle handle,
                            I2C_ExtendedParams *extendedParams,
                            uint32_t timeout)
    {
        int32_t                 status = I2C_STS_SUCCESS;
        I2CLLD_Object           *object = NULL;
    
        if ((handle != NULL) && (extendedParams != NULL))
        {
            /* Get the pointer to the object */
            object = (I2CLLD_Object*)handle;
    
            if (object->state == I2C_STATE_IDLE)
            {
                /* No current transfer is going on. */
                /* TODO: This should happen automically. */
                object->state = I2C_STATE_BUSY;
    
                (void)I2C_lld_Transaction_init(&object->i2ctxn);
                object->i2ctxn.readBuf      = extendedParams->buffer;
                object->i2ctxn.readCount    = extendedParams->size;
    
                (void)I2C_lld_Message_init(&object->i2cMsg);
                object->i2cMsg.txn              = &object->i2ctxn;
                object->i2cMsg.txnCount         = 1U;
                object->i2cMsg.targetAddress    = extendedParams->deviceAddress;
                object->i2cMsg.expandSA         = extendedParams->expandSA;
                object->i2cMsg.timeout          = timeout;
    
                object->currentMsg = &object->i2cMsg;
                object->currentTxnCount = 0U;
    
                status = I2C_lld_primeTransferPoll(handle);
            }
            else
            {
                status = I2C_STS_ERR_BUS_BUSY;
            }
        }
        else
        {
            status = I2C_STS_ERR_INVALID_PARAM;
        }
    
        return status;
    }
    
    int32_t I2C_lld_readIntr(   I2CLLD_Handle handle,
                                I2C_ExtendedParams *extendedParams)
    {
        int32_t                 status = I2C_STS_SUCCESS;
        I2CLLD_Object           *object = NULL;
    
        if ((handle != NULL) && (extendedParams != NULL))
        {
            /* Get the pointer to the object */
            object = (I2CLLD_Object*)handle;
    
            if (object->state == I2C_STATE_IDLE)
            {
                /* No current transfer is going on. */
                /* TODO: This should happen automically. */
                object->state = I2C_STATE_BUSY;
    
                (void)I2C_lld_Transaction_init(&object->i2ctxn);
                object->i2ctxn.readBuf      = extendedParams->buffer;
                object->i2ctxn.readCount    = extendedParams->size;
    
                (void)I2C_lld_Message_init(&object->i2cMsg);
                object->i2cMsg.txn              = &object->i2ctxn;
                object->i2cMsg.txnCount         = 1U;
                object->i2cMsg.targetAddress    = extendedParams->deviceAddress;
                object->i2cMsg.expandSA         = extendedParams->expandSA;
    
                object->currentMsg = &object->i2cMsg;
                object->currentTxnCount = 0U;
    
                status = I2C_lld_primeTransferIntr(handle);
            }
            else
            {
                status = I2C_STS_ERR_BUS_BUSY;
            }
        }
        else
        {
            status = I2C_STS_ERR_INVALID_PARAM;
        }
    
        return status;
    }
    
    int32_t I2C_lld_mem_write(  I2CLLD_Handle handle,
                                I2C_Memory_ExtendedParams *mem_extendedParams,
                                uint32_t timeout)
    {
        int32_t                 status = I2C_STS_SUCCESS;
        I2CLLD_Object           *object = NULL;
        uint32_t                buffer_len = 0U;
    
        if ((handle != NULL) && (mem_extendedParams != NULL))
        {
            /* Get the pointer to the object */
            object = (I2CLLD_Object*)handle;
    
            if (object->state == I2C_STATE_IDLE)
            {
                /* No current transfer is going on. */
                /* TODO: This should happen automically. */
                object->state = I2C_STATE_BUSY;
    
                buffer_len += mem_extendedParams->memAddrSize;
                buffer_len += mem_extendedParams->extendedParams.size;
    
                object->memTxnActive = true;
                object->memAddrSize = mem_extendedParams->memAddrSize;
                object->dataArray = &(mem_extendedParams->extendedParams.buffer[0]);
    
                if(mem_extendedParams->memAddrSize == I2C_MEM_ADDR_SIZE_8_BITS)
                {
                    object->addBuff[0] = (uint8_t)(mem_extendedParams->memAddr &
                                                    (uint32_t)0x00FF);
                }
                else if(mem_extendedParams->memAddrSize==I2C_MEM_ADDR_SIZE_16_BITS)
                {
                    object->addBuff[0] = (uint8_t)((mem_extendedParams->memAddr &
                                                    (uint32_t)0xFF00) >> 8U);
                    object->addBuff[1] = (uint8_t)(mem_extendedParams->memAddr &
                                                    (uint32_t)0x00FF);
                }
                else
                {
                    status = I2C_STS_ERR_INVALID_PARAM;
                }
    
                if(status == I2C_STS_SUCCESS)
                {
                    (void)I2C_lld_Transaction_init(&object->i2ctxn);
                    object->i2ctxn.writeBuf = &object->addBuff[0];
                    object->i2ctxn.writeCount = buffer_len;
    
                    (void)I2C_lld_Message_init(&object->i2cMsg);
                    object->i2cMsg.txn = &object->i2ctxn;
                    object->i2cMsg.txnCount = 1U;
                    object->i2cMsg.targetAddress =
                                mem_extendedParams->extendedParams.deviceAddress;
                    object->i2cMsg.expandSA =
                                mem_extendedParams->extendedParams.expandSA;
                    object->i2cMsg.timeout = timeout;
    
                    object->currentMsg = &object->i2cMsg;
                    object->currentTxnCount = 0U;
    
                    status = I2C_lld_primeTransferPoll(handle);
                }
    
                object->memTxnActive = false;
            }
            else
            {
                status = I2C_STS_ERR_BUS_BUSY;
            }
        }
        else
        {
            status = I2C_STS_ERR_INVALID_PARAM;
        }
    
        return status;
    }
    
    int32_t I2C_lld_mem_writeIntr(  I2CLLD_Handle handle,
                                    I2C_Memory_ExtendedParams *mem_extendedParams)
    {
        int32_t                 status = I2C_STS_SUCCESS;
        I2CLLD_Object           *object = NULL;
        uint32_t                buffer_len = 0U;
    
        if ((handle != NULL) && (mem_extendedParams != NULL))
        {
            /* Get the pointer to the object */
            object = (I2CLLD_Object*)handle;
    
            if (object->state == I2C_STATE_IDLE)
            {
                /* No current transfer is going on. */
                /* TODO: This should happen automically. */
                object->state = I2C_STATE_BUSY;
    
                buffer_len += mem_extendedParams->memAddrSize;
                buffer_len += mem_extendedParams->extendedParams.size;
    
                object->memTxnActive = true;
                object->memAddrSize = mem_extendedParams->memAddrSize;
                object->dataArray = &(mem_extendedParams->extendedParams.buffer[0]);
    
                if(mem_extendedParams->memAddrSize == I2C_MEM_ADDR_SIZE_8_BITS)
                {
                    object->addBuff[0] = (uint8_t)(mem_extendedParams->memAddr &
                                                    (uint32_t)0x00FF);
                }
                else if(mem_extendedParams->memAddrSize==I2C_MEM_ADDR_SIZE_16_BITS)
                {
                    object->addBuff[0] = (uint8_t)((mem_extendedParams->memAddr &
                                                    (uint32_t)0xFF00) >> 8U);
                    object->addBuff[1] = (uint8_t)(mem_extendedParams->memAddr &
                                                    (uint32_t)0x00FF);
                }
                else
                {
                    status = I2C_STS_ERR_INVALID_PARAM;
                }
    
                if(status == I2C_STS_SUCCESS)
                {
                    (void)I2C_lld_Transaction_init(&object->i2ctxn);
                    object->i2ctxn.writeBuf = &object->addBuff[0];
                    object->i2ctxn.writeCount = buffer_len;
    
                    (void)I2C_lld_Message_init(&object->i2cMsg);
                    object->i2cMsg.txn = &object->i2ctxn;
                    object->i2cMsg.txnCount = 1U;
                    object->i2cMsg.targetAddress =
                                mem_extendedParams->extendedParams.deviceAddress;
                    object->i2cMsg.expandSA =
                                mem_extendedParams->extendedParams.expandSA;
    
    
                    object->currentMsg = &object->i2cMsg;
                    object->currentTxnCount = 0U;
    
                    status = I2C_lld_primeTransferIntr(handle);
                }
            }
            else
            {
                status = I2C_STS_ERR_BUS_BUSY;
            }
        }
        else
        {
            status = I2C_STS_ERR_INVALID_PARAM;
        }
    
        return status;
    }
    
    int32_t I2C_lld_mem_read(   I2CLLD_Handle handle,
                                I2C_Memory_ExtendedParams *mem_extendedParams,
                                uint32_t timeout)
    {
        int32_t                 status = I2C_STS_SUCCESS;
        I2CLLD_Object           *object = NULL;
        uint32_t                buffer_len = 0U;
    
        if ((handle != NULL) && (mem_extendedParams != NULL))
        {
            /* Get the pointer to the object */
            object = (I2CLLD_Object*)handle;
    
            if (object->state == I2C_STATE_IDLE)
            {
                /* No current transfer is going on. */
                /* TODO: This should happen automically. */
                object->state = I2C_STATE_BUSY;
    
                buffer_len += mem_extendedParams->memAddrSize;
    
                object->memTxnActive = true;
    
                if(mem_extendedParams->memAddrSize == I2C_MEM_ADDR_SIZE_8_BITS)
                {
                    object->addBuff[0] = (uint8_t)(mem_extendedParams->memAddr &
                                                    (uint32_t)0x00FF);
                }
                else if(mem_extendedParams->memAddrSize==I2C_MEM_ADDR_SIZE_16_BITS)
                {
                    object->addBuff[0] = (uint8_t)((mem_extendedParams->memAddr &
                                                    (uint32_t)0xFF00) >> 8U);
                    object->addBuff[1] = (uint8_t)(mem_extendedParams->memAddr &
                                                    (uint32_t)0x00FF);
                }
                else
                {
                    status = I2C_STS_ERR_INVALID_PARAM;
                }
    
                if(status == I2C_STS_SUCCESS)
                {
                    (void)I2C_lld_Transaction_init(&object->i2ctxn);
                    object->i2ctxn.writeBuf = &object->addBuff[0];
                    object->i2ctxn.writeCount = buffer_len;
                    object->i2ctxn.readBuf = mem_extendedParams->extendedParams.buffer;
                    object->i2ctxn.readCount = mem_extendedParams->extendedParams.size;
    
                    (void)I2C_lld_Message_init(&object->i2cMsg);
                    object->i2cMsg.txn = &object->i2ctxn;
                    object->i2cMsg.txnCount = 1U;
                    object->i2cMsg.targetAddress =
                                mem_extendedParams->extendedParams.deviceAddress;
                    object->i2cMsg.expandSA =
                                mem_extendedParams->extendedParams.expandSA;
                    object->i2cMsg.timeout = timeout;
    
                    object->currentMsg = &object->i2cMsg;
                    object->currentTxnCount = 0U;
    
                    status = I2C_lld_primeTransferPoll(handle);
                }
                object->memTxnActive = false;
            }
            else
            {
                status = I2C_STS_ERR_BUS_BUSY;
            }
        }
        else
        {
            status = I2C_STS_ERR_INVALID_PARAM;
        }
    
        return status;
    }
    
    int32_t I2C_lld_mem_readIntr(   I2CLLD_Handle handle,
                                    I2C_Memory_ExtendedParams *mem_extendedParams)
    {
        int32_t                 status = I2C_STS_SUCCESS;
        I2CLLD_Object           *object = NULL;
    
        if ((handle != NULL) && (mem_extendedParams != NULL))
        {
            /* Get the pointer to the object */
            object = (I2CLLD_Object*)handle;
    
            if (object->state == I2C_STATE_IDLE)
            {
                /* No current transfer is going on. */
                /* TODO: This should happen automically. */
                object->state = I2C_STATE_BUSY;
    
                object->memTxnActive = true;
                object->memAddrSize = mem_extendedParams->memAddrSize;
    
                if(mem_extendedParams->memAddrSize == I2C_MEM_ADDR_SIZE_8_BITS)
                {
                    object->addBuff[0] = (uint8_t)(mem_extendedParams->memAddr &
                                                    (uint32_t)0x00FF);
                }
                else if(mem_extendedParams->memAddrSize==I2C_MEM_ADDR_SIZE_16_BITS)
                {
                    object->addBuff[0] = (uint8_t)((mem_extendedParams->memAddr &
                                                    (uint32_t)0xFF00) >> 8U);
                    object->addBuff[1] = (uint8_t)(mem_extendedParams->memAddr &
                                                    (uint32_t)0x00FF);
                }
                else
                {
                    status = I2C_STS_ERR_INVALID_PARAM;
                }
    
                if(status == I2C_STS_SUCCESS)
                {
                    (void)I2C_lld_Transaction_init(&object->i2ctxn);
                    object->i2ctxn.writeBuf = &object->addBuff[0];
                    object->i2ctxn.writeCount = object->memAddrSize;
                    object->i2ctxn.readBuf = mem_extendedParams->extendedParams.buffer;
                    object->i2ctxn.readCount = mem_extendedParams->extendedParams.size;
    
                    (void)I2C_lld_Message_init(&object->i2cMsg);
                    object->i2cMsg.txn = &object->i2ctxn;
                    object->i2cMsg.txnCount = 1U;
                    object->i2cMsg.targetAddress =
                                mem_extendedParams->extendedParams.deviceAddress;
                    object->i2cMsg.expandSA =
                                mem_extendedParams->extendedParams.expandSA;
    
                    object->currentMsg = &object->i2cMsg;
                    object->currentTxnCount = 0U;
    
                    status = I2C_lld_primeTransferIntr(handle);
                }
            }
            else
            {
                status = I2C_STS_ERR_BUS_BUSY;
            }
        }
        else
        {
            status = I2C_STS_ERR_INVALID_PARAM;
        }
    
        return status;
    }
    
    int32_t I2C_lld_transferPoll(I2CLLD_Handle handle, I2CLLD_Message *msg)
    {
        int32_t status;
    
        if((handle != NULL) && (msg != NULL))
        {
            status = I2C_lld_transferInit(handle, msg);
            if (status == I2C_STS_SUCCESS)
            {
                /* I2C_lld_transferInit returns I2C_STS_SUCCESS */
                status = I2C_lld_primeTransferPoll(handle);
            }
            else
            {
                /*  If status is not I2C_STS_SUCCESS, Can happen in casess
                    I2C_lld_transferInit returns I2C_STS_ERR_INVALID_PARAM or
                    I2C_STS_ERR_BUS_BUSY.
    
                    In Such case return Genaric Error.
                */
                status = I2C_STS_ERR;
            }
        }
        else
        {
            /* In case of invalid Handle or Message passing */
            status = I2C_STS_ERR_INVALID_PARAM;
        }
    
        return status;
    }
    
    int32_t I2C_lld_transferIntr(I2CLLD_Handle handle, I2CLLD_Message *msg)
    {
        int32_t status;
    
        if((handle != NULL) && (msg != NULL))
        {
            status = I2C_lld_transferInit(handle, msg);
            if (status == I2C_STS_SUCCESS)
            {
                status = I2C_lld_primeTransferIntr(handle);
            }
            else
            {
                /*  If status is not I2C_STS_SUCCESS; Can happen in case
                    controllerMode member of given msg is false
                    In Such case return Genaric Error.
                */
                status = I2C_STS_ERR;
            }
        }
        else
        {
            status = I2C_STS_ERR_INVALID_PARAM;
        }
    
        return status;
    }
    
    int32_t I2C_lld_targetTransferIntr( I2CLLD_Handle handle,
                                        I2CLLD_targetTransaction *txn)
    {
        int32_t                 retVal = I2C_STS_SUCCESS;
        I2CLLD_Object           *object = NULL;
        uint32_t                xsa;
        uint32_t                regVal = 0U;
    
        if ((handle != NULL) && (txn != NULL))
        {
            /* Get the pointer to the object */
            object = (I2CLLD_Object*)handle;
            if (txn->timeout == 0U)
            {
                /* Timeout cannot be NO_WAIT, set it to Maximum Possible Value */
                txn->timeout = I2C_WAIT_FOREVER;
            }
        }
        else
        {
            retVal = I2C_STS_ERR_INVALID_PARAM;
        }
    
        if (retVal == I2C_STS_SUCCESS)
        {
            if (object->state == I2C_STATE_IDLE)
            {
                /* No current transfer is going on. */
                /* Set driver object state to Busy */
                object->state = I2C_STATE_BUSY;
                /* Save current transaction in driver Object */
                object->currentTargetTransaction = txn;
            }
            else
            {
                /* Some transfer is going on. return with system Busy. */
                retVal = I2C_STS_ERR_BUS_BUSY;
            }
        }
    
        if (retVal == I2C_STS_SUCCESS)
        {
            /* Store the current target transaction */
            object->currentTargetTransaction = txn;
    
            object->writeBufIdx = (uint8_t *)txn->writeBuf;
            object->writeCountIdx = (uint32_t)txn->writeCount;
    
            object->readBufIdx = (uint8_t *)txn->readBuf;
            object->readCountIdx = (uint32_t)txn->readCount;
    
            if (object->currentTargetTransaction->expandSA == (bool)true)
            {
                /* Enable the 10-bit address mode for Own Address 0 */
                xsa = I2C_CFG_10BIT_OWN_ADDR_0;
            }
            else
            {
                /* Enable the 7-bit address mode for Own Address 0 */
                xsa = I2C_CFG_7BIT_OWN_ADDR_0;
            }
    
            /* In target mode, set the I2C own address */
            I2COwnAddressSet(   object->baseAddr,
                                object->ownTargetAddr[0],
                                I2C_OWN_ADDR_0);
    
            /* Configure data buffer length to 0 as the actual number of bytes to
               transmit/receive is dependant on external controller. */
            I2CSetDataCount(object->baseAddr, 0U);
            /* Enable interrupts for target mode */
            I2CTargetIntEnableEx(object->baseAddr,
                                I2C_INT_TRANSMIT_READY | I2C_INT_RECV_READY |
                                I2C_INT_ADRR_READY_ACESS | I2C_INT_ADRR_TARGET);
            /* Start the I2C transfer in target mode */
            regVal = I2C_CFG_MST_ENABLE | xsa;
    
            if ((object->bitRate == I2C_1P0MHZ) ||
                (object->bitRate == I2C_3P4MHZ))
            {
                regVal |= I2C_CFG_HS_MOD;
            }
            I2CControllerControl(object->baseAddr, regVal);
        }
    
        return retVal;
    }
    
    int32_t I2C_lld_probe(I2CLLD_Handle handle, uint32_t targetAddr)
    {
        int32_t             retVal = I2C_STS_ERR;
        uint32_t            regVal;
        I2CLLD_Object       *object = NULL;
    
        /* Input parameter validation */
        if (handle != NULL)
        {
            object = (I2CLLD_Object *)handle;
    
            if (object->state == I2C_STATE_IDLE)
            {
                /* No current transfer should be going on */
                /* Change the current state to BUSY */
                object->state = I2C_STATE_BUSY;
    
                /* Get All the enabled Interrupts */
                regVal = I2CGetEnabledIntStatus(object->baseAddr, I2C_INT_ALL);
                /* Disable All the interrupts */
                I2CControllerIntDisableEx(object->baseAddr, I2C_INT_ALL);
                /* Wait until bus not busy */
                if (I2C_waitForBb(handle, I2C_DELAY_MED) != I2C_STS_SUCCESS)
                {
                    retVal = I2C_STS_ERR;
                }
                else
                {
                    /* Set target address */
                    I2CControllerTargetAddrSet(object->baseAddr, (uint32_t)targetAddr);
                    /* Try to write one byte */
                    I2CControllerDataPut(object->baseAddr, (uint8_t) 0U);
                    /* Set Data Count to one */
                    I2CSetDataCount(object->baseAddr, (uint32_t) 1U);
                    /* Stop bit needed here; Enable Stop condition */
                    I2CConfig(object->baseAddr,
                                (I2C_CFG_MST_ENABLE | I2C_CFG_MST_TX |
                                I2C_CFG_START | I2C_CFG_STOP));
    
                    /* Enough delay for the NACK bit set */
                    object->Clock_uSleep(I2C_DELAY_BIG);
    
                    /* Check if NACK bit is set */
                    if (0U == I2CControllerIntRawStatusEx(object->baseAddr, I2C_INT_NO_ACK))
                    {
                        /* NACK bit not set */
                        retVal = I2C_STS_SUCCESS;
                        /* Clear all interrupts */
                        I2CControllerIntClearEx(object->baseAddr, I2C_INT_ALL);
                        /* Wait for stop to complete and bus to become free */
                        (void)I2C_waitForBb(handle, I2C_DELAY_MED);
                    }
                    else
                    {
                        /* NACK bit set */
                        /* Clear all interrupts */
                        I2CControllerIntClearEx(object->baseAddr, I2C_INT_ALL);
                        /* Generate Stop */
                        I2CControllerStop(object->baseAddr);
                        /* Wait for stop to complete and bus to become free */
                        (void)I2C_waitForBb(handle, I2C_DELAY_MED);
                        /* NACK bit was set; Device not Available */
                        retVal = I2C_STS_ERR;
                    }
    
                    /* Clear TX FIFO */
                    I2CFIFOClear(object->baseAddr, I2C_TX_MODE);
                    /* Clear RX FIFO */
                    I2CFIFOClear(object->baseAddr, I2C_RX_MODE);
                    /* Set Data Count to Zero */
                    I2CSetDataCount(object->baseAddr, 0U);
                }
    
                /* Re-Enable the Interrupts that were disabled */
                I2CControllerIntEnableEx(object->baseAddr, regVal);
                /* Change the driver state back to IDLE */
                object->state = I2C_STATE_IDLE;
            }
            else
            {
                /* Some transfer is going on. return with system Busy. */
                retVal = I2C_STS_ERR_BUS_BUSY;
            }
        }
    
        return (retVal);
    }
    
    int32_t I2C_lld_setBusFrequency(I2CLLD_Handle handle, uint32_t busFrequency)
    {
        int32_t             retVal = I2C_STS_SUCCESS;
        I2CLLD_Object       *object = NULL;
        uint32_t            outputClk = 0;
        uint32_t            internalClk = 0;
    
        /* Input parameter validation */
        if(NULL != handle)
        {
            /* Get the pointer to the object */
            object = (I2CLLD_Object*)handle;
    
            if (object->state == I2C_STATE_IDLE)
            {
                /* Change driver state to Busy */
                object->state = I2C_STATE_BUSY;
                /* Put i2c in reset/disabled state */
                I2CControllerDisable(object->baseAddr);
                /* Extract bit rate from the input parameter */
                switch(busFrequency)
                {
                    case I2C_100KHZ:
                    {
                        outputClk = 100000U;
                        internalClk = I2C_MODULE_INTERNAL_CLK_4MHZ;
                        break;
                    }
    
                    case I2C_400KHZ:
                    {
                        outputClk = 400000U;
                        internalClk = I2C_MODULE_INTERNAL_CLK_12MHZ;
                        break;
                    }
    
                    case I2C_1P0MHZ:
                    {
                        outputClk = 1000000U;
                        internalClk = I2C_MODULE_INTERNAL_CLK_12MHZ;
                        break;
                    }
    
                    case I2C_3P4MHZ:
                    {
                        outputClk = 3400000U;
                        internalClk = I2C_MODULE_INTERNAL_CLK_12MHZ;
                        break;
                    }
    
                    default:
                    {
                        /* Default case force it to 100 KHZ bit rate */
                        outputClk = 100000U;
                        internalClk = I2C_MODULE_INTERNAL_CLK_4MHZ;
                        break;
                    }
                }
    
                /* Set the I2C configuration */
                I2CControllerInitExpClk(object->baseAddr, object->funcClk,
                                        internalClk, outputClk);
                /* Clear any pending interrupts */
                I2CControllerIntClearEx(object->baseAddr, I2C_INT_ALL);
                /* Mask off all interrupts */
                I2CControllerIntDisableEx(object->baseAddr, I2C_INT_ALL);
                /* Enable the I2C Controller for operation */
                I2CControllerEnable(object->baseAddr);
                /* Enable free run mode */
                I2CControllerEnableFreeRun(object->baseAddr);
                /* Change Driver state back to IDLE */
                object->state = I2C_STATE_IDLE;
            }
            else
            {
                /* Some transfer is going on. return with system Busy. */
                retVal = I2C_STS_ERR_BUS_BUSY;
            }
        }
        else
        {
            retVal = I2C_STS_ERR_INVALID_PARAM;
        }
    
        return retVal;
    }
    
    int32_t I2C_lld_recoverBus(I2CLLD_Handle handle, uint32_t i2cDelay)
    {
    
        int32_t             retVal = I2C_STS_SUCCESS;
        I2CLLD_Object       *object = NULL;
        uint32_t            sysTest, i;
    
        if(handle != NULL)
        {
            /* Get the pointer to the object */
            object = (I2CLLD_Object*)handle;
        }
        else
        {
            retVal = I2C_STS_ERR_INVALID_PARAM;
        }
    
    
        if (retVal == I2C_STS_SUCCESS)
        {
            /* Check if SDA or SCL is stuck low based on the SYSTEST.
            * If SCL is stuck low we reset the IP.
            * If SDA is stuck low drive 9 clock pulses on SCL and check if the
            * target has released the SDA. If not we reset the I2C controller.
            */
    
            sysTest = I2CControllerGetSysTest(object->baseAddr);
            if ((sysTest & I2C_SYSTEST_SCL_I_FUNC_MASK) == 0U)
            {
                /* SCL is stuck low reset the I2C IP */
                retVal = I2C_lld_resetCtrl(object);
            }
            else if ((sysTest & I2C_SYSTEST_SDA_I_FUNC_MASK) == 0U)
            {
                /* SDA is stuck low; generate 9 clk pulses on SCL */
                /* Switch to system test mode */
                sysTest = (((uint32_t)I2C_SYSTEST_ST_EN_MASK) |
                    ((uint32_t)CSL_I2C_SYSTEST_TMODE_LOOPBACK << (uint32_t)CSL_I2C_SYSTEST_TMODE_SHIFT));
    
                I2CControllerSetSysTest(object->baseAddr, sysTest);
    
                for (i = 0; i < 9U; i++)
                {
                    sysTest = (I2C_SYSTEST_SCL_O_SCLOH << I2C_SYSTEST_SCL_O_SHIFT);
                    I2CControllerSetSysTest(object->baseAddr, sysTest);
                    object->Clock_uSleep(i2cDelay);
    
                    sysTest = (I2C_SYSTEST_SCL_O_SCLOL << I2C_SYSTEST_SCL_O_SHIFT);
                    I2CControllerSetSysTest(object->baseAddr, sysTest);
                    object->Clock_uSleep(i2cDelay);
                }
    
                /* Switch back to functional mode */
                sysTest = (I2C_SYSTEST_ST_EN_DISABLE << I2C_SYSTEST_ST_EN_SHIFT);
                sysTest |= (I2C_SYSTEST_TMODE_FUNCTIONAL << CSL_I2C_SYSTEST_TMODE_SHIFT);
                I2CControllerSetSysTest(object->baseAddr, sysTest);
    
                /* Now check if the SDA is releases. If its still stuck low,
                 * There is nothing that can be done. We still try to reset our IP.
                 */
                sysTest = I2CControllerGetSysTest(object->baseAddr);
    
                if ((sysTest & I2C_SYSTEST_SDA_I_FUNC_MASK) == 0U)
                {
                    retVal = I2C_lld_resetCtrl(handle);
                }
            }
            else
            {
                /* Nothing to be done. SCA and SDA both are not stuck to low */
            }
        }
    
        return retVal;
    }
    
    
    /* ========================================================================== */
    /*                     API ISR Function Definitions                           */
    /* ========================================================================== */
    
    void I2C_lld_controllerIsr(void *args)
    {
        I2CLLD_Object       *object = NULL;
        int32_t             xferStatus = I2C_STS_SUCCESS;
        uint32_t            isrLoopCount = 0U;
        uint32_t            w;
        uint32_t            stat;
        uint32_t            rawStat;
        uint32_t            intErr = 0U;
        uint32_t            fatalError = 0U;
        uint32_t            xsa;
        uint32_t            regVal;
        uint32_t            loopFlag = TRUE;
    
        /* Get the pointer to the object */
        object = (I2CLLD_Object*)args;
    
        /*
         * Ack the stat in one go, but [R/X]RDY should be
         * acked after the data operation is complete.
         */
    
        /*
         * The Controller ISR handling is based on AM5 TRM HS I2C Programming Guide
         * Section 24.1.5. The driver only enables [R/X]RDY and ARDY interrupts, and
         * ISR checks the raw interrupt status register to handle any fatal errors
         * (No Ack, arbitration lost, etc.). It also logs non fatal errors (TX underflow
         * RX overflow, etc.) internally. The ISR also handles restart condition (write
         * followed by a restart restart)
         *
         *
         * Keep looping till there are no pending interrupts.
         * This allows I2C_INT_ADRR_READY_ACESS to be processed in same ISR
         * as [R/X]RDY and reduce interrupt count.
         *
         */
    
        while (loopFlag == TRUE)
        {
            /* Store current interrupt status */
            stat = I2CControllerIntStatus(object->baseAddr);
            if ((0U == stat) || (isrLoopCount > I2C_MAX_CONSECUTIVE_ISRS))
            {
                /* No interrupt remaining or loop count went over 1 */
                loopFlag = FALSE;
            }
            else
            {
                /* Loop Count under max intr and intrs available */
                /* Increment loop count */
                isrLoopCount++;
                /* Check Raw Interrupt Status */
                rawStat = I2CControllerIntRawStatus(object->baseAddr);
    
                if ((rawStat & I2C_INT_NO_ACK) != 0U)
                {
                    intErr |= I2C_INT_NO_ACK;
                    xferStatus = I2C_STS_ERR_NO_ACK;
                    I2CControllerIntClearEx(object->baseAddr, I2C_INT_NO_ACK);
                    fatalError = 1U;
                }
    
                if ((rawStat & I2C_INT_ARBITRATION_LOST) != 0U)
                {
                    intErr |= I2C_INT_ARBITRATION_LOST;
                    xferStatus = I2C_STS_ERR_ARBITRATION_LOST;
                    I2CControllerIntClearEx(object->baseAddr,I2C_INT_ARBITRATION_LOST);
                    fatalError = 1U;
                }
    
                if ((rawStat & I2C_INT_ACCESS_ERROR) != 0U)
                {
                    intErr |= I2C_INT_ACCESS_ERROR;
                    xferStatus = I2C_STS_ERR_ACCESS_ERROR;
                    I2CControllerIntClearEx(object->baseAddr,I2C_INT_ACCESS_ERROR);
                    fatalError = 1U;
                }
    
                if(fatalError != 0U)
                {
                    /* Some Error Happened */
                    /* Issue the stop condition */
                    I2CControllerStop(object->baseAddr);
                    /* Disable all interrupts */
                    I2CControllerIntDisableEx(object->baseAddr, I2C_INT_ALL);
                    /* Clear all interrupts */
                    I2CControllerIntClearEx(object->baseAddr, I2C_INT_ALL);
    
                    I2CControllerIntEnableEx(object->baseAddr, I2C_INT_STOP_CONDITION);
                    /* Clear TX FIFO */
                    I2CFIFOClear(object->baseAddr, I2C_TX_MODE);
                    /* Clear RX FIFO */
                    I2CFIFOClear(object->baseAddr, I2C_RX_MODE);
                    /* Set data count to zero */
                    I2CSetDataCount(object->baseAddr, 0);
                    /* Store interrupt status in driver object */
                    object->intStatusErr |= intErr;
                    /* Finish current transfer */
                    I2C_lld_completeCurrTransfer(object, xferStatus);
                    /* Breat out of the interrpt Loop */
                    break;
                }
    
                if(rawStat & I2C_INT_STOP_CONDITION)
                {
                    if(object->intStatusErr != 0)
                    {
                        /* Disable all interrupts */
                        I2CControllerIntDisableEx(object->baseAddr, I2C_INT_ALL);
                        /* Clear all interrupts */
                        I2CControllerIntClearEx(object->baseAddr, I2C_INT_ALL);
                        /* Put i2c in reset/disabled state */
                        I2CControllerDisable(object->baseAddr);
                        /* Enable i2c module */
                        I2CControllerEnable(object->baseAddr);
                        break;
                    }
                }
    
                /*  Store all interrupts except receive ready and transmit ready
                 *  in seperate variable & clear all those interrupts
                 */
                w = stat & ~(I2C_INT_RECV_READY | I2C_INT_TRANSMIT_READY);
                I2CControllerIntClearEx(object->baseAddr, w);
    
                if (((stat & I2C_INT_ADRR_READY_ACESS) == I2C_INT_ADRR_READY_ACESS) ||
                    ((stat & I2C_INT_BUS_FREE) == I2C_INT_BUS_FREE))
                {
                    /* Bus free or register access ready interrupt fired */
                    /* Clear Receive ready and transmit ready Interrupt */
                    w = stat & (I2C_INT_RECV_READY | I2C_INT_TRANSMIT_READY);
                    I2CControllerIntClearEx(object->baseAddr, w);
    
                    if (((object->writeCountIdx) == 0U) && ((object->readCountIdx) != 0U))
                    {
                        /* Write Completed; Read count is not zero */
                        /* Set read count */
                        I2CSetDataCount(object->baseAddr, object->readCountIdx);
                        /*
                         * Configure peripheral for I2C Receive mode,
                         * do not send stop when sending restart
                         */
                        if (object->currentMsg->expandSA == (bool)true)
                        {
                            /* Enable the 10-bit address mode */
                            xsa = I2C_CFG_10BIT_TARGET_ADDR;
                        }
                        else
                        {
                            /* Enable the 7-bit address mode */
                            xsa = I2C_CFG_7BIT_TARGET_ADDR;
                        }
    
                        regVal = I2C_CFG_MST_RX | xsa;
                        if ((object->bitRate == I2C_1P0MHZ) || (object->bitRate == I2C_3P4MHZ))
                        {
                            regVal |= I2C_CFG_HS_MOD;
                        }
                        I2CControllerControl(object->baseAddr, regVal);
                        /* Enable RX interrupt to handle data received */
                        I2CControllerIntEnableEx(object->baseAddr, I2C_INT_RECV_READY);
                        /* Start I2C peripheral in RX mode */
                        I2CControllerStart(object->baseAddr);
                    }
                    else
                    {
                        /* Write completed; Read count is zero (Nothing to read) */
                        /* No further looping requried */
                        if ((rawStat & I2C_INT_BUS_BUSY) != 0U)
                        {
                            /* Bus Busy state */
                            /* Generate Stop */
                            I2CControllerStop(object->baseAddr);
                            /* Enable bus free interrupt to wait for bus release */
                            I2CControllerIntEnableEx(object->baseAddr, I2C_INT_BUS_FREE);
                        }
                        else
                        {
                            /* Disable all interrupts */
                            I2CControllerIntDisableEx(object->baseAddr, I2C_INT_ALL);
                            /* Complete current Transfer */
                            I2C_lld_completeCurrTransfer(object,xferStatus);
                        }
                        /* Set loopFlag to false; don't execute anything from below
                         * Transaction Finished.
                         */
                        loopFlag = FALSE;
                    }
                }
    
                if ((loopFlag == TRUE) && (0U == intErr))
                {
                    /* Further interrupts available but no error happend */
                    if ((stat & I2C_INT_RECV_READY) != 0U)
                    {
                        /* Receive ready interrupt happened */
                        /* Save the received data */
                        if (object->readBufIdx != NULL)
                        {
                            *(object->readBufIdx) = I2CControllerDataGet(object->baseAddr);
                            object->readBufIdx++;
                            object->readCountIdx--;
                        }
                        /* Clear receive ready interrpt */
                        I2CControllerIntClearEx((object->baseAddr),
                                                (stat & I2C_INT_RECV_READY));
                    }
    
                    if ((stat & I2C_INT_TRANSMIT_READY) != 0U)
                    {
                        /* Transmit ready interrupt happened */
                        if (object->writeCountIdx != 0U)
                        {
                            /* Write count index is not Zero */
                            /*
                             * Write data until FIFO is full or all data written.
                             * The math below is: (DCOUNT - TXBUFSTAT) % 64 < TXBUFSIZE.
                             */
                            while ( ((object->writeCountIdx) != 0U) &&
                                    /*    Pending number of bytes to be transmitted - number of bytes yet to be transmitted from fifo = actual pending bytes */
                                    (   ((I2CDataCountGet(object->baseAddr) - I2CBufferStatus(object->baseAddr, I2C_TX_BUFFER_STATUS)) % 64U) <
                                        (((uint32_t)8U) << I2CBufferStatus(object->baseAddr,I2C_FIFO_DEPTH))))
                                        /* FIFO depth in Bytes */
                            {
    
                                /* Write data into transmit FIFO */
                                I2CControllerDataPut(   object->baseAddr,
                                                        *(object->writeBufIdx));
                                (object->writeBufIdx)++;
                                object->writeCountIdx--;
    
                                /* Update Write buffer index in case of a memory Transaction */
                                if(object->memTxnActive)
                                {
                                    if( (object->i2ctxn.writeCount - object->memAddrSize) ==
                                        (object->writeCountIdx))
                                    {
                                        object->writeBufIdx = object->dataArray;
                                    }
                                }
                            }
                        }
                        else
                        {
                            /* Write count index is Zero */
                            /* Disable Transmit ready interrupt */
                            I2CControllerIntDisableEx(object->baseAddr, I2C_INT_TRANSMIT_READY);
                        }
                        /* Clear The Transmit Ready interrupt */
                        I2CControllerIntClearEx(object->baseAddr,
                                            (stat & I2C_INT_TRANSMIT_READY));
                    }
                }
    
                if ((loopFlag == TRUE) && (0U == intErr))
                {
                    /* Loop flag true with no error */
                    /* Check weather Receive overrun happened */
                    if ((stat & I2C_INT_RECV_OVER_RUN) != 0U)
                    {
                        intErr |= I2C_INT_RECV_OVER_RUN;
                    }
                    /* Check weather Transmit underflow happened */
                    if ((stat & I2C_INT_TRANSMIT_UNDER_FLOW) != 0U)
                    {
                         intErr |= I2C_INT_TRANSMIT_UNDER_FLOW;
                    }
                }
            }
        }
    
        /* Save the interrupt status errors */
        object->intStatusErr |= intErr;
    }
    
    void I2C_lld_targetIsr(void *args)
    {
        I2CLLD_Object       *object = NULL;
        uint32_t            rawStat;
    
        /* Get the pointer to the object */
        object = (I2CLLD_Object*)args;
    
        /*
         *  ISR Handling of different events is as below in same order:
         *  1.  RRDY: Handle receive ready interrupt before AAS(Address recognized as target) or ARDY(Register access ready IRQ enabled status) interrupt,
         *      as If ISR delayed and restart or stop condition received then
         *      the data should be read first.
         *  2.  ARDY: In case of stop condition bus busy will be reset. If it is a
         *      restart condition bus busy will still be set.
         *  3.  AAS: In case of addressed as target after transfer is initiated, it
         *      is a restart condition. Give the restart callback.
         *  4.  XRDY: Read application tx buffer and send data.
         *
         *  In case of restart hold the bus low till application gives next buffer.
         *  If the Buffers are overflowing or underflowing return error code
         *  accordingly. Application should call the abort transfer explicitly.
         */
        rawStat = I2CTargetIntRawStatus(object->baseAddr);
    
        if ((rawStat & I2C_INT_RECV_READY) != 0U)
        {
            /* Receive Ready interrupt received */
            if (object->readCountIdx != 0U)
            {
                /* Read count is not zero i.e. Bytes yet to be read */
                /* Read from RX register only when current transaction is ongoing */
                *(object->readBufIdx) = I2CControllerDataGet(object->baseAddr);
                object->readBufIdx++;
                object->readCountIdx--;
                /* Clear receive ready interrupt */
                I2CControllerIntClearEx(object->baseAddr, I2C_INT_RECV_READY);
            }
            else
            {
                /* Clear the RX data FIFO */
                (void)I2CTargetDataGet(object->baseAddr);
                /* Clear all Interrupts */
                I2CTargetIntClearEx(object->baseAddr, I2C_INT_ALL);
                /* Disable STOP condition Interrupt */
                I2CTargetIntDisableEx(object->baseAddr, I2C_INT_ALL);
                /* Finish the current transfer */
                I2C_lld_completeCurrTargetTransfer(object, I2C_STS_ERR);
            }
        }
    
        if ((rawStat & I2C_INT_ADRR_READY_ACESS) != 0U)
        {
            /* ARDY(Register access ready interrupt) */
            if ((rawStat & I2C_INT_BUS_BUSY) != 0U)
            {
                /* Bus Still busy means stop condition did not happen */
                /* Clear Interrupt, Callback will be handled in ADDR_TARGET */
                I2CTargetIntClearEx(object->baseAddr, I2C_INT_ADRR_READY_ACESS);
            }
            else
            {
                /* Bus busy was reset i.e. stop condition happened; End of transfer */
                /* Clear all Interrupts */
                I2CTargetIntClearEx(object->baseAddr, I2C_INT_ALL);
                /* Finish the current transfer */
                I2C_lld_completeCurrTargetTransfer(object, I2C_STS_SUCCESS);
            }
        }
    
        if ((rawStat & I2C_INT_ADRR_TARGET) != 0U)
        {
            /* AAS(Address recognized as target) interrupt happened */
            if (object->state == I2C_STATE_BUSY)
            {
                /* This is the first transfer initiation from controller */
                /* Update the state to transfer started */
                object->state = I2C_TARGET_XFER_STATE;
                /* Clear the Interrupt */
                I2CTargetIntClearEx(object->baseAddr, I2C_INT_ADRR_TARGET);
            }
            else if (object->state == I2C_TARGET_XFER_STATE)
            {
                if ((object->writeCountIdx == 0U) && ((rawStat & I2C_INT_TRANSMIT_UNDER_FLOW) != 0U))
                {
                    /*
                     * This is a restart condition, target write count should be provided by
                     * application in the callback function
                     */
    
                    /* Callback to application to restart read/write */
                    object->targetTransferCompleteCallback( (void *)object,
                                                    object->currentTargetTransaction,
                                                    I2C_STS_RESTART);
    
                    // I2C_lld_targetTransferIntr(object, object->currentTargetTransaction);
                    object->writeBufIdx = (uint8_t*)(object->currentTargetTransaction->writeBuf);
                    object->writeCountIdx = (uint32_t)(object->currentTargetTransaction->writeCount);
    
                    object->readBufIdx = (uint8_t*)(object->currentTargetTransaction->readBuf);
                    object->readCountIdx = (uint32_t)(object->currentTargetTransaction->readCount);
                }
                else
                {
                    /* No Code */
                }
    
                object->state = I2C_TARGET_RESTART_STATE;
                I2CTargetIntClearEx(object->baseAddr, I2C_INT_ADRR_TARGET);
            }
            else
            {
                /* Control should not come here. Sphurious interrupt clear it. */
                I2CTargetIntClearEx(object->baseAddr, I2C_INT_ADRR_TARGET);
            }
        }
    
        if ((rawStat & I2C_INT_TRANSMIT_READY) != 0U)
        {
            /* XRDY(Transmit Ready Interrupt happened) */
            if (object->state == I2C_TARGET_XFER_STATE)
            {
                /* I2C in Target Transfer state */
                if (object->writeCountIdx != 0U)
                {
                    /* Write count not zero */
                    I2CControllerDataPut(object->baseAddr, *(object->writeBufIdx));
                    object->writeCountIdx--;
                    object->writeBufIdx++;
                    I2CTargetIntClearEx(object->baseAddr, I2C_INT_TRANSMIT_READY);
                }
                else
                {
                    /* Write count zero; write Completed */
                    /* Clear all interrupts */
                    I2CTargetIntClearEx(object->baseAddr, I2C_INT_ALL);
                    /* Disable STOP condition interrupt */
                    I2CTargetIntDisableEx(object->baseAddr, I2C_INT_ALL);
                    /* Update Read buffer and count */
                    object->readBufIdx = (uint8_t*)(object->currentTargetTransaction->readBuf);
                    object->readCountIdx = (uint32_t)(object->currentTargetTransaction->readCount);
                    /* Post Semaphore to unblock transfer fxn */
                    object->targetTransferCompleteCallback( (void*)object,
                                                    object->currentTargetTransaction,
                                                    I2C_STS_ERR);
                    /* No other transactions need to occur */
                    object->currentTargetTransaction = NULL;
                }
            }
            else
            {
                /* I2C is not in target Transfer State; may be restart state */
                if (object->writeCountIdx != 0U)
                {
                    I2CControllerDataPut(object->baseAddr, *(object->writeBufIdx));
                    object->writeCountIdx--;
                    object->writeBufIdx++;
                    I2CTargetIntClearEx(object->baseAddr, I2C_INT_TRANSMIT_READY);
                }
                else
                {
                    /* Clear all interrupts */
                    I2CTargetIntClearEx(object->baseAddr, I2C_INT_ALL);
                    /* Disable STOP condition interrupt */
                    I2CTargetIntDisableEx(object->baseAddr, I2C_INT_ALL);
                    /* Update Read buffer and count */
                    object->readBufIdx = (uint8_t*)(object->currentTargetTransaction->readBuf);
                    object->readCountIdx = (uint32_t)object->currentTargetTransaction->readCount;
                    /* Post Semaphore to unblock transfer fxn */
                    object->targetTransferCompleteCallback( (void*)object,
                                                    object->currentTargetTransaction,
                                                    I2C_STS_ERR);
                    /* No other transactions need to occur */
                    object->currentTargetTransaction = NULL;
    
                }
            }
        }
        return;
    }
    
    /* ========================================================================== */
    /*                      Internal Function Definitions                         */
    /* ========================================================================== */
    
    static void I2CControllerInitExpClk(uint32_t baseAddr,
                                        uint32_t sysClk,
                                        uint32_t internalClk,
                                        uint32_t outputClk)
    {
        CSL_I2cRegsOvly i2cRegs = (CSL_I2cRegsOvly)baseAddr;
        uint32_t prescalar;
        uint32_t divisor;
        uint32_t div_h, div_l;
        uint32_t actIntClk = 0U;
    
        /* Iterate through the valid pre-scalar values until one is found that is
         * the closest match to the desired internal clock speed
         */
        for (prescalar = 0U; prescalar < I2C_MAX_CLK_PRESCALAR; prescalar++)
        {
            /* Calculate the actual speed that would be used for the current
             * pre-scalar value, and if it is within 1 MHz of the desired value then
             * we have a match
             */
            actIntClk = sysClk / (prescalar + 1U);
    
            if (actIntClk <= (internalClk + I2C_INTERNAL_CLK_STEP))
            {
                break;
            }
        }
    
        if (outputClk > 400000U)
        {
            /* Prescalar bypassed in high speed mode */
            prescalar = 0;
            actIntClk = sysClk;
        }
        i2cRegs->PSC = prescalar;
    
        /* Calculate the divisor to be used based on actual internal clock speed
         * based on pre-scalar value used
         */
        divisor = actIntClk / outputClk;
        if ((outputClk * divisor) != actIntClk)
        {
            /* Round up the divisor so that output clock never exceeds the
             * requested value if it is not exact
             */
            divisor += 1U;
        }
    
        /* Split into SCK HIGH and LOW time to take odd numbered divisors
         * into account and avoid reducing the output clock frequency
         */
        div_h = divisor / 2U;
        div_l = divisor - div_h;
    
        if (outputClk > 400000U)
        {
            i2cRegs->SCLL = (uint32_t)((div_l - 7U) << 8U);
            i2cRegs->SCLH = (uint32_t)((div_h - 5U) << 8U);
        }
        else
        {
            i2cRegs->SCLL = (uint32_t)(div_l - 7U);
            i2cRegs->SCLH = (uint32_t)(div_h - 5U);
        }
    }
    
    
    
    static void I2CControllerEnable(uint32_t baseAddr)
    {
        CSL_I2cRegsOvly i2cRegs = (CSL_I2cRegsOvly)baseAddr;
        i2cRegs->CON |= I2C_CON_I2C_EN_MASK;
    }
    
    static void I2CControllerEnableFreeRun(uint32_t baseAddr)
    {
        CSL_I2cRegsOvly i2cRegs = (CSL_I2cRegsOvly)baseAddr;
        i2cRegs->SYSTEST |= I2C_SYSTEST_FREE_MASK;
    }
    
    static void I2CControllerSetSysTest(uint32_t baseAddr, uint32_t sysTest)
    {
        CSL_I2cRegsOvly i2cRegs = (CSL_I2cRegsOvly)baseAddr;
        i2cRegs->SYSTEST = sysTest;
    }
    
    static uint32_t I2CControllerGetSysTest(uint32_t baseAddr)
    {
        CSL_I2cRegsOvly i2cRegs = (CSL_I2cRegsOvly)baseAddr;
        uint32_t sysTest = 0U;
    
        sysTest = i2cRegs->SYSTEST;
    
        return (sysTest);
    }
    
    static void I2CControllerDisable(uint32_t baseAddr)
    {
        CSL_I2cRegsOvly i2cRegs = (CSL_I2cRegsOvly)baseAddr;
        i2cRegs->CON &= ~I2C_CON_I2C_EN_MASK;
    }
    
    static int32_t I2CControllerBusBusy(uint32_t baseAddr)
    {
        CSL_I2cRegsOvly i2cRegs = (CSL_I2cRegsOvly)baseAddr;
        int32_t status = (int32_t)0;
    
        if((i2cRegs->IRQSTATUS_RAW & CSL_I2C_IRQSTATUS_RAW_BB_MASK) != 0U)
        {
            status = (int32_t)1;
        }
    
        return status;
    }
    
    static void I2CControllerControl(uint32_t baseAddr, uint32_t cmd)
    {
        CSL_I2cRegsOvly i2cRegs = (CSL_I2cRegsOvly)baseAddr;
        i2cRegs->CON = cmd | I2C_CON_I2C_EN_MASK;
    }
    
    static void I2CControllerStart(uint32_t baseAddr)
    {
        CSL_I2cRegsOvly i2cRegs = (CSL_I2cRegsOvly)baseAddr;
        i2cRegs->CON |= I2C_CON_STT_MASK;
    }
    
    static void I2CControllerStop(uint32_t baseAddr)
    {
        CSL_I2cRegsOvly i2cRegs = (CSL_I2cRegsOvly)baseAddr;
        i2cRegs->CON |= I2C_CON_STP_MASK;
    }
    
    static void I2CControllerIntEnableEx(uint32_t baseAddr, uint32_t intFlag)
    {
        CSL_I2cRegsOvly i2cRegs = (CSL_I2cRegsOvly)baseAddr;
        uint32_t i2cRegValue = i2cRegs->IRQENABLE_SET;
        i2cRegValue |= intFlag;
        i2cRegs->IRQENABLE_SET = i2cRegValue;
    }
    
    static void I2CTargetIntEnableEx(uint32_t baseAddr, uint32_t intFlag)
    {
        CSL_I2cRegsOvly i2cRegs = (CSL_I2cRegsOvly)baseAddr;
        uint32_t i2cRegValue = i2cRegs->IRQENABLE_SET;
        i2cRegValue |= intFlag;
        i2cRegs->IRQENABLE_SET = i2cRegValue;
    }
    
    static void I2CControllerIntDisableEx(uint32_t baseAddr, uint32_t intFlag)
    {
        CSL_I2cRegsOvly i2cRegs = (CSL_I2cRegsOvly)baseAddr;
        i2cRegs->IRQENABLE_CLR = intFlag;
    }
    
    static void I2CTargetIntDisableEx(uint32_t baseAddr, uint32_t intFlag)
    {
        CSL_I2cRegsOvly i2cRegs = (CSL_I2cRegsOvly)baseAddr;
        i2cRegs->IRQENABLE_CLR = intFlag;
    }
    
    static uint32_t I2CControllerIntStatus(uint32_t baseAddr)
    {
        CSL_I2cRegsOvly i2cRegs = (CSL_I2cRegsOvly)baseAddr;
        return((uint32_t)(i2cRegs->IRQSTATUS));
    }
    
    static uint32_t I2CControllerIntRawStatus(uint32_t baseAddr)
    {
        CSL_I2cRegsOvly i2cRegs = (CSL_I2cRegsOvly)baseAddr;
        return((uint32_t)(i2cRegs->IRQSTATUS_RAW));
    }
    
    static uint32_t I2CTargetIntRawStatus(uint32_t baseAddr)
    {
        CSL_I2cRegsOvly i2cRegs = (CSL_I2cRegsOvly)baseAddr;
        return((uint32_t)(i2cRegs->IRQSTATUS_RAW));
    }
    
    static uint32_t I2CControllerIntRawStatusEx(uint32_t baseAddr, uint32_t intFlag)
    {
        CSL_I2cRegsOvly i2cRegs = (CSL_I2cRegsOvly)baseAddr;
        return(((uint32_t)(i2cRegs->IRQSTATUS_RAW)) & intFlag);
    }
    
    static void I2CControllerIntClearEx(uint32_t baseAddr, uint32_t intFlag)
    {
        CSL_I2cRegsOvly i2cRegs = (CSL_I2cRegsOvly)baseAddr;
        i2cRegs->IRQSTATUS = intFlag;
    }
    
    static void I2CTargetIntClearEx(uint32_t baseAddr, uint32_t intFlag)
    {
        CSL_I2cRegsOvly i2cRegs = (CSL_I2cRegsOvly)baseAddr;
        i2cRegs->IRQSTATUS = intFlag;
    }
    
    static uint32_t I2CGetEnabledIntStatus(uint32_t baseAddr, uint32_t intFlag)
    {
        CSL_I2cRegsOvly i2cRegs = (CSL_I2cRegsOvly)baseAddr;
        return (uint32_t)((i2cRegs->IRQENABLE_SET) & intFlag);
    }
    
    static void I2CControllerTargetAddrSet(uint32_t baseAddr, uint32_t targetAdd)
    {
    
        CSL_I2cRegsOvly i2cRegs = (CSL_I2cRegsOvly)baseAddr;
        i2cRegs->SA = targetAdd;
    }
    
    static void I2CSetDataCount(uint32_t baseAddr, uint32_t count)
    {
        CSL_I2cRegsOvly i2cRegs = (CSL_I2cRegsOvly)baseAddr;
        i2cRegs->CNT = count;
    }
    
    static uint32_t I2CDataCountGet(uint32_t baseAddr)
    {
        CSL_I2cRegsOvly i2cRegs = (CSL_I2cRegsOvly)baseAddr;
        return (i2cRegs->CNT);
    }
    
    static void I2CFIFOClear(uint32_t baseAddr, uint32_t flag)
    {
        CSL_I2cRegsOvly i2cRegs = (CSL_I2cRegsOvly)baseAddr;
        if (I2C_TX_MODE == flag)
        {
            i2cRegs->BUF |= I2C_BUF_TXFIFO_CLR_MASK;
        }
        else
        {
            i2cRegs->BUF |= I2C_BUF_RXFIFO_CLR_MASK;
        }
    }
    
    static uint32_t I2CBufferStatus(uint32_t baseAddr, uint32_t flag)
    {
        CSL_I2cRegsOvly i2cRegs = (CSL_I2cRegsOvly)baseAddr;
        uint32_t status;
    
        switch (flag)
        {
            case I2C_TX_BUFFER_STATUS:
                status = ((i2cRegs->BUFSTAT) & (CSL_I2C_BUFSTAT_TXSTAT_MASK));
                break;
    
            case I2C_RX_BUFFER_STATUS:
                status = ((i2cRegs->BUFSTAT) & (CSL_I2C_BUFSTAT_RXSTAT_MASK));
                break;
    
            case I2C_FIFO_DEPTH:
                status = ((i2cRegs->BUFSTAT) & (CSL_I2C_BUFSTAT_FIFODEPTH_MASK));
                break;
    
            default:
                /* Invalid input */
                status = 0U;
                break;
        }
    
        return status;
    }
    
    static void I2COwnAddressSet(uint32_t baseAddr, uint32_t ownAdd, uint32_t flag)
    {
        CSL_I2cRegsOvly i2cRegs = (CSL_I2cRegsOvly)baseAddr;
    
        switch (flag)
        {
            case I2C_OWN_ADDR_0:
                i2cRegs->OA = ownAdd;
                break;
    
            case I2C_OWN_ADDR_1:
                i2cRegs->OA1 = ownAdd;
                break;
    
            case I2C_OWN_ADDR_2:
                i2cRegs->OA2 = ownAdd;
                break;
    
            case I2C_OWN_ADDR_3:
                i2cRegs->OA3 = ownAdd;
                break;
    
            default:
                /* Invalid input */
                break;
        }
    }
    
    static void I2CSoftReset(uint32_t baseAddr)
    {
        CSL_I2cRegsOvly i2cRegs = (CSL_I2cRegsOvly)baseAddr;
        i2cRegs->SYSC |= I2C_SYSC_SRST_MASK;
    }
    
    static void I2CAutoIdleDisable(uint32_t baseAddr)
    {
        CSL_I2cRegsOvly i2cRegs = (CSL_I2cRegsOvly)baseAddr;
        i2cRegs->SYSC &= ~I2C_SYSC_AUTOIDLE_MASK;
    }
    
    static uint32_t I2CSystemStatusGet(uint32_t baseAddr)
    {
        CSL_I2cRegsOvly i2cRegs = (CSL_I2cRegsOvly)baseAddr;
        return (i2cRegs->SYSS & I2C_SYSS_RDONE_MASK);
    }
    
    static void I2CControllerDataPut(uint32_t baseAddr, uint8_t data)
    {
        CSL_I2cRegsOvly i2cRegs = (CSL_I2cRegsOvly)baseAddr;
        i2cRegs->DATA = (uint32_t)data;
        /*write data to be transmitted to Data transmit register */
    }
    
    static uint8_t I2CControllerDataGet(uint32_t baseAddr)
    {
        CSL_I2cRegsOvly i2cRegs = (CSL_I2cRegsOvly)baseAddr;
        uint8_t rData;
    
        rData = (uint8_t)(i2cRegs->DATA);
    
        return rData;
    }
    
    static uint8_t I2CTargetDataGet(uint32_t baseAddr)
    {
        CSL_I2cRegsOvly i2cRegs = (CSL_I2cRegsOvly)baseAddr;
        uint8_t rData;
    
        rData = (uint8_t)(i2cRegs->DATA);
    
        return rData;
    }
    
    static void I2CSyscInit(uint32_t baseAddr, uint32_t syscFlag)
    {
        CSL_I2cRegsOvly i2cRegs = (CSL_I2cRegsOvly)baseAddr;
        i2cRegs->SYSC = syscFlag;
    }
    
    static void I2CConfig(uint32_t baseAddr, uint32_t conParams)
    {
        CSL_I2cRegsOvly i2cRegs = (CSL_I2cRegsOvly)baseAddr;
        i2cRegs->CON = conParams;
    }
    
    /** ============================================================================
    * Description:      Waits for bus to become free; program will wait for the bus
    *                   to become free for timeout number of ticks
    *                   keeping track of time.
    *                   In case value of provided timeout is zero; program will
    *                   wait for 500 micro Seconds.
    *
    * Input Parameters: handle(I2CLLD_Handle)
    *                   flag(uint32_t)
    *                   pTimeout(uint32_t *)
    * Return Values:    I2C_STS_SUCCESS,
    *                   I2C_STS_ERR_TIMEOUT,
    ** ========================================================================== */
    
    static int32_t I2C_waitForBb(I2CLLD_Handle handle, uint32_t timeout)
    {
        uint32_t            stat;
        int32_t             retVal = I2C_STS_SUCCESS;
        uint32_t            bbtimeout = timeout;
        uint32_t            startTicks, elapsedTicks = 0;
        I2CLLD_Object       *object = NULL;
    
        /* Get Pointer to the driver object */
        object = (I2CLLD_Object *)handle;
    
        if(bbtimeout > 0U)
        {
            /* BUS BUS timeout greater than 0 (Valid Value) */
            /* Clear current interrupts...*/
            I2CControllerIntClearEx(object->baseAddr, I2C_INT_ALL);
    
            while (bbtimeout > 0U)
            {
                /* Poll Bus Busy bit */
                stat = I2CControllerIntRawStatusEx(object->baseAddr, I2C_INT_BUS_BUSY);
                if (stat == 0U)
                {
                    /* Bus Free Case, Break out of loop */
                    break;
                }
                /* Decrement bus busy timeout */
                bbtimeout = bbtimeout - 1U;
            }
    
            if (timeout > 0U)
            {
                if (bbtimeout == 0U)
                {
                    /* Timeout happened */
                    retVal = I2C_STS_ERR_TIMEOUT;
                }
                else
                {
                    /* Bus is free before timeout could happen */
                    /* No Code */
                }
            }
    
            /* Clear all interrupts (delayed stuff) */
            I2CControllerIntClearEx(object->baseAddr, I2C_INT_ALL);
        }
        else
        {
            /* If provided timeout value is zero */
            startTicks = object->Clock_getTicks();
    
            while((I2CControllerBusBusy(object->baseAddr) == 1)  &&
            (elapsedTicks < object->Clock_usecToTicks(I2C_BUS_BUSY_TIMEOUT_IN_US)))
            {
                elapsedTicks = object->Clock_getTicks() - startTicks;
                /* Set timeout error if timeout occurred */
                if(elapsedTicks >=
                        object->Clock_usecToTicks(I2C_BUS_BUSY_TIMEOUT_IN_US))
                {
                    retVal = I2C_STS_ERR_TIMEOUT;
                    break;
                }
            }
        }
    
        return retVal;
    }
    
    /** ============================================================================
    * Description:      Internal function, waits for flag bits to be set while
    *                   keeping track of time.
    *
    * Input Parameters: handle(I2CLLD_Handle)
    *                   flag(uint32_t)
    *                   pTimeout(uint32_t *)
    * Return Values:    I2C_STS_SUCCESS,
    *                   I2C_STS_ERR_TIMEOUT,
    ** ========================================================================== */
    
    static int32_t I2C_waitForPin( I2CLLD_Handle handle,
                                    uint32_t flag,
                                    uint32_t *pTimeout)
    {
        int32_t             status = I2C_STS_SUCCESS;
        uint32_t            intRawStat = 0U;
        uint32_t            timeout = *pTimeout;
        I2CLLD_Object       *object = NULL;
    
        /* Get pointer to the driver Object */
        object = (I2CLLD_Object *)handle;
    
        if(timeout > 0U)
        {
            /* Get Current Interrupt Status */
            intRawStat = I2CControllerIntRawStatus(object->baseAddr);
            /* Loop until the flag condition is met or timeout happens */
            while ( ((uint32_t) 0U == (intRawStat & flag)) &&
                    (status == I2C_STS_SUCCESS))
            {
                if (    ((object->Clock_getTicks()) - (object->startTicks)) >
                        (object->Clock_usecToTicks((uint64_t)(timeout))))
                {
                    status = I2C_STS_ERR_TIMEOUT;
                }
                /* Update Interrupt Status */
                intRawStat = I2CControllerIntRawStatus(object->baseAddr);
            }
    
            if (status == I2C_STS_ERR_TIMEOUT)
            {
                /* Clear all Interrupts in case of timeout */
                I2CControllerIntClearEx(object->baseAddr, I2C_INT_ALL);
            }
        }
    
        return status;
    }
    
    /** ============================================================================
    * Description:      Internal function to Initialize I2C Transaction
    * Input Parameters: I2CLLD_Handle, I2CLLD_Message
    * Return Values:    I2C_STS_SUCCESS,
    *                   I2C_STS_ERR_INVALID_PARAM,
    *                   I2C_STS_ERR_BUS_BUSY
    ** ========================================================================== */
    
    static int32_t I2C_lld_transferInit(I2CLLD_Handle handle, I2CLLD_Message *msg)
    {
        int32_t             status = I2C_STS_SUCCESS;
        I2CLLD_Object       *object = NULL;
    
        /* Get the pointer to the object */
        object = (I2CLLD_Object*)handle;
    
        if (msg->timeout == 0U)
        {
            /* Timeout cannot be I2C_NO_WAIT, set it to I2C_WAIT_FOREVER */
            msg->timeout = I2C_WAIT_FOREVER;
        }
    
        if((msg->txn) == (I2CLLD_Transaction *)NULL)
        {
            status = I2C_STS_ERR_INVALID_PARAM;
        }
    
        if (    (status == I2C_STS_SUCCESS) &&
                ((msg->txn->writeCount != 0U) || (msg->txn->readCount != 0U)))
        {
            if (object->state == I2C_STATE_IDLE)
            {
                /* No current transfer is going on. */
                /* Set state to busy */
                object->state = I2C_STATE_BUSY;
                /* Set current message */
                object->currentMsg = msg;
                /* Set transaction count to zero */
                object->currentTxnCount = 0U;
            }
            else
            {
                /* Some transfer is going on. return with system busy. */
                status = I2C_STS_ERR_BUS_BUSY;
            }
        }
    
        return status;
    }
    
    /** ============================================================================
    * Description:      Polling mode prime transfer function. Carries out all
    *                   all transactions within the given message
    *                   I2C_lld_transferInit was called with before calling this.
    *
    * Input Parameters: I2CLLD_Handle
    * Return Values:    I2C_STS_SUCCESS,
    *                   I2C_STS_ERR_TIMEOUT,
    *                   I2C_STS_ERR_ARBITRATION_LOST,
    *                   I2C_STS_ERR_NO_ACK,
    *                   I2C_STS_ERR_ACCESS_ERROR,
    *                   I2C_STS_ERR
    ** ========================================================================== */
    
    static int32_t I2C_lld_primeTransferPoll(I2CLLD_Handle handle)
    {
        I2CLLD_Object       *object = NULL;
        int32_t             status = I2C_STS_SUCCESS;
        uint32_t            xsa, regVal;
        uint32_t            errStat = 0, fatalError = 0;
    
        /* Get the pointer to the object */
        object = (I2CLLD_Object*)handle;
        /* Store current time */
        object->startTicks = object->Clock_getTicks();
    
        while((object->currentTxnCount) < (object->currentMsg->txnCount))
        {
            /* Store Write and Read details in the driver object */
            object->writeBufIdx = (uint8_t*)object->currentMsg->txn[object->currentTxnCount].writeBuf;
            object->writeCountIdx = (uint32_t)object->currentMsg->txn[object->currentTxnCount].writeCount;
    
            object->readBufIdx = (uint8_t*)object->currentMsg->txn[object->currentTxnCount].readBuf;
            object->readCountIdx = (uint32_t)object->currentMsg->txn[object->currentTxnCount].readCount;
    
            /* Clear All interrupts */
            I2CControllerIntClearEx(object->baseAddr, I2C_INT_ALL);
    
            if (object->currentMsg->expandSA == true)
            {
                /* Enable the 10-bit address mode */
                xsa = I2C_CFG_10BIT_TARGET_ADDR;
            }
            else
            {
                /* Enable the 7-bit address mode */
                xsa = I2C_CFG_7BIT_TARGET_ADDR;
            }
    
            /* Wait for Bus to be free */
            while(  (I2CControllerBusBusy(object->baseAddr) == (int32_t)1) &&
                    (status == I2C_STS_SUCCESS))
            {
                if (    ((object->Clock_getTicks()) - (object->startTicks)) >
                        (object->Clock_usecToTicks((uint64_t)(object->currentMsg->timeout))))
                {
                    status = I2C_STS_ERR_TIMEOUT;
                }
            }
    
            /* In case previous transaction failed and there is still data in FIFO */
            /* Clear TX FIFO */
            I2CFIFOClear(object->baseAddr, I2C_TX_MODE);
            /* Clear RX FIFO */
            I2CFIFOClear(object->baseAddr, I2C_RX_MODE);
    
            /* Controller Mode */
            if(object->currentMsg->controllerMode)
            {
                /* In controller mode, set the I2C target address */
                I2CControllerTargetAddrSet( object->baseAddr,
                                            object->currentMsg->targetAddress);
    
                if((object->writeCountIdx != 0U) && (status == I2C_STS_SUCCESS))
                {
                    /* Set number of bytes to Write */
                    I2CSetDataCount(object->baseAddr, object->writeCountIdx);
                    /* Put controller in transmitter mode */
                    regVal = I2C_CFG_MST_TX | xsa;
                    /* Check if I2C is in HS-Mode or not */
                    if (    (object->bitRate == I2C_1P0MHZ) ||
                            (object->bitRate == I2C_3P4MHZ))
                    {
                        regVal |= I2C_CFG_HS_MOD;
                    }
                    /* Write configuration to control Register */
                    I2CControllerControl(object->baseAddr, regVal);
                    /* Generate start */
                    I2CControllerStart(object->baseAddr);
                    /* Loop Until Write is complete or timeout happens or some error happens */
                    while ((object->writeCountIdx != 0U) && (status == I2C_STS_SUCCESS))
                    {
                        /* Wait for transmit ready or error or timeout */
                        while(  (
                                (I2CControllerIntRawStatusEx(object->baseAddr,  I2C_INT_TRANSMIT_READY) == 0U) &&
                                (I2CControllerIntRawStatusEx(object->baseAddr, (I2C_INT_ARBITRATION_LOST    |
                                                                                I2C_INT_NO_ACK              |
                                                                                I2C_INT_ACCESS_ERROR        |
                                                                                I2C_INT_STOP_CONDITION) ) == 0U)) &&
                                (status == I2C_STS_SUCCESS))
                        {
                            if (((object->Clock_getTicks()) - (object->startTicks)) >
                                (object->Clock_usecToTicks((uint64_t)(object->currentMsg->timeout))))
                            {
                                status = I2C_STS_ERR_TIMEOUT;
                            }
                        }
                        /* Get raw interrupt status */
                        errStat = I2CControllerIntRawStatusEx(object->baseAddr, I2C_INT_ARBITRATION_LOST    | \
                                                                                I2C_INT_NO_ACK              | \
                                                                                I2C_INT_ACCESS_ERROR);
    
                        /* if we get an error or timeout happens, break out of loop */
                        if ((errStat != 0U) || (status != I2C_STS_SUCCESS))
                        {
                            if(errStat != 0U)
                            {
                                fatalError = 1U;
                            }
                            break;
                        }
    
                        /* Write byte and increase data pointer to next byte */
                        I2CControllerDataPut(object->baseAddr, *(object->writeBufIdx));
                        /* Increment write buffer index */
                        (object->writeBufIdx)++;
                        /* Clear transmit ready interrupt */
                        I2CControllerIntClearEx(object->baseAddr, I2C_INT_TRANSMIT_READY);
                        /* Update number of bytes to be written */
                        object->writeCountIdx--;
                        /* In case of memory transaction, change buffer index */
                        if(handle->memTxnActive)
                        {
                            if( (handle->i2ctxn.writeCount - handle->memAddrSize) ==
                                (handle->writeCountIdx))
                            {
                                handle->writeBufIdx = handle->dataArray;
                            }
                        }
                    }
    
                    if ((fatalError == 0U) && (status == I2C_STS_SUCCESS))
                    {
                        /* No Error happened, write completed successfully */
                        /* Wait for register access ready */
                        status = I2C_waitForPin(    object,
                                                    I2C_INT_ADRR_READY_ACESS,
                                                    &(object->currentMsg->timeout));
                    }
    
                    if(fatalError == 1U)
                    {
                        /* Some kind of Error Happened */
                        if ((errStat & I2C_INT_ARBITRATION_LOST) == I2C_INT_ARBITRATION_LOST)
                        {
                            status = I2C_STS_ERR_ARBITRATION_LOST;
                        }
                        else if ((errStat & I2C_INT_NO_ACK) == I2C_INT_NO_ACK)
                        {
                            status = I2C_STS_ERR_NO_ACK;
                        }
                        else if ((errStat & I2C_INT_ACCESS_ERROR) == I2C_INT_ACCESS_ERROR)
                        {
                            status = I2C_STS_ERR_ACCESS_ERROR;
                        }
                        else
                        {
                            /* No Code */
                        }
                        /* Store error in error status */
                        object->intStatusErr = errStat;
                    }
                    else
                    {
                        /* No Code */
                    }
    
                    if (object->readCountIdx == 0U)
                    {
                        /* There is nothing to read as part of this transaction */
                        /* Generate stop when there is no read followed by write */
                        I2CControllerStop(object->baseAddr);
    
                        /* Check if any Error occured during write */
                        if ((fatalError == 0U) && (status == I2C_STS_SUCCESS))
                        {
                            /* No Error happened; Write executed successfully */
                            /* Wait for stop to happen */
                            status = I2C_waitForPin(handle,
                                                    I2C_INT_STOP_CONDITION,
                                                    &(object->currentMsg->timeout));
    
    
                            /* Wait for register access ready */
                            status = I2C_waitForPin(handle,
                                                    I2C_INT_ADRR_READY_ACESS,
                                                    &(object->currentMsg->timeout));
                        }
                        else
                        {
                            /* Some Error happened */
                            /* Wait for stop to Happen; ignore return value */
                            (void)I2C_waitForPin(   handle,
                                                    I2C_INT_STOP_CONDITION,
                                                    &(object->currentMsg->timeout));
                            /* Wait for register access ready */
                            (void)I2C_waitForPin(   handle,
                                                    I2C_INT_ADRR_READY_ACESS,
                                                    &(object->currentMsg->timeout));
                            /* Return value ignored as status should hold the error
                            */
                        }
                    }
                    else
                    {
                        /* There is some read to be executed
                        as part of this transaction */
    
                        /*
                            Do nothing
                            1. if some error happened during write status will not
                                be I2C_STS_SUCCESS so read will not happen.
                            2. if write operation happened successfully and read
                                count is not zero then driver will wait for
                                I2C_INT_ADRR_READY_ACESS and go for read operation
                                without stop condition.
                        */
                    }
                }
    
                if ((object->readCountIdx != 0U) && (status == I2C_STS_SUCCESS))
                {
                    /* Clear all interrupts */
                    I2CControllerIntClearEx(object->baseAddr, I2C_INT_ALL);
                    /* Set number of bytes to read */
                    I2CSetDataCount(object->baseAddr, object->readCountIdx);
                    /* Set to controller receiver mode */
                    regVal = I2C_CFG_MST_RX | xsa;
                    /* Check if I2C is in HS-Mode or not */
                    if ((object->bitRate == I2C_1P0MHZ) ||
                        (object->bitRate == I2C_3P4MHZ))
                    {
                        regVal |= I2C_CFG_HS_MOD;
                    }
                    /* Write configuration to control Register */
                    I2CControllerControl(object->baseAddr, regVal);
                    /* Generate start */
                    I2CControllerStart(object->baseAddr);
                    /* Loop until read completes or some error happens */
                    while ((object->readCountIdx != 0U) && (status == I2C_STS_SUCCESS))
                    {
                        /* Wait for receive ready or error */
                        while(( (I2CControllerIntRawStatusEx(object->baseAddr,  I2C_INT_RECV_READY) == 0U) &&
                                (I2CControllerIntRawStatusEx(object->baseAddr,  I2C_INT_ARBITRATION_LOST    |
                                                                                I2C_INT_NO_ACK              |
                                                                                I2C_INT_ACCESS_ERROR ) == 0U)) &&
                                (status == I2C_STS_SUCCESS))
                        {
                            if (((object->Clock_getTicks()) - (object->startTicks)) >
                                (object->Clock_usecToTicks((uint64_t)(object->currentMsg->timeout))))
                            {
                                status = I2C_STS_ERR_TIMEOUT;
                            }
                        }
    
                        errStat = I2CControllerIntRawStatusEx(object->baseAddr, I2C_INT_ARBITRATION_LOST    |
                                                                                I2C_INT_NO_ACK              |
                                                                                I2C_INT_ACCESS_ERROR);
    
                        /* if we get an error or timeout happens, break out of loop */
                        if ((errStat != 0U) || (status != I2C_STS_SUCCESS))
                        {
                            if(errStat != 0U)
                            {
                                fatalError = 1U;
                            }
                            break;
                        }
    
                        /* Read byte */
                        *(object->readBufIdx) =
                            (uint8_t)I2CControllerDataGet(object->baseAddr);
    
                        /* Clear receive ready interrupt */
                        I2CControllerIntClearEx(object->baseAddr, I2C_INT_RECV_READY);
                        /* Increment read buffer index */
                        object->readBufIdx++;
                        /* Update number of bytes to be read */
                        object->readCountIdx--;
                    }
    
                    if ((fatalError == 0U) && (status == I2C_STS_SUCCESS))
                    {
                        /* Wait for register access ready */
                        status = I2C_waitForPin(    handle,
                                                    I2C_INT_ADRR_READY_ACESS,
                                                    &(object->currentMsg->timeout));
                    }
    
                    if(fatalError == 1U)
                    {
                        /* Some kind of Error Happened */
                        if ((errStat & I2C_INT_ARBITRATION_LOST) == I2C_INT_ARBITRATION_LOST)
                        {
                            status = I2C_STS_ERR_ARBITRATION_LOST;
                        }
                        else if ((errStat & I2C_INT_NO_ACK) == I2C_INT_NO_ACK)
                        {
                            status = I2C_STS_ERR_NO_ACK;
                        }
                        else if ((errStat & I2C_INT_ACCESS_ERROR) == I2C_INT_ACCESS_ERROR)
                        {
                            status = I2C_STS_ERR_ACCESS_ERROR;
                        }
                        else
                        {
                            /* No Code */
                         }
                        /* Store error in error status */
                        object->intStatusErr = errStat;
                    }
                    else
                    {
                        /* No Error Happened */
                        /* No Code */
                    }
    
                    /* Generate stop */
                    I2CControllerStop(object->baseAddr);
    
                    if ((fatalError == 0U) && (status == I2C_STS_SUCCESS))
                    {
                        /* No Error happened; Read executed successfully */
                        /* Wait for stop to happen */
                        status = I2C_waitForPin(    handle,
                                                    I2C_INT_STOP_CONDITION,
                                                    &(object->currentMsg->timeout));
    
                        /* Wait for register access ready */
                        status = I2C_waitForPin(    handle,
                                                    I2C_INT_ADRR_READY_ACESS,
                                                    &(object->currentMsg->timeout));
                    }
                    else
                    {
                        /* Some Error happened */
                        /* Wait for stop to happen */
                        (void)I2C_waitForPin(   handle,
                                                I2C_INT_STOP_CONDITION,
                                                &(object->currentMsg->timeout));
    
                        /* Wait for register access ready */
                        (void)I2C_waitForPin(   handle,
                                                I2C_INT_ADRR_READY_ACESS,
                                                &(object->currentMsg->timeout));
                        /* Return value ignored as status should hold the error
                        */
                    }
                }
            }
            /* Target Mode */
            else
            {
                /* Polling mode not available in target Mode */
                /* Control should not enter here */
                status = I2C_STS_ERR;
            }
    
            if(status == I2C_STS_SUCCESS)
            {
                /* If Last transaction completed successfully */
                /* Increment Transaction count and go to next Transaction */
                object->currentTxnCount++;
            }
            else
            {
                /* Last transaction failed */
                /* Break out of loop of transactions */
                break;
            }
        }
    
        /* No further Transactions or some existing transaction Failed */
        object->currentMsg = NULL;
        /* Change the driver State back to idle */
        object->state = I2C_STATE_IDLE;
    
        return status;
    }
    
    /** ============================================================================
    * Description:      Interrupt mode prime transfer function. Carries out all
    *                   all transactions within the given message
    *                   I2C_lld_transferInit was called with before calling this.
    *
    * Input Parameters: I2CLLD_Handle
    * Return Values:    I2C_STS_SUCCESS,
    *                   I2C_STS_ERR
    ** ========================================================================== */
    
    static int32_t I2C_lld_primeTransferIntr(I2CLLD_Handle handle)
    {
        I2CLLD_Object       *object = NULL;
        int32_t             status = I2C_STS_SUCCESS;
        uint32_t            xsa, regVal;
    
        /* Get the pointer to the object */
        object = (I2CLLD_Object *)handle;
    
        /* Store Write and Read details in the driver object */
        object->writeBufIdx = (uint8_t*)object->currentMsg->txn[object->currentTxnCount].writeBuf;
        object->writeCountIdx = (uint32_t)object->currentMsg->txn[object->currentTxnCount].writeCount;
    
        object->readBufIdx = (uint8_t*)object->currentMsg->txn[object->currentTxnCount].readBuf;
        object->readCountIdx = (uint32_t)object->currentMsg->txn[object->currentTxnCount].readCount;
    
        if(object->intStatusErr != 0)
        {
            (void)I2C_lld_recoverBus(object, 10);
        }
    
        object->intStatusErr = 0;
    
        if (object->currentMsg->expandSA == true)
        {
            /* Enable the 10-bit address mode */
            xsa = I2C_CFG_10BIT_TARGET_ADDR;
        }
        else
        {
            /* Enable the 7-bit address mode */
            xsa = I2C_CFG_7BIT_TARGET_ADDR;
        }
        /* Clear all interrupts */
        I2CControllerIntClearEx(object->baseAddr, I2C_INT_ALL);
        /* Clear TX FIFO */
        I2CFIFOClear(object->baseAddr, I2C_TX_MODE);
        /* Clear RX FIFO */
        I2CFIFOClear(object->baseAddr, I2C_RX_MODE);
    
        /* Controller Mode */
        if (object->currentMsg->controllerMode)
        {
            /* In controller mode, set the I2C target address */
            I2CControllerTargetAddrSet( object->baseAddr,
                                        object->currentMsg->targetAddress);
            /* Start transfer in Transmit mode */
            if (object->writeCountIdx != 0U)
            {
                /* Write Count not zero */
                /* Set number of bytes to be transmitting */
                I2CSetDataCount(object->baseAddr, object->writeCountIdx);
                /*
                 * Configure the I2C transfer to be in controller transmitter mode
                 */
                regVal = I2C_CFG_MST_TX | xsa;
                if ((object->readCountIdx) == 0U)
                {
                    /*
                     * if there is no read data, automatically send stop when write is complete
                     * otherwise (restart), do not send stop
                     */
                    regVal |= I2C_CFG_STOP;
                }
    
                if ((object->bitRate == I2C_1P0MHZ) || (object->bitRate == I2C_3P4MHZ))
                {
                    regVal |= I2C_CFG_HS_MOD;
                }
                I2CControllerControl(object->baseAddr, regVal);
    
                regVal =    I2C_INT_TRANSMIT_READY | I2C_INT_ADRR_READY_ACESS |
                            I2C_INT_NO_ACK | I2C_INT_ARBITRATION_LOST;
                /* Enable Requried Interrupts */
                I2CControllerIntEnableEx(object->baseAddr, regVal);
                /* Start the I2C transfer in controller transmit mode */
                I2CControllerStart(object->baseAddr);
    
            }
            else
            {
                /* Write count zero */
                /* Specify the number of bytes to read */
                I2CSetDataCount(object->baseAddr, object->readCountIdx);
    
                /*
                 * Start the I2C transfer in controller receive mode,
                 * and automatically send stop when done
                 */
                regVal = I2C_CFG_MST_RX | I2C_CFG_STOP | xsa;
                if (    (object->bitRate == I2C_1P0MHZ) ||
                        (object->bitRate == I2C_3P4MHZ))
                {
                    regVal |= I2C_CFG_HS_MOD;
                }
                I2CControllerControl(object->baseAddr, regVal);
    
                /* Enable RX interrupts */
                I2CControllerIntEnableEx(   object->baseAddr,
                                            I2C_INT_RECV_READY          |
                                            I2C_INT_ADRR_READY_ACESS    |
                                            I2C_INT_NO_ACK              |
                                            I2C_INT_ARBITRATION_LOST);
                /* Send start bit */
                I2CControllerStart(object->baseAddr);
            }
        }
        /* Target Mode */
        else
        {
            status = I2C_STS_ERR;
        }
    
        return status;
    }
    
    /** ============================================================================
    * Description:      Completes current transaction; increments current
    *                   transaction count if more transactions available in current
    *                   message or finishes the transfer process.
    *
    * Input Parameters: handle(I2CLLD_Handle), xferStatus(int32_t)
    * Return Values:    NONE
    ** ========================================================================== */
    
    static void I2C_lld_completeCurrTransfer(   I2CLLD_Handle handle,
                                                int32_t xferStatus)
    {
        I2CLLD_Object *object = (I2CLLD_Object*)handle;
        /* Input parameter validation */
        if (handle != NULL)
        {
            if(object->currentMsg != NULL)
            {
                if( (xferStatus == I2C_STS_SUCCESS) &&
                    (object->currentTxnCount < (object->currentMsg->txnCount - 1U)))
                {
                    /* Last transaction completed successfully,
                     * Other thansactions available */
                    /* Increment Current Transaction Count */
                    object->currentTxnCount++;
                    /* Initiate the next transaction */
                    (void)I2C_lld_primeTransferIntr(handle);
                }
                else
                {
                    /* No other thansactions available */
                    /* Clear the data Array in case transaction was of type mem */
                    object->dataArray = (uint8_t*)NULL;
                    /* Call Transfer Complete Callback */
                    object->transferCompleteCallback(handle, object->currentMsg, xferStatus);
                    /* No other transactions need to occur */
                    object->currentMsg = NULL;
                    /* Change I2C state back to Idle */
                    object->state = I2C_STATE_IDLE;
                }
            }
        }
    }
    
    /** ============================================================================
    * Description:      Completes current target transaction. Clears stored current
    *                   Target Transaction.
    *
    * Input Parameters: handle(I2CLLD_Handle), xferStatus(int32_t)
    * Return Values:    NONE
    ** ========================================================================== */
    
    static void I2C_lld_completeCurrTargetTransfer( I2CLLD_Handle handle,
                                                    int32_t xferStatus)
    {
        if(handle != NULL)
        {
            /* Get Pointer to driver Object */
            I2CLLD_Object *object = (I2CLLD_Object*)handle;
            /* Callback to Application */
            object->targetTransferCompleteCallback( (void *)object,
                                                    object->currentTargetTransaction,
                                                    xferStatus);
            /* No other transactions need to occur */
            object->currentTargetTransaction = NULL;
            /* Change driver state back to IDLE */
            object->state = I2C_STATE_IDLE;
        }
    }
    
    static int32_t I2C_lld_resetCtrl(I2CLLD_Handle handle)
    {
        int32_t status = I2C_STS_SUCCESS;
    
        if(handle != NULL)
        {
            status = I2C_lld_ctrlInit(handle);
        }
        else
        {
            status = I2C_STS_ERR_INVALID_PARAM;
        }
    
        return status;
    }
    
    static int32_t I2C_lld_ctrlInit(I2CLLD_Handle handle)
    {
        I2CLLD_Object       *object = NULL;
        uint32_t            delay = 50U;
        uint32_t            outputClk;
        uint32_t            internalClk;
        uint32_t            regVal;
        int32_t             retVal = I2C_STS_SUCCESS;
    
        /* Get the pointer to the object */
        object = (I2CLLD_Object *)handle;
    
        /* Put i2c in reset/disabled state */
        I2CControllerDisable(object->baseAddr);
        /* Do a software reset */
        I2CSoftReset(object->baseAddr);
        /* Enable i2c module */
        I2CControllerEnable(object->baseAddr);
    
        /* Wait for the reset to get complete  -- constant delay - 50ms */
        while ((I2CSystemStatusGet(object->baseAddr) == 0U) && (delay != 0U))
        {
            delay--;
            object->Clock_uSleep(1000);
        }
    
        if (delay == 0U)
        {
            /* Reset has failed, return!!! */
            retVal = I2C_STS_ERR;
        }
        else
        {
            /* Put i2c in reset/disabled state */
            I2CControllerDisable(object->baseAddr);
            /* Configure i2c bus speed */
            switch(object->bitRate)
            {
                case I2C_100KHZ:
                {
                    outputClk = 100000U;
                    internalClk = I2C_MODULE_INTERNAL_CLK_4MHZ;
                    break;
                }
                case I2C_400KHZ:
                {
                    outputClk = 400000U;
                    internalClk = I2C_MODULE_INTERNAL_CLK_12MHZ;
                    break;
                }
                case I2C_1P0MHZ:
                {
                    outputClk = 1000000U;
                    internalClk = I2C_MODULE_INTERNAL_CLK_12MHZ;
                    break;
                }
               case I2C_3P4MHZ:
               {
                    outputClk = 3400000U;
                    internalClk = I2C_MODULE_INTERNAL_CLK_12MHZ;
                    break;
               }
    
               default:
               {
                    /* Default case force it to 100 KHZ bit rate */
                    outputClk = 100000U;
                    internalClk = I2C_MODULE_INTERNAL_CLK_4MHZ;
                    break;
               }
    
            }
    
            /* Set the I2C configuration */
            I2CControllerInitExpClk(    object->baseAddr, object->funcClk,
                                        internalClk, outputClk);
            /**
             * Configure I2C_SYSC params
             * Disable auto idle mode
             * Both OCP and systen clock cut off
             * Wake up mechanism disabled
             * No idle mode selected
             */
            regVal = (CSL_I2C_SYSC_AUTOIDLE_MASK) &
                    (CSL_I2C_SYSC_AUTOIDLE_DISABLE << CSL_I2C_SYSC_AUTOIDLE_SHIFT);
            regVal |= (CSL_I2C_SYSC_IDLEMODE_MASK) &
                    (CSL_I2C_SYSC_IDLEMODE_NOIDLE << CSL_I2C_SYSC_IDLEMODE_SHIFT);
            regVal |= (CSL_I2C_SYSC_ENAWAKEUP_MASK) &
                    (CSL_I2C_SYSC_ENAWAKEUP_DISABLE << CSL_I2C_SYSC_ENAWAKEUP_SHIFT);
            regVal |= (CSL_I2C_SYSC_CLKACTIVITY_MASK) &
                    ((uint32_t)CSL_I2C_SYSC_CLKACTIVITY_BOOTHOFF << (uint32_t)CSL_I2C_SYSC_CLKACTIVITY_SHIFT);
    
            I2CSyscInit(object->baseAddr, regVal);
    
            /* Configure I2C_CON params */
            regVal =    (I2C_CON_OPMODE_MASK) &
                        (I2C_CON_OPMODE_FSI2C << I2C_CON_OPMODE_SHIFT);
            regVal |=   (I2C_CON_STB_MASK) &
                        (I2C_CON_STB_NORMAL << I2C_CON_STB_SHIFT);
    
            I2CConfig(object->baseAddr, regVal);
    
            /* Take the I2C module out of reset */
            I2CControllerEnable(object->baseAddr);
            /* Enable free run mode */
            I2CControllerEnableFreeRun(object->baseAddr);
        }
    
        /* Clear interrupt status register */
        I2CControllerIntClearEx(object->baseAddr, I2C_INT_ALL);
    
        return retVal;
    }
    

    i2c_v0.c file present under mcu_plus_sdk_path/source/drivers/i2c/v0/i2c_v0.c

    /*
     *  Copyright (C)2018-2024 Texas Instruments Incorporated
     *
     *  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   i2c_v0.c
     *
     *  \brief  File containing I2C Driver APIs implementation for V0.
     */
    
    /* ========================================================================== */
    /*                             Include Files                                  */
    /* ========================================================================== */
    
    #include <drivers/i2c.h>
    #include <kernel/dpl/AddrTranslateP.h>
    
    /* ========================================================================== */
    /*                           Macros & Typedefs                                */
    /* ========================================================================== */
    
    #define I2C_DELAY_MED                   ((uint32_t) 10000U)
    #define I2C_DELAY_BIG                   ((uint32_t) 30000U)
    #define I2C_DELAY_SMALL                 ((uint32_t) 5000U)
    #define I2C_DELAY_USEC                  ((uint32_t) 250U)
    
    /*
     * Maximum number of loop count to handle in the same ISR, which is
     * to process multiple interrupts (ARDY, RRDY, XRDY) in the ISR to
     * reduce interrupt count
     *
     * Keep at least 3 to support optimal RX followed by TX scenario
     * Keep at least 2 to support optimal RX scenario
     */
    #define I2C_MAX_CONSECUTIVE_ISRS      (1U)
    
    /* ========================================================================== */
    /*                         Structure Declarations                             */
    /* ========================================================================== */
    
    typedef struct
    {
        void                   *lock;
        /**< Driver lock - to protect across open/close */
        SemaphoreP_Object       lockObj;
        /**< Driver lock object */
    } I2C_DrvObj;
    
    /* Default I2C parameters structure */
    const I2C_Params I2C_defaultParams = {
    
        I2C_MODE_BLOCKING,              /* transferMode */
        NULL,                           /* transferCallbackFxn */
        I2C_100KHZ,                     /* bitRate */
    };
    
    /* Default I2C Memory Transaction Structure */
    const I2C_Mem_Transaction I2C_defaultMemTransaction = {
    
        0,                              /* memAddr */
        I2C_MEM_ADDR_SIZE_8_BITS,       /* memAddrSize */
        NULL,                           /* buffer */
        0,                              /* size */
        I2C_MEM_TXN_DIR_INVALID         /* memDataDir */
    };
    
    /* Default I2C transaction parameters structure */
    const I2C_Transaction I2C_defaultTransaction = {
    
        NULL,                           /* writeBuf */
        0,                              /* writeCount */
        NULL,                           /* readBuf */
        0,                              /* readCount */
        0,                              /* targetAddress */
        NULL,                           /* nextPtr */
        NULL,                           /* arg */
        SystemP_WAIT_FOREVER,           /* timeout */
        (bool)true,                     /* controllerMode */
        (bool)false,                    /* expandSA */
        (bool)false,                    /* memTxnEnable */
        NULL,                           /* memTransaction */
        I2C_STS_SUCCESS                 /* status */
    };
    
    /* ========================================================================== */
    /*                     Internal Function Declarations                         */
    /* ========================================================================== */
    
    static inline void I2C_transferCallback(I2C_Handle handle,
                                            I2C_Transaction *msg,
                                            int32_t transferStatus);
    
    static void I2C_completeCurrTransfer(I2C_Handle handle, int32_t xferStatus);
    
    /* Transfer complete callback functions */
    static void I2C_LLD_transferCompleteCallback(void *args,
                                                 const I2CLLD_Message * msg,
                                                 int32_t transferStatus);
    
    static void I2C_LLD_targetTransferCompleteCallback(void *args,
                                        const I2CLLD_targetTransaction * targetTxn,
                                        int32_t transferStatus);
    
    /* HWI Function */
    static void I2C_hwiFxn(void* arg);
    
    /* Internal Transfer Functions */
    static int32_t I2C_primeTransfer(I2C_Handle handle,
                                     I2C_Transaction *transaction);
    
    static int32_t I2C_mem_primeTransfer(I2C_Handle handle,
                                         I2C_Transaction *transaction);
    /* ========================================================================== */
    /*                            Global Variables                                */
    /* ========================================================================== */
    
    /* Externs */
    extern I2C_Config gI2cConfig[];
    extern uint32_t gI2cConfigNum;
    
    /** \brief Driver object */
    static I2C_DrvObj gI2cDrvObj =
    {
        .lock = NULL,
    };
    
    /* ========================================================================== */
    /*                       API Function Definitions                             */
    /* ========================================================================== */
    
    void I2C_init(void)
    {
        I2C_Handle handle;
        uint32_t i;
    
        /* Call init function for each config */
        for (i = 0; i < gI2cConfigNum; i++)
        {
            handle = &gI2cConfig[i];
            /* Input parameter validation */
            if (handle->object != NULL)
            {
                /* Mark the object as available */
                handle->object->isOpen = (bool)false;
            }
        }
        /* Create driver lock */
        (void)SemaphoreP_constructMutex(&gI2cDrvObj.lockObj);
        gI2cDrvObj.lock = &gI2cDrvObj.lockObj;
    }
    
    void I2C_deinit(void)
    {
        /* Delete driver lock */
        if(NULL != gI2cDrvObj.lock)
        {
            SemaphoreP_destruct(&gI2cDrvObj.lockObj);
            gI2cDrvObj.lock = NULL;
        }
    }
    
    void I2C_Params_init(I2C_Params *params)
    {
        /* Input parameter validation */
        if (params != NULL)
        {
            *params = I2C_defaultParams;
        }
    }
    
    I2C_Handle I2C_open(uint32_t idx, const I2C_Params *params)
    {
        I2C_Handle          handle = NULL;
        I2C_Object          *object = NULL;
        I2C_HwAttrs const   *hwAttrs = NULL;
        I2CLLD_Handle       i2cLldHandle;
        int32_t             status = SystemP_SUCCESS;
        uint32_t            i;
    
        /* Check index */
        if(idx >= gI2cConfigNum)
        {
            status = SystemP_FAILURE;
        }
        else
        {
            handle = (I2C_Handle)&(gI2cConfig[idx]);
        }
    
        DebugP_assert(NULL != gI2cDrvObj.lock);
        (void)SemaphoreP_pend(&gI2cDrvObj.lockObj, SystemP_WAIT_FOREVER);
    
        if(SystemP_SUCCESS == status)
        {
            object = (I2C_Object*)handle->object;
            DebugP_assert(NULL != object);
            DebugP_assert(NULL != handle->hwAttrs);
            hwAttrs = (I2C_HwAttrs const *)handle->hwAttrs;
            if(true == object->isOpen)
            {
                /* Handle already opended */
                status = SystemP_FAILURE;
                handle = NULL;
            }
        }
    
        if (SystemP_SUCCESS == status)
        {
            /* Mark the handle as being used */
            object->isOpen = (bool)true;
            /* Store the I2C parameters */
            if (params == NULL) {
                /* No params passed in, so use the defaults */
                I2C_Params_init(&(object->i2cParams));
            }
            else {
                /* Copy the params contents */
                object->i2cParams = *params;
            }
    
            object->i2cLldHandle = &object->i2cLldObject;
            i2cLldHandle = object->i2cLldHandle;
    
            i2cLldHandle->baseAddr = handle->hwAttrs->baseAddr;
            i2cLldHandle->intrNum = handle->hwAttrs->intNum;
            i2cLldHandle->bitRate = object->i2cParams.bitRate;
            i2cLldHandle->funcClk = handle->hwAttrs->funcClk;
            for(i=0; i<I2C_MAX_NUM_OWN_TARGET_ADDR; i++)
            {
                i2cLldHandle->ownTargetAddr[i] = handle->hwAttrs->ownTargetAddr[i];
            }
            i2cLldHandle->state = I2C_STATE_RESET;
    
            i2cLldHandle->Clock_getTicks = ClockP_getTicks;
            i2cLldHandle->Clock_usecToTicks = ClockP_usecToTicks;
            i2cLldHandle->Clock_uSleep = ClockP_usleep;
    
            i2cLldHandle->targetTransferCompleteCallback = I2C_LLD_targetTransferCompleteCallback;
    
            if (true == hwAttrs->enableIntr)
            {
                i2cLldHandle->transferCompleteCallback = I2C_LLD_transferCompleteCallback;
    
                HwiP_Params hwiPrms;
    
                /* Initialize with defaults */
                HwiP_Params_init(&hwiPrms);
    
                /* Populate the interrupt parameters */
                hwiPrms.args = (void *)handle;
                hwiPrms.callback = &I2C_hwiFxn;
                /* Event going in to CPU */
                hwiPrms.eventId = (uint16_t)hwAttrs->eventId;
                hwiPrms.intNum = hwAttrs->intNum;
                hwiPrms.isPulse = 1;
                hwiPrms.priority = 4U;
                hwiPrms.isFIQ = 0;
    
                /* Register interrupts */
                status = HwiP_construct(&object->hwiObj,&hwiPrms);
                DebugP_assert(status==SystemP_SUCCESS);
            }
    
            /*
             * Construct thread safe handles for this I2C peripheral
             * Semaphore to provide exclusive access to the I2C peripheral
             */
            status = SemaphoreP_constructMutex(&object->mutex);
            DebugP_assert(status==SystemP_SUCCESS);
    
    
            if (object->i2cParams.transferMode == I2C_MODE_BLOCKING)
            {
                /*
                * Semaphore to cause the waiting task to block for the I2C
                * to finish
                */
                status = SemaphoreP_constructBinary(&object->transferComplete, 0);
                DebugP_assert(status==SystemP_SUCCESS);
    
                /* Store internal callback function */
                object->i2cParams.transferCallbackFxn = &I2C_transferCallback;
            }
    
            if(object->i2cParams.transferMode == I2C_MODE_CALLBACK)
            {
                if (params != NULL)
                {
                /* Save the callback function pointer */
                object->i2cParams.transferCallbackFxn = params->transferCallbackFxn;
                }
            }
    
            /* Clear the head pointer */
            object->headPtr = NULL;
            object->tailPtr = NULL;
    
            /* Initialize LLD driver */
            if(I2C_lld_init(i2cLldHandle) == I2C_STS_SUCCESS)
            {
                status = SystemP_SUCCESS;
                /* Store HLD handle insinde LLD Object */
                i2cLldHandle->args = handle;
                /* Specify the idle state for this I2C peripheral */
                object->state = I2C_STATE_IDLE;
            }
            else
            {
                status = SystemP_FAILURE;
            }
    
            DebugP_assert(status==SystemP_SUCCESS);
        }
    
        SemaphoreP_post(&gI2cDrvObj.lockObj);
        return (handle);
    }
    
    void I2C_close(I2C_Handle handle)
    {
        I2C_Object          *object = NULL;
        I2C_HwAttrs const   *hwAttrs = NULL;
        int32_t             status = SystemP_SUCCESS;
    
        /* Input parameter validation */
        if (handle != NULL)
        {
            /* Get the pointer to the object */
            object = (I2C_Object*)handle->object;
            hwAttrs = (I2C_HwAttrs const *)handle->hwAttrs;
    
            DebugP_assert(NULL != gI2cDrvObj.lock);
            (void)SemaphoreP_pend(&gI2cDrvObj.lockObj, SystemP_WAIT_FOREVER);
    
            /* Check to see if a I2C transaction is in progress */
            if (object->headPtr == NULL)
            {
                if(I2C_lld_deInit(object->i2cLldHandle) == I2C_STS_SUCCESS)
                {
                    status = SystemP_SUCCESS;
                }
                else
                {
                    status = SystemP_FAILURE;
                }
                DebugP_assert(status == SystemP_SUCCESS);
    
                if (true == hwAttrs->enableIntr)
                {
                    /* Destruct the Hwi */
                    (void)HwiP_destruct(&object->hwiObj);
                }
    
                /* Destruct the instance lock */
                (void)SemaphoreP_destruct(&object->mutex);
    
                if (I2C_MODE_BLOCKING == object->i2cParams.transferMode)
                {
                    /* Destruct the transfer completion lock */
                    (void)SemaphoreP_destruct(&object->transferComplete);
                }
    
                object->isOpen = (bool)false;
            }
            SemaphoreP_post(&gI2cDrvObj.lockObj);
        }
        return;
    }
    
    void I2C_Memory_Transaction_init(I2C_Mem_Transaction *memTransaction)
    {
        *memTransaction = I2C_defaultMemTransaction;
    }
    
    void I2C_Transaction_init(I2C_Transaction *transaction)
    {
        *transaction = I2C_defaultTransaction;
    }
    
    int32_t I2C_transfer(I2C_Handle handle,
                                I2C_Transaction *transaction)
    {
        int32_t             retVal = I2C_STS_ERR;
        uint8_t             ret_flag = 0U;
        uintptr_t           key;
        I2C_Object          *object = NULL;
        I2C_HwAttrs const   *hwAttrs = NULL;
    
        if ((handle != NULL) && (transaction != NULL))
        {
            /* Get the pointer to the object and hwAttrs */
            object = (I2C_Object*)handle->object;
            hwAttrs = (I2C_HwAttrs const *)handle->hwAttrs;
    
            if (transaction->timeout == 0U)
            {
                /* timeout cannot be NO_WAIT, set it to default value */
                transaction->timeout = SystemP_WAIT_FOREVER;
            }
        }
        else
        {
            ret_flag = 1U;
        }
    
        if ((ret_flag == 0U) && (   (transaction->writeCount != 0U)    ||
                                    (transaction->readCount != 0U)     ||
                                    (transaction->memTxnEnable == true)))
        {
            if (object->i2cParams.transferMode == I2C_MODE_CALLBACK)
            {
                /* Check if a transfer is in progress */
                key = HwiP_disable();
                if (object->headPtr != NULL)
                {
                    /* Transfer in progress. Update the message pointed by the tailPtr
                     * to point to the next message in the queue
                     */
                    object->tailPtr->nextPtr = transaction;
                    /* Update the tailPtr to point to the last message */
                    object->tailPtr = transaction;
                    /* I2C is still being used */
                    HwiP_restore(key);
                    retVal = I2C_STS_SUCCESS;
                    ret_flag = 1U;
                }
                else
                {
                    /* Store the headPtr indicating I2C is in use */
                    object->headPtr = transaction;
                    object->tailPtr = transaction;
                    HwiP_restore(key);
                }
            }
    
            if(ret_flag == 0U)
            {
                /* Acquire the lock for this particular I2C handle */
                (void)SemaphoreP_pend(&object->mutex, SystemP_WAIT_FOREVER);
    
                /*
                 * I2CSubArtic_primeTransfer is a longer process and
                 * protection is needed from the I2C interrupt
                 */
                if (true == hwAttrs->enableIntr)
                {
                    (void)HwiP_disableInt((uint32_t)hwAttrs->intNum);
                }
    
                /* Conditional statement for memory transaction and normal transaction */
                if(transaction->memTxnEnable)
                {
                    retVal = I2C_mem_primeTransfer(handle, transaction);
                }
                else
                {
                    retVal = I2C_primeTransfer(handle, transaction);
                }
    
                if (true == hwAttrs->enableIntr)
                {
                    (void)HwiP_enableInt((uint32_t)hwAttrs->intNum);
                }
    
                if ((retVal == I2C_STS_SUCCESS) &&
                    (object->i2cParams.transferMode == I2C_MODE_BLOCKING) &&
                    (true == hwAttrs->enableIntr))
                {
                    /*
                      * Wait for the transfer to complete here.
                      * It's OK to block from here because the I2C's Hwi will unblock
                      * upon errors
                      */
                    retVal = SemaphoreP_pend(   &object->transferComplete,
                                                transaction->timeout);
    
                    if ( retVal != SystemP_SUCCESS)
                    {
                        /* Transaction timed out or had some error in semaphore pend */
                        retVal = SystemP_TIMEOUT;
                        (void)I2C_recoverBus(handle, I2C_DELAY_SMALL);
                    }
                }
    
                /* Polling mode Case */
                if ((false == hwAttrs->enableIntr))
                {
                    transaction->status = retVal;
    
                    if(retVal == I2C_STS_SUCCESS)
                    {
                        retVal = SystemP_SUCCESS;
                    }
                    else if(retVal == I2C_STS_ERR_TIMEOUT)
                    {
                        retVal = SystemP_TIMEOUT;
                    }
                    else
                    {
                        retVal = SystemP_FAILURE;
                    }
                }
                /* Release the lock for this particular I2C handle */
                (void)SemaphoreP_post(&object->mutex);
            }
        }
    
        return (retVal);
    }
    
    int32_t I2C_probe(I2C_Handle handle, uint32_t targetAddr)
    {
        int32_t retVal = SystemP_FAILURE;
        I2C_Object *object = NULL;
        I2CLLD_Handle i2cLldHandle = NULL;
    
        if(NULL != handle)
        {
            object = (I2C_Object*)handle->object;
            i2cLldHandle = object->i2cLldHandle;
            /* Acquire the lock for this particular I2C handle */
            (void)SemaphoreP_pend(&object->mutex, SystemP_WAIT_FOREVER);
            /* Invoke LLD API */
            if(I2C_lld_probe(i2cLldHandle, targetAddr) == I2C_STS_SUCCESS)
            {
                retVal = SystemP_SUCCESS;
            }
            /* Release the lock for this particular I2C handle */
            (void)SemaphoreP_post(&object->mutex);
        }
        return (retVal);
    }
    
    int32_t I2C_setBusFrequency(I2C_Handle handle, uint32_t busFrequency)
    {
        int32_t retVal = SystemP_FAILURE;
        I2C_Object *object = NULL;
        I2CLLD_Handle i2cLldHandle = NULL;
    
        if(NULL != handle)
        {
            object = (I2C_Object*)handle->object;
            i2cLldHandle = object->i2cLldHandle;
            /* Acquire the lock for this particular I2C handle */
            (void)SemaphoreP_pend(&object->mutex, SystemP_WAIT_FOREVER);
            /* Invoke LLD API*/
            if(I2C_lld_setBusFrequency(i2cLldHandle, busFrequency) == I2C_STS_SUCCESS)
            {
                retVal = SystemP_SUCCESS;
            }
            /* Release the lock for this particular I2C handle */
            (void)SemaphoreP_post(&object->mutex);
        }
        return retVal;
    }
    
    int32_t I2C_recoverBus(I2C_Handle handle, uint32_t i2cDelay)
    {
        I2C_Object   *object = NULL;
        int32_t status = I2C_STS_SUCCESS;
    
        if(handle == NULL)
        {
            status = I2C_STS_ERR;
        }
    
        if(I2C_STS_SUCCESS == status)
        {
            object = (I2C_Object*)handle->object;
            if(object == NULL)
            {
                status = I2C_STS_ERR;
            }
        }
    
        if (I2C_STS_SUCCESS == status)
        {
            /* Acquire the lock for this particular I2C handle */
            (void)SemaphoreP_pend(&object->mutex, SystemP_WAIT_FOREVER);
    
            status = I2C_lld_recoverBus(object->i2cLldHandle, i2cDelay);
    
            /* Release the lock for this particular I2C handle */
            (void)SemaphoreP_post(&object->mutex);
        }
    
        if (status == I2C_STS_SUCCESS)
        {
            status = SystemP_SUCCESS;
        }
        else
        {
            status = SystemP_FAILURE;
        }
    
        return status;
    }
    
    I2C_Handle I2C_getHandle(uint32_t index)
    {
        I2C_Handle         handle = NULL;
        /* Check index */
        if(index < gI2cConfigNum)
        {
            I2C_Object *object;
    
            object = gI2cConfig[index].object;
            if((object != NULL) && ((bool)true == object->isOpen))
            {
                /* valid handle */
                handle = (I2C_Handle)&(gI2cConfig[index]);
            }
        }
    
        return handle;
    }
    
    /* ========================================================================== */
    /*                      Internal Function Definitions                         */
    /* ========================================================================== */
    
    static int32_t I2C_primeTransfer(   I2C_Handle handle,
                                        I2C_Transaction *transaction)
    {
        I2C_Object *object = NULL;
        I2C_HwAttrs const *hwAttrs = NULL;
    
        /* Get the pointer to the object and hwAttrs */
        object = (I2C_Object*)handle->object;
        hwAttrs = (I2C_HwAttrs const *)handle->hwAttrs;
    
        I2CLLD_Handle i2cLldHandle;
        i2cLldHandle = object->i2cLldHandle;
    
        int32_t status = I2C_STS_SUCCESS;
    
        /* Store the new internal counters and pointers */
        object->currentTransaction = transaction;
    
        /* Controller Mode */
        if(object->currentTransaction->controllerMode)
        {
            (void)I2C_lld_Transaction_init(&i2cLldHandle->i2ctxn);
            i2cLldHandle->i2ctxn.writeBuf = (uint8_t*)object->currentTransaction->writeBuf;
            i2cLldHandle->i2ctxn.writeCount = (uint32_t)object->currentTransaction->writeCount;
            i2cLldHandle->i2ctxn.readBuf = (uint8_t*)object->currentTransaction->readBuf;
            i2cLldHandle->i2ctxn.readCount = (uint32_t)object->currentTransaction->readCount;
    
            (void)I2C_lld_Message_init(&i2cLldHandle->i2cMsg);
            i2cLldHandle->i2cMsg.txn = &i2cLldHandle->i2ctxn;
            i2cLldHandle->i2cMsg.txnCount = 1U;
            i2cLldHandle->i2cMsg.targetAddress = object->currentTransaction->targetAddress;
            i2cLldHandle->i2cMsg.timeout = object->currentTransaction->timeout;
            i2cLldHandle->i2cMsg.expandSA = object->currentTransaction->expandSA;
    
            if (true == hwAttrs->enableIntr)
            {
                status = I2C_lld_transferIntr(i2cLldHandle, &(i2cLldHandle->i2cMsg));
            }
            else
            {
                status = I2C_lld_transferPoll(i2cLldHandle, &(i2cLldHandle->i2cMsg));
                object->currentTransaction->status = status;
            }
        }
    
        /* Target Mode */
        else
        {
            i2cLldHandle->i2cTargetTransaction.writeBuf = (uint8_t*)transaction->writeBuf;
            i2cLldHandle->i2cTargetTransaction.writeCount = (uint32_t)transaction->writeCount;
    
            i2cLldHandle->i2cTargetTransaction.readBuf = (uint8_t*)transaction->readBuf;
            i2cLldHandle->i2cTargetTransaction.readCount = (uint32_t)transaction->readCount;
    
            i2cLldHandle->i2cTargetTransaction.timeout = transaction->timeout;
            i2cLldHandle->i2cTargetTransaction.expandSA = transaction->expandSA;
    
            status = I2C_lld_targetTransferIntr(i2cLldHandle, &(i2cLldHandle->i2cTargetTransaction));
        }
    
        return status;
    }
    
    static int32_t I2C_mem_primeTransfer(   I2C_Handle handle,
                                            I2C_Transaction *transaction)
    {
        I2C_Object *object = NULL;
        I2C_HwAttrs const *hwAttrs = NULL;
    
        /* Get the pointer to the object and hwAttrs */
        object = (I2C_Object*)handle->object;
        hwAttrs = (I2C_HwAttrs const *)handle->hwAttrs;
    
        I2CLLD_Handle i2cLldHandle;
        i2cLldHandle = object->i2cLldHandle;
    
        int32_t status = I2C_STS_SUCCESS;
    
        object->currentTransaction = transaction;
    
        /* Store the new internal counters and pointers */
        /* Controller Mode */
        if(object->currentTransaction->controllerMode)
        {
    
            I2C_Memory_ExtendedParams mem_extendedParams;
    
            mem_extendedParams.memAddr =
                            object->currentTransaction->memTransaction->memAddr;
            mem_extendedParams.memAddrSize =
                            object->currentTransaction->memTransaction->memAddrSize;
    
    
    
            mem_extendedParams.extendedParams.deviceAddress =
                            object->currentTransaction->targetAddress;
            mem_extendedParams.extendedParams.buffer =
                            object->currentTransaction->memTransaction->buffer;
            mem_extendedParams.extendedParams.size =
                            object->currentTransaction->memTransaction->size;
            mem_extendedParams.extendedParams.expandSA =
                            object->currentTransaction->expandSA;
    
            /* INTERRUPT MODE */
            if (true == hwAttrs->enableIntr)
            {
                if(object->currentTransaction->memTransaction->memDataDir ==
                                                                I2C_MEM_TXN_DIR_TX)
                {
                    status = I2C_lld_mem_writeIntr(i2cLldHandle,
                                                            &mem_extendedParams);
                }
                else if(object->currentTransaction->memTransaction->memDataDir ==
                                                                I2C_MEM_TXN_DIR_RX)
                {
                    status = I2C_lld_mem_readIntr(i2cLldHandle,
                                                            &mem_extendedParams);
                }
                else
                {
                    status = I2C_STS_ERR_INVALID_PARAM;
                }
            }
            /* POLLING MODE */
            else
            {
                if(object->currentTransaction->memTransaction->memDataDir ==
                                                                I2C_MEM_TXN_DIR_TX)
                {
                    status = I2C_lld_mem_write(i2cLldHandle, &mem_extendedParams,
                                               object->currentTransaction->timeout);
                }
                else if(object->currentTransaction->memTransaction->memDataDir ==
                                                                I2C_MEM_TXN_DIR_RX)
                {
                    status = I2C_lld_mem_read(i2cLldHandle, &mem_extendedParams,
                                              object->currentTransaction->timeout);
                }
                else
                {
                    status = I2C_STS_ERR_INVALID_PARAM;
                }
            }
        }
    
        /* Target Mode */
        else
        {
            status = I2C_STS_ERR;
        }
    
        return status;
    }
    
    static inline void I2C_transferCallback(I2C_Handle handle,
                                            I2C_Transaction *msg,
                                            int32_t transferStatus)
    {
        I2C_Object *object;
    
        /* Input parameter validation */
        if ((handle != NULL) && (msg != NULL))
        {
            /* Get the pointer to the object */
            object = (I2C_Object *)handle->object;
            /* Indicate transfer complete */
            SemaphoreP_post(&object->transferComplete);
        }
    }
    
    static void I2C_completeCurrTransfer(I2C_Handle handle, int32_t xferStatus)
    {
        I2C_Object     *object = (I2C_Object*)handle->object;
    
        object->state = I2C_STATE_IDLE;
    
        if(object->currentTransaction != NULL)
        {
            object->currentTransaction->status = xferStatus;
            /* Callback to application or post semaphore */
            object->i2cParams.transferCallbackFxn(  handle,
                                                    object->currentTransaction,
                                                    xferStatus);
    
            /* See if we need to process any other transactions */
            if (object->headPtr == object->tailPtr)
            {
                /* No other transactions need to occur */
                object->currentTransaction = NULL;
                object->headPtr = NULL;
            }
            else
            {
            /* Another transfer needs to take place */
            object->headPtr = (I2C_Transaction*)(object->headPtr->nextPtr);
            /* Start new transfer */
            (void)I2C_primeTransfer(handle, object->headPtr);
            }
        }
    }
    
    /* LLD transfer complete callback called from LLD in Blocking Mode */
    static void I2C_LLD_transferCompleteCallback (void * args,
                                                  const I2CLLD_Message * msg,
                                                  int32_t transferStatus)
    {
        I2CLLD_Handle i2cLldHandle = (I2CLLD_Handle)args;
    
        if((NULL_PTR != i2cLldHandle) && (NULL_PTR != msg))
        {
            I2C_Handle i2cHldhandle = (I2C_Handle)i2cLldHandle->args;
    
            if(NULL != i2cHldhandle)
            {
                I2C_completeCurrTransfer(i2cHldhandle, transferStatus);
            }
        }
    }
    
    static void I2C_LLD_targetTransferCompleteCallback (void * args,
                                    const I2CLLD_targetTransaction * targetTxn,
                                    int32_t transferStatus)
    {
        I2CLLD_Handle   lldhandle = (I2CLLD_Handle)args;
        I2C_Config      *config;
        I2C_Object      *object;
    
        if((NULL_PTR != lldhandle) && (NULL_PTR != targetTxn))
        {
            I2C_Handle hldhandle = (I2C_Handle)lldhandle->args;
    
            config = (I2C_Config *) hldhandle;
            object = config->object;
    
            if(NULL != hldhandle)
            {
                // if((object->i2cParams.transferMode) == I2C_MODE_CALLBACK)
                // {
                I2C_completeCurrTransfer(hldhandle, transferStatus);
    
                (void)SemaphoreP_post(&object->mutex);
                    // object->currentTransaction->status = transferStatus;
                    // object->i2cParams.transferCallbackFxn(hldhandle,
                    //                                     object->currentTransaction,
                    //                                     transferStatus);
                // }
                // else
                // {
                    /* No Code */
                // }
            }
        }
    }
    
    static void I2C_hwiFxn(void* arg)
    {
        I2C_Handle      handle = (I2C_Handle)arg;
        I2C_Object      *object = NULL;
    
        /* Input parameter validation */
        if (handle != NULL)
        {
            /* Get the pointer to the object */
            object = (I2C_Object *)handle->object;
    
            if (object->currentTransaction->controllerMode)
            {
                I2C_lld_controllerIsr(object->i2cLldHandle);
            }
            else
            {
                I2C_lld_targetIsr(object->i2cLldHandle);
            }
        }
        return;
    }
    
    

    Please make the necessary changes, rebuild the drivers and let me know if this resolves the issue for Slave functionality.

    Looking forward to your response, alternatively mark the answer resolved if it helps with your query.

    Regards,

    Vaibhav

  • Congratulations, we found a compilation issue after synchronizing the code here. It should be that the corresponding header file was not provided

    like

    #include <drivers/i2c/v0/lld/i2c_lld.h>

    or -g -Wno-gnu-variable-sized-type-not-at-end -Wno-unused-function  -Os  -I/extstorage/zyk/ti_am/git/sdk0806-bak/mcu_plus_sdk_am62ax_08_06_00_18/../tools/ti-cgt-armllvm_2.1.2.LTS/include/c -I/extstorage/zyk/ti_am/git/sdk0806-bak/mcu_plus_sdk_am62ax_08_06_00_18/source   -DSOC_AM62AX   -MMD -o obj/am62ax/ti-arm-clang/release/r5f/drivers//i2c_v0.obj i2c/v0/i2c_v0.c
    Compiling: drivers.am62ax.dm-r5f.ti-arm-clang.release.lib: i2c/v0/i2c_v0.c
    make[3]: Nothing to be done for 'all'.
    make[3]: Leaving directory '/extstorage/zyk/ti_am/git/sdk0806-bak/mcu_plus_sdk_am62ax_08_06_00_18/source/kernel/freertos'
    make[3]: Nothing to be done for 'all'.
    make[3]: Leaving directory '/extstorage/zyk/ti_am/git/sdk0806-bak/mcu_plus_sdk_am62ax_08_06_00_18/source/kernel/freertos'
    /extstorage/zyk/ti_am/git/sdk0806-bak/mcu_plus_sdk_am62ax_08_06_00_18/../tools/ti-cgt-armllvm_2.1.2.LTS/bin/tiarmclang -c -mcpu=cortex-r5 -mfloat-abi=hard -mfpu=vfpv3-d16 -mthumb -Wall -Werror -g -Wno-gnu-variable-sized-type-not-at-end -Wno-unused-function  -Os  -I/extstorage/zyk/ti_am/git/sdk0806-bak/mcu_plus_sdk_am62ax_08_06_00_18/../tools/ti-cgt-armllvm_2.1.2.LTS/include/c -I/extstorage/zyk/ti_am/git/sdk0806-bak/mcu_plus_sdk_am62ax_08_06_00_18/source   -DSOC_AM62AX -DENABLE_SCICLIENT_DIRECT   -MMD -o obj/am62ax/ti-arm-clang/release/dm-r5f/drivers//i2c_v0.obj i2c/v0/i2c_v0.c
    i2c/v0/i2c_v0.c:86:7: error: unknown type name 'I2C_Mem_Transaction'; did you mean 'I2C_Transaction'?
    const I2C_Mem_Transaction I2C_defaultMemTransaction = {
          ^~~~~~~~~~~~~~~~~~~
          I2C_Transaction
    /extstorage/zyk/ti_am/git/sdk0806-bak/mcu_plus_sdk_am62ax_08_06_00_18/source/drivers/i2c/v0/i2c.h:263:3: note: 'I2C_Transaction' declared here
    } I2C_Transaction;
      ^
    i2c/v0/i2c_v0.c:89:5: error: use of undeclared identifier 'I2C_MEM_ADDR_SIZE_8_BITS'
        I2C_MEM_ADDR_SIZE_8_BITS,       /* memAddrSize */
        ^
    i2c/v0/i2c_v0.c:92:5: error: use of undeclared identifier 'I2C_MEM_TXN_DIR_INVALID'
        I2C_MEM_TXN_DIR_INVALID         /* memDataDir */
        ^
    i2c/v0/i2c_v0.c:108:5: error: excess elements in struct initializer [-Werror,-Wexcess-initializers]
        (bool)false,                    /* memTxnEnable */
        ^~~~~~~~~~~
    i2c/v0/i2c_v0.c:125:52: error: unknown type name 'I2CLLD_Message'
                                                 const I2CLLD_Message * msg,
                                                       ^
    i2c/v0/i2c_v0.c:86:7: error: unknown type name 'I2C_Mem_Transaction'; did you mean 'I2C_Transaction'?
    const I2C_Mem_Transaction I2C_defaultMemTransaction = {
          ^~~~~~~~~~~~~~~~~~~
          I2C_Transaction
    /extstorage/zyk/ti_am/git/sdk0806-bak/mcu_plus_sdk_am62ax_08_06_00_18/source/drivers/i2c/v0/i2c.h:263:3: note: 'I2C_Transaction' declared here
    } I2C_Transaction;
      ^
    i2c/v0/i2c_v0.c:129:43: error: unknown type name 'I2CLLD_targetTransaction'
                                        const I2CLLD_targetTransaction * targetTxn,
                                              ^
    i2c/v0/i2c_v0.c:204:5: error: unknown type name 'I2CLLD_Handle'; did you mean 'I2C_Handle'?
        I2CLLD_Handle       i2cLldHandle;
        ^~~~~~~~~~~~~
        I2C_Handle
    /extstorage/zyk/ti_am/git/sdk0806-bak/mcu_plus_sdk_am62ax_08_06_00_18/source/drivers/i2c/v0/i2c.h:175:35: note: 'I2C_Handle' declared here
    typedef struct I2C_Config_s      *I2C_Handle;
                                      ^
    i2c/v0/i2c_v0.c:249:17: error: no member named 'i2cLldHandle' in 'struct I2C_Object_s'
            object->i2cLldHandle = &object->i2cLldObject;
            ~~~~~~  ^
    i2c/v0/i2c_v0.c:249:41: error: no member named 'i2cLldObject' in 'struct I2C_Object_s'
            object->i2cLldHandle = &object->i2cLldObject;
                                    ~~~~~~  ^
    i2c/v0/i2c_v0.c:250:32: error: no member named 'i2cLldHandle' in 'struct I2C_Object_s'
            i2cLldHandle = object->i2cLldHandle;
                           ~~~~~~  ^
    i2c/v0/i2c_v0.c:252:23: error: no member named 'baseAddr' in 'struct I2C_Config_s'
            i2cLldHandle->baseAddr = handle->hwAttrs->baseAddr;
            ~~~~~~~~~~~~  ^
    i2c/v0/i2c_v0.c:253:23: error: no member named 'intrNum' in 'struct I2C_Config_s'
            i2cLldHandle->intrNum = handle->hwAttrs->intNum;
            ~~~~~~~~~~~~  ^
    i2c/v0/i2c_v0.c:254:23: error: no member named 'bitRate' in 'struct I2C_Config_s'
            i2cLldHandle->bitRate = object->i2cParams.bitRate;
            ~~~~~~~~~~~~  ^
    i2c/v0/i2c_v0.c:255:23: error: no member named 'funcClk' in 'struct I2C_Config_s'
            i2cLldHandle->funcClk = handle->hwAttrs->funcClk;
            ~~~~~~~~~~~~  ^
    i2c/v0/i2c_v0.c:89:5: error: use of undeclared identifier 'I2C_MEM_ADDR_SIZE_8_BITS'
        I2C_MEM_ADDR_SIZE_8_BITS,       /* memAddrSize */
        ^
    i2c/v0/i2c_v0.c:92:5: error: use of undeclared identifier 'I2C_MEM_TXN_DIR_INVALID'
        I2C_MEM_TXN_DIR_INVALID         /* memDataDir */
        ^
    i2c/v0/i2c_v0.c:108:5: error: excess elements in struct initializer [-Werror,-Wexcess-initializers]
        (bool)false,                    /* memTxnEnable */
        ^~~~~~~~~~~
    i2c/v0/i2c_v0.c:125:52: error: unknown type name 'I2CLLD_Message'
                                                 const I2CLLD_Message * msg,
                                                       ^
    i2c/v0/i2c_v0.c:256:20: error: use of undeclared identifier 'I2C_MAX_NUM_OWN_TARGET_ADDR'
            for(i=0; i<I2C_MAX_NUM_OWN_TARGET_ADDR; i++)
                       ^
    i2c/v0/i2c_v0.c:258:27: error: no member named 'ownTargetAddr' in 'struct I2C_Config_s'
                i2cLldHandle->ownTargetAddr[i] = handle->hwAttrs->ownTargetAddr[i];
                ~~~~~~~~~~~~  ^
    i2c/v0/i2c_v0.c:258:63: error: no member named 'ownTargetAddr' in 'struct I2C_HwAttrs_s'
                i2cLldHandle->ownTargetAddr[i] = handle->hwAttrs->ownTargetAddr[i];
                                                 ~~~~~~~~~~~~~~~  ^
    i2c/v0/i2c_v0.c:260:23: error: no member named 'state' in 'struct I2C_Config_s'
            i2cLldHandle->state = I2C_STATE_RESET;
            ~~~~~~~~~~~~  ^
    i2c/v0/i2c_v0.c:260:31: error: use of undeclared identifier 'I2C_STATE_RESET'
            i2cLldHandle->state = I2C_STATE_RESET;
                                  ^
    fatal error: too many errors emitted, stopping now [-ferror-limit=]
    i2c/v0/i2c_v0.c:129:43: error: unknown type name 'I2CLLD_targetTransaction'
                                        const I2CLLD_targetTransaction * targetTxn,
                                              ^
    20 errors generated.
    i2c/v0/i2c_v0.c:204:5: error: unknown type name 'I2CLLD_Handle'; did you mean 'I2C_Handle'?
        I2CLLD_Handle       i2cLldHandle;
        ^~~~~~~~~~~~~
        I2C_Handle
    /extstorage/zyk/ti_am/git/sdk0806-bak/mcu_plus_sdk_am62ax_08_06_00_18/source/drivers/i2c/v0/i2c.h:175:35: note: 'I2C_Handle' declared here
    typedef struct I2C_Config_s      *I2C_Handle;
                                      ^
    i2c/v0/i2c_v0.c:249:17: error: no member named 'i2cLldHandle' in 'struct I2C_Object_s'
            object->i2cLldHandle = &object->i2cLldObject;
            ~~~~~~  ^
    i2c/v0/i2c_v0.c:249:41: error: no member named 'i2cLldObject' in 'struct I2C_Object_s'
            object->i2cLldHandle = &object->i2cLldObject;
                                    ~~~~~~  ^
    i2c/v0/i2c_v0.c:250:32: error: no member named 'i2cLldHandle' in 'struct I2C_Object_s'
            i2cLldHandle = object->i2cLldHandle;
                           ~~~~~~  ^
    i2c/v0/i2c_v0.c:252:23: error: no member named 'baseAddr' in 'struct I2C_Config_s'
            i2cLldHandle->baseAddr = handle->hwAttrs->baseAddr;
            ~~~~~~~~~~~~  ^
    i2c/v0/i2c_v0.c:253:23: error: no member named 'intrNum' in 'struct I2C_Config_s'
    make[3]: *** [makefile.am62ax.r5f.ti-arm-clang:166: i2c_v0.obj] Error 1
            i2cLldHandle->intrNum = handle->hwAttrs->intNum;
            ~~~~~~~~~~~~  ^
    make[3]: Leaving directory '/extstorage/zyk/ti_am/git/sdk0806-bak/mcu_plus_sdk_am62ax_08_06_00_18/source/drivers'
    i2c/v0/i2c_v0.c:254:23: error: no member named 'bitRate' in 'struct I2C_Config_s'
            i2cLldHandle->bitRate = object->i2cParams.bitRate;
            ~~~~~~~~~~~~  ^
    i2c/v0/i2c_v0.c:255:23: error: no member named 'funcClk' in 'struct I2C_Config_s'
            i2cLldHandle->funcClk = handle->hwAttrs->funcClk;
            ~~~~~~~~~~~~  ^
    make[2]: *** [makefile.am62ax:169: drivers_r5f.ti-arm-clang] Error 2
    make[2]: *** Waiting for unfinished jobs....
    i2c/v0/i2c_v0.c:256:20: error: use of undeclared identifier 'I2C_MAX_NUM_OWN_TARGET_ADDR'
            for(i=0; i<I2C_MAX_NUM_OWN_TARGET_ADDR; i++)
                       ^
    i2c/v0/i2c_v0.c:258:27: error: no member named 'ownTargetAddr' in 'struct I2C_Config_s'
                i2cLldHandle->ownTargetAddr[i] = handle->hwAttrs->ownTargetAddr[i];
                ~~~~~~~~~~~~  ^
    i2c/v0/i2c_v0.c:258:63: error: no member named 'ownTargetAddr' in 'struct I2C_HwAttrs_s'
                i2cLldHandle->ownTargetAddr[i] = handle->hwAttrs->ownTargetAddr[i];
                                                 ~~~~~~~~~~~~~~~  ^
    i2c/v0/i2c_v0.c:260:23: error: no member named 'state' in 'struct I2C_Config_s'
            i2cLldHandle->state = I2C_STATE_RESET;
            ~~~~~~~~~~~~  ^
    i2c/v0/i2c_v0.c:260:31: error: use of undeclared identifier 'I2C_STATE_RESET'
            i2cLldHandle->state = I2C_STATE_RESET;
                                  ^
    fatal error: too many errors emitted, stopping now [-ferror-limit=]
    20 errors generated.
    make[3]: *** [makefile.am62ax.dm-r5f.ti-arm-clang:180: i2c_v0.obj] Error 1
    make[3]: Leaving directory '/extstorage/zyk/ti_am/git/sdk0806-bak/mcu_plus_sdk_am62ax_08_06_00_18/source/drivers'
    make[2]: *** [makefile.am62ax:169: drivers_dm-r5f.ti-arm-clang] Error 2
    make[3]: Nothing to be done for 'all'.
    make[3]: Leaving directory '/extstorage/zyk/ti_am/git/sdk0806-bak/mcu_plus_sdk_am62ax_08_06_00_18/source/drivers/device_manager/rm_pm_hal'
    make[3]: Nothing to be done for 'all'.
    make[3]: Leaving directory '/extstorage/zyk/ti_am/git/sdk0806-bak/mcu_plus_sdk_am62ax_08_06_00_18/source/drivers/device_manager/rm_pm_hal/sbl'
    make[2]: Leaving directory '/extstorage/zyk/ti_am/git/sdk0806-bak/mcu_plus_sdk_am62ax_08_06_00_18'
    make[1]: *** [makefile.am62ax:6: all] Error 2
    make[1]: Leaving directory '/extstorage/zyk/ti_am/git/sdk0806-bak/mcu_plus_sdk_am62ax_08_06_00_18'
    make: *** [makefile:56: all] Error 2
    zyk@aitronx-System-Product-Name:~/ti_am/git/sdk0806-bak/mcu_plus_sdk_am62ax_08_06_00_18$ sudo make -j git diff^
    Could you please check which other code needs to be synchronized to ensure that it can be compiled and passed

  • Hello Wu,

    I realized that I did this on AM243x as a demonstration to check for slave working fine. So safe to say the above files I gave are going to work completely fine for AM243x.

    I will check an equivalent for this on AM62A and send the file to you along with the example.

    I appreciate your patience on this and I look forward to providing you the replication for AM62A.

    Regards,

    Vaibhav

  • Thank you for your support. This feature has been adjusted and it will also benefit your product for a win-win situation

    Expected to support this feature on am62a

    thx

  • Greetings Wu,

    Thanks for your patience.

    This feature has been adjusted and it will also benefit your product for a win-win situation

    That is correct.

    I have the AM62A Slave Code ready and turns out there was no need to change the drivers, just the slave application code change was enough.

    Note, that my setup is as follows. Please check the attached diagram.

    So my Controller is SoC_I2C0 of the AM243-LP and Peripheral is MCU_I2C0 of the AM62A(as per your requirement).

    I am attaching the code for the MCU_I2C0 slave/peripheral application.

    Here you go:

     0647.empty_am62ax-sk_mcu-r5fss0-0_nortos_ti-arm-clang.zip

    Note, there are no changes in the driver as of now for AM62A atleast.

    Looking forward to your test results.

    Regards,

    Vaibhav

  • We can detect 0x49, which is our slave address, but when trying to read and write, an error occurred. Master i2c is on the Linux side

    May I ask what the specific i2c format is? Please verify that I made a mistake in the format on my end

    while true;do i2cset -f -y 2 0x49 0x0 0x1;sleep 1; i2cget -f -y 2 0x49 0x40;sleep 1;done;

    root@am62axx-evm:~#       i2cget -f -y 2 0x49 0x0
    0x06
    root@am62axx-evm:~#       i2cget -f -y 2 0x49 0x0
    [   37.191684] omap_i2c 20020000.i2c: controller timed out
    Error: Read failed

  • Greetings Wu,

    Slave has been identified on A72, there are a few issues,a new address was found in A72 i2c2, but when attempting to read or write, a timeout class printing occurred

    The slave should be at the address 0x1C itself as seen in the earlier screenshot sent by you. This is because MCU_I2C0 is at 0x1C slave address.

    Can you please check why 0x49 is showing up?

    Regards,

    Vaibhav

  • We have configured 0x49 in the configuration file

    examples/drivers/ipc/ipc_rpmsg_echo_linux/am62ax-sk/mcu-r5fss0-0_freertos/example.syscfg

    i2c1.ownSlaveAddr1 = 0x49;
    
    

    Confirm that it is the address of this mcu1-0 i2c1 (which we refer to as i2c1 slave),

    We have modified it to be the same as your address, which is 0x1c, and the situation is the same

  • Hello Wu,

    I also want to make sure you are running the slave application first and then the Controller commands are being initiated over the kernel.

    examples/drivers/ipc/ipc_rpmsg_echo_linux/am62ax-sk/mcu-r5fss0-0_freertos

    Can you please attach the project file here? I would like to go through the same.

    Regards,

    Vaibhav

  • I also want to make sure you are running the slave application first and then the Controller commands are being initiated over the kernel. Exclamation Arrows counterclockwise

    I will enter the password after the slave wakes up, and now even the i2cdelete action on this side will get stuck

    The printing of i2c on the left and center below only includes debugging information for printing

    ipc_rpmsg_echo_linux.tar.gz

  • Hello Wu,

    Thank you for attaching the file.

    I am going to go through it and follow up with you in few business days.

    Regards,

    Vaibhav

  • ok, Thank you for your support

  • Hi Wu,

    Thank you for your patience. 
    Please expect responses in sometime..

    Regards,

    Vaibhav

  • Greetings Wu,

    Thank you for your patience.

    I have gone through the attached code and the sysconfig file you sent me.

    So the following is my understanding.

    • MCU_I2Cx is the peripheral and MAIN_I2Cx is the controller.
    • If this is the case, and then you are controlling the master from the kernel space with the i2c commands, then the master need not be defined on MCU PLUS SDK side of story.
    • I am saying this because I see that your sysconfig file has declaration of MAIN_I2Cx as the controller, but your sysconfig should only have MCU_I2Cx as declaration.
    • Attaching the relevant section.

    Now I would like to have your dts file where Main Domain I2C1 side of story is defined. This will help me debug your problem faster.

    Looking forward to your response.


    Regards,

    Vaibhav

  • i2c2 main is master control,i2c1 slave is disable(linux disabled) is on mcu1-0

    &main_i2c1 {
    	status = "disabled";
    	pinctrl-names = "default";
    	pinctrl-0 = <&main_i2c1_pins_default>;
    	clock-frequency = <100000>;
    
    	exp1: gpio@22 {
    		compatible = "ti,tca6424";
    		reg = <0x22>;
    		gpio-controller;
    		#gpio-cells = <2>;
    		status = "disabled";

    	main_i2c1: i2c@20010000 {
    		compatible = "ti,am64-i2c", "ti,omap4-i2c";
    		reg = <0x00 0x20010000 0x00 0x100>;
    		interrupts = <GIC_SPI 162 IRQ_TYPE_LEVEL_HIGH>;
    		#address-cells = <1>;
    		#size-cells = <0>;
    		power-domains = <&k3_pds 103 TI_SCI_PD_EXCLUSIVE>;
    		clocks = <&k3_clks 103 2>;
    		clock-names = "fck";
    		status = "disabled";
    	};

    you can see below no i2c1  main  controller open (slave )

    # dmesg|grep i2c
    [    0.790946] i2c /dev entries driver
    [    0.907042] omap_i2c 2b200000.i2c: bus 0 rev0.12 at 400 kHz
    [    0.914210] omap_i2c 20000000.i2c: bus 1 rev0.12 at 400 kHz
    [    0.921157] omap_i2c 20020000.i2c: bus 2 rev0.12 at 400 kHz

    U also can see below send command to shell,it read ok at the first time,but second is fail.

    root@am62axx-evm:~# [  130.101163] Initializing XFRM netlink socket
    
    root@am62axx-evm:~# i2cdetect -r -y 2
         0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
    00:          -- -- -- -- -- -- -- -- -- -- -- -- -- 
    10: -- -- -- -- -- -- -- -- -- -- -- -- 1c -- -- -- 
    20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
    30: UU -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
    40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
    50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
    60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
    70: -- -- -- -- -- -- -- --                         
    root@am62axx-evm:~#       i2cget -f -y 2 0x1c 0x40
    0x06
    root@am62axx-evm:~#       i2cget -f -y 2 0x1c 0x40
    [  254.849582] omap_i2c 20020000.i2c: controller timed out
    Error: Read failed

  • Greetings Wu,

    Thank you for providing the device tree source files for main i2c1(slave).

    i2c2 main is master control

    I would also like to see all the instances/declarations of main i2c2(master) in the device tree source files.

    Few more things I want to get clarification on: Why are there two I2C instances defined in SysConfig? This is from the sysconfig file you sent me.

    One I understand is slave but what about the other one?

    Looking forward to your response.

    Regards,

    Vaibhav

  • The instance of i2c0 has been deleted here, and the phenomenon is the same

    root@am62axx-evm:~# i2cdetect -r -y 2
    0 1 2 3 4 5 6 7 8 9 a b c d e f
    00: -- -- -- -- -- -- -- -- -- -- -- -- --
    10: -- -- -- -- -- -- -- -- -- -- -- -- 1c -- -- --
    20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
    30: UU -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
    40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
    50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
    60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
    70: -- -- -- -- -- -- -- --
    root@am62axx-evm:~# i2cget -f -y 2 0x1c 0x40
    0x06
    root@am62axx-evm:~# i2cget -f -y 2 0x1c 0x40
    [ 56.257577] omap_i2c 20020000.i2c: controller timed out
    Error: Read failed

  • Hello Wu,

    Thank you for your response.

    I would also like to see all the instances/declarations of main i2c2(master) in the device tree source files.

    Can you send me the following.

    Looking forward to your response.

    Regards,

    Vaibhav

  • // SPDX-License-Identifier: GPL-2.0
    /*
     * AM62A SK: https://www.ti.com/lit/zip/sprr459
     *
     * Copyright (C) 2022 Texas Instruments Incorporated - https://www.ti.com/
     */
    
    /dts-v1/;
    
    #include <dt-bindings/leds/common.h>
    #include <dt-bindings/gpio/gpio.h>
    #include <dt-bindings/net/ti-dp83867.h>
    #include "k3-am62a7.dtsi"
    
    / {
    	compatible =  "ti,am62a7-sk", "ti,am62a7";
    	model = "Texas Instruments AM62A7 SK";
    
    	aliases {
    		serial1 = &wkup_uart0;
    		serial2 = &main_uart0;
    		mmc0 = &sdhci0;
    		mmc1 = &sdhci1;
    		ethernet0 = &cpsw_port1;
    	};
    
    	chosen {
    		stdout-path = "serial2:115200n8";
    	};
    
    	memory@80000000 {
    		device_type = "memory";
    		/* 4G RAM */
    		reg = <0x00000000 0x80000000 0x00000000 0x80000000>,
    		      <0x00000008 0x80000000 0x00000000 0x80000000>;
    	};
    
    	dma_buf_phys {
    		compatible = "ti,dma-buf-phys";
    	};
    
    	reserved-memory {
    		#address-cells = <2>;
    		#size-cells = <2>;
    		ranges;
    
    		secure_tfa_ddr: tfa@9e780000 {
    			reg = <0x00 0x9e780000 0x00 0x80000>;
    			alignment = <0x1000>;
    			no-map;
    		};
    
    		secure_ddr: optee@9e800000 {
    			reg = <0x00 0x9e800000 0x00 0x01800000>; /* for OP-TEE */
    			alignment = <0x1000>;
    			no-map;
    		};
    
    		wkup_r5fss0_core0_dma_memory_region: r5f-dma-memory@9c800000 {
    			compatible = "shared-dma-pool";
    			reg = <0x00 0x9c800000 0x00 0x100000>;
    			no-map;
    		};
    
    		wkup_r5fss0_core0_memory_region: r5f-dma-memory@9c900000 {
    			compatible = "shared-dma-pool";
    			reg = <0x00 0x9c900000 0x00 0x01e00000>;
    			no-map;
    		};
    
    		mcu_r5fss0_core0_dma_memory_region: r5f-dma-memory@9b800000 {
    			compatible = "shared-dma-pool";
    			reg = <0x00 0x9b800000 0x00 0x100000>;
    			no-map;
    		};
    
    		mcu_r5fss0_core0_memory_region: r5f-dma-memory@9b900000 {
    			compatible = "shared-dma-pool";
    			reg = <0x00 0x9b900000 0x00 0x0f00000>;
    			no-map;
    		};
    
    		c7x_0_dma_memory_region: c7x-dma-memory@99800000 {
    			compatible = "shared-dma-pool";
    			reg = <0x00 0x99800000 0x00 0x100000>;
    			no-map;
    		};
    
    		c7x_0_memory_region: c7x-memory@99900000 {
    			compatible = "shared-dma-pool";
    			reg = <0x00 0x99900000 0x00 0x01efffff>;
    			no-map;
    		};
    
    		edgeai_rtos_ipc_memory_region: edgeai-rtos-ipc-memory-region {
    			reg = <0x00 0xa0000000 0x00 0x01000000>;
    			no-map;
    		};
    
    		edgeai_memory_region: edgeai-dma-memory@a1000000 {
    			compatible = "shared-dma-pool";
    			reg = <0x00 0xa1000000 0x00 0x02000000>;
    			no-map;
    		};
    
    		edgeai_shared_region: edgeai_shared-memories {
    			compatible = "dma-heap-carveout";
    			reg = <0x00 0xa3000000 0x00 0x0b000000>;
    		};
    
    		edgeai_core_heaps: edgeai-core-heap-memory@ae000000 {
    			compatible = "shared-dma-pool";
    			reg = <0x00 0xae000000 0x00 0x12000000>;
    			no-map;
    		};
    	};
    
    	vmain_pd: regulator-0 {
    		/* TPS25750 PD CONTROLLER OUTPUT */
    		compatible = "regulator-fixed";
    		regulator-name = "vmain_pd";
    		regulator-min-microvolt = <5000000>;
    		regulator-max-microvolt = <5000000>;
    		regulator-always-on;
    		regulator-boot-on;
    	};
    
    	vcc_5v0: regulator-1 {
    		/* Output of TPS63070 */
    		compatible = "regulator-fixed";
    		regulator-name = "vcc_5v0";
    		regulator-min-microvolt = <5000000>;
    		regulator-max-microvolt = <5000000>;
    		vin-supply = <&vmain_pd>;
    		regulator-always-on;
    		regulator-boot-on;
    	};
    
    	vcc_3v3_main: regulator-2 {
    		/* output of LM5141-Q1 */
    		compatible = "regulator-fixed";
    		regulator-name = "vcc_3v3_main";
    		regulator-min-microvolt = <3300000>;
    		regulator-max-microvolt = <3300000>;
    		vin-supply = <&vmain_pd>;
    		regulator-always-on;
    		regulator-boot-on;
    	};
    
    	vdd_mmc1: regulator-3 {
    		/* TPS22918DBVR */
    		compatible = "regulator-fixed";
    		regulator-name = "vdd_mmc1";
    		regulator-min-microvolt = <3300000>;
    		regulator-max-microvolt = <3300000>;
    		regulator-boot-on;
    		enable-active-high;
    	//	gpio = <&exp1 3 GPIO_ACTIVE_HIGH>;
    	};
    
    	vcc_3v3_sys: regulator-4 {
    		/* output of TPS222965DSGT */
    		compatible = "regulator-fixed";
    		regulator-name = "vcc_3v3_sys";
    		regulator-min-microvolt = <3300000>;
    		regulator-max-microvolt = <3300000>;
    		vin-supply = <&vcc_3v3_main>;
    		regulator-always-on;
    		regulator-boot-on;
    	};
    	vddshv_sdio: regulator-5 {
    		compatible = "regulator-gpio";
    		regulator-name = "vddshv_sdio";
    		pinctrl-names = "default";
    		pinctrl-0 = <&vddshv_sdio_pins_default>;
    		regulator-min-microvolt = <1800000>;
    		regulator-max-microvolt = <3300000>;
    		regulator-boot-on;
    		vin-supply = <&ldo1>;
    		gpios = <&main_gpio0 31 GPIO_ACTIVE_HIGH>;
    		states = <1800000 0x0>,
    			 <3300000 0x1>;
    	};
    	leds {
    		compatible = "gpio-leds";
    		pinctrl-names = "default";
    		pinctrl-0 = <&usr_led_pins_default>;
    
    		led-0 {
    			label = "am62a-sk:green:heartbeat";
    			gpios = <&main_gpio1 49 GPIO_ACTIVE_HIGH>;
    			linux,default-trigger = "heartbeat";
    			function = LED_FUNCTION_HEARTBEAT;
    			default-state = "off";
    		};
    	};
    
    	hdmi_mstrclk: hdmi-mstrclk {
    		compatible = "fixed-clock";
    		#clock-cells = <0>;
    		clock-frequency = <12288000>;
    	};
    
    	tlv320_mclk: clk-0 {
    		#clock-cells = <0>;
    		compatible = "fixed-clock";
    		clock-frequency = <12288000>;
    	};
    
    	codec_audio: sound {
    		compatible = "simple-audio-card";
    		simple-audio-card,name = "AM62Ax-SKEVM";
    		simple-audio-card,widgets =
    			"Headphone",	"Headphone Jack",
    			"Line",	"Line In",
    			"Microphone",	"Microphone Jack";
    		simple-audio-card,routing =
    			"Headphone Jack",	"HPLOUT",
    			"Headphone Jack",	"HPROUT",
    			"LINE1L",		"Line In",
    			"LINE1R",		"Line In",
    			"MIC3R",		"Microphone Jack",
    			"Microphone Jack",	"Mic Bias";
    		simple-audio-card,format = "dsp_b";
    		simple-audio-card,bitclock-master = <&sound_master>;
    		simple-audio-card,frame-master = <&sound_master>;
    		simple-audio-card,bitclock-inversion;
    
    		simple-audio-card,cpu {
    			sound-dai = <&mcasp1>;
    		};
    
    		sound_master: simple-audio-card,codec {
    			sound-dai = <&tlv320aic3106>;
    			clocks = <&tlv320_mclk>;
    		};
    	};
    
    	hdmi: connector {
    		compatible = "hdmi-connector";
    		label = "hdmi";
    		type = "a";
    /*		port {
    			hdmi_connector_in: endpoint {
    				remote-endpoint = <&sii9022_out>;
    			};
    		};*/
    	};
    	transceiver1: can-phy0 {
    		compatible = "ti,tcan1042";//"bosch,m_can";
    		#phy-cells = <0>;
    		max-bitrate = <5000000>;
    	};
    	transceiver2: can-phy1 {
    		compatible = "ti,tcan1042";//"bosch,m_can";
    		#phy-cells = <0>;
    		max-bitrate = <5000000>;
    	//		pinctrl-names = "default";
    	//		pinctrl-0 = <&main_mcan0_gpio_pins_default>;
    	//		standby-gpios = <&main_gpio0 65 GPIO_ACTIVE_HIGH>;
    	};
    
    	transceiver3: can-phy2 {
    	compatible = "ti,tcan1042";//"bosch,m_can";
    	#phy-cells = <0>;
    	max-bitrate = <5000000>;
    	//		pinctrl-names = "default";
    	//		pinctrl-0 = <&main_mcan5_gpio_pins_default>;
    	//		standby-gpios = <&main_gpio0 66 GPIO_ACTIVE_HIGH>;
    	};
    };
    
    &main_pmx0 {
    	main_uart0_pins_default: main-uart0-pins-default {
    		pinctrl-single,pins = <
    			AM62AX_IOPAD(0x1c8, PIN_INPUT, 0) /* (D14) UART0_RXD */
    			AM62AX_IOPAD(0x1cc, PIN_OUTPUT, 0) /* (E14) UART0_TXD */
    		>;
    	};
    
    	main_i2c0_pins_default: main-i2c0-pins-default {
    		pinctrl-single,pins = <
    			AM62AX_IOPAD(0x1e0, PIN_INPUT_PULLUP, 0) /* (B16) I2C0_SCL */
    			AM62AX_IOPAD(0x1e4, PIN_INPUT_PULLUP, 0) /* (A16) I2C0_SDA */
    		>;
    	};
    
    	main_i2c1_pins_default: main-i2c1-pins-default {
    		pinctrl-single,pins = <
    			AM62AX_IOPAD(0x1e8, PIN_INPUT_PULLUP, 0) /* (B17) I2C1_SCL */
    			AM62AX_IOPAD(0x1ec, PIN_INPUT_PULLUP, 0) /* (A17) I2C1_SDA */
    		>;
    	};
    
    	main_i2c2_pins_default: main-i2c2-pins-default {
    		pinctrl-single,pins = <
    			AM62AX_IOPAD(0x0b0, PIN_INPUT_PULLUP, 1) /* (K22) GPMC0_CSn2.I2C2_SCL */
    			AM62AX_IOPAD(0x0b4, PIN_INPUT_PULLUP, 1) /* (K24) GPMC0_CSn3.I2C2_SDA */
    		>;
    	};
    
    	main_mmc0_pins_default: main-mmc0-pins-default {
    		pinctrl-single,pins = <
    			AM62AX_IOPAD(0x220, PIN_INPUT, 0) /* (Y3) MMC0_CMD */
    			AM62AX_IOPAD(0x218, PIN_INPUT, 0) /* (AB1) MMC0_CLKLB */
    			AM62AX_IOPAD(0x21c, PIN_INPUT, 0) /* (AB1) MMC0_CLK */
    			AM62AX_IOPAD(0x214, PIN_INPUT, 0) /* (AA2) MMC0_DAT0 */
    			AM62AX_IOPAD(0x210, PIN_INPUT_PULLUP, 0) /* (AA1) MMC0_DAT1 */
    			AM62AX_IOPAD(0x20c, PIN_INPUT_PULLUP, 0) /* (AA3) MMC0_DAT2 */
    			AM62AX_IOPAD(0x208, PIN_INPUT_PULLUP, 0) /* (Y4) MMC0_DAT3 */
    			AM62AX_IOPAD(0x204, PIN_INPUT_PULLUP, 0) /* (AB2) MMC0_DAT4 */
    			AM62AX_IOPAD(0x200, PIN_INPUT_PULLUP, 0) /* (AC1) MMC0_DAT5 */
    			AM62AX_IOPAD(0x1fc, PIN_INPUT_PULLUP, 0) /* (AD2) MMC0_DAT6 */
    			AM62AX_IOPAD(0x1f8, PIN_INPUT_PULLUP, 0) /* (AC2) MMC0_DAT7 */
    		>;
    	};
    
    	main_mmc1_pins_default: main-mmc1-pins-default {
    		pinctrl-single,pins = <
    			AM62AX_IOPAD(0x23c, PIN_INPUT, 0) /* (A21) MMC1_CMD */
    			AM62AX_IOPAD(0x234, PIN_INPUT, 0) /* (B22) MMC1_CLK */
    			AM62AX_IOPAD(0x230, PIN_INPUT, 0) /* (A22) MMC1_DAT0 */
    			AM62AX_IOPAD(0x22c, PIN_INPUT, 0) /* (B21) MMC1_DAT1 */
    			AM62AX_IOPAD(0x228, PIN_INPUT, 0) /* (C21) MMC1_DAT2 */
    			AM62AX_IOPAD(0x224, PIN_INPUT, 0) /* (D22) MMC1_DAT3 */
    			AM62AX_IOPAD(0x240, PIN_INPUT, 0) /* (D17) MMC1_SDCD */
    		>;
    	};
    
    	usr_led_pins_default: usr-led-pins-default {
    		pinctrl-single,pins = <
    			AM62AX_IOPAD(0x244, PIN_OUTPUT, 7) /* (D18) MMC1_SDWP.GPIO1_49 */
    		>;
    	};
    
    	main_gpio1_ioexp_intr_pins_default: main-gpio1-ioexp-intr-pins-default {
    		pinctrl-single,pins = <
    			AM62AX_IOPAD(0x01d4, PIN_INPUT, 7) /* (C15) UART0_RTSn.GPIO1_23 */
    
    		>;
    	};
    	main_tp2803_pins_default: main-tp2803-pins-default {
    		pinctrl-single,pins = <
    			AM62AX_IOPAD(0x01b0, PIN_OUTPUT, 7) /* A21  GPIO1_14 TP28_RST*/
    			AM62AX_IOPAD(0x0184, PIN_OUTPUT, 7) /* AA21 GPIO1_3  AHD-EN */
    			AM62AX_IOPAD(0x01a8, PIN_OUTPUT, 7) /* A20  GPIO1_12 TP2803_PWR_EN*/
    		>;
    	};
    	main_dss0_pins_default: main-dss0-pins-default {
    		pinctrl-single,pins = <
    			AM62AX_IOPAD(0x104, PIN_OUTPUT, 0) /* (AA22) VOUT0_PCLK */
    			AM62AX_IOPAD(0x0c0, PIN_OUTPUT, 0) /* (U20) VOUT0_DATA2 */
    			AM62AX_IOPAD(0x0c4, PIN_OUTPUT, 0) /* (U19) VOUT0_DATA3 */
    			AM62AX_IOPAD(0x0c8, PIN_OUTPUT, 0) /* (T19) VOUT0_DATA4 */
    			AM62AX_IOPAD(0x0cc, PIN_OUTPUT, 0) /* (U18) VOUT0_DATA5 */
    			AM62AX_IOPAD(0x0d0, PIN_OUTPUT, 0) /* (V22) VOUT0_DATA6 */
    			AM62AX_IOPAD(0x0d4, PIN_OUTPUT, 0) /* (V21) VOUT0_DATA7 */
    			AM62AX_IOPAD(0x0d8, PIN_OUTPUT, 0) /* (V19) VOUT0_DATA8 */
    			AM62AX_IOPAD(0x0dc, PIN_OUTPUT, 0) /* (V18) VOUT0_DATA9 */
    			AM62AX_IOPAD(0x0e8, PIN_OUTPUT, 0) /* (W20) VOUT0_DATA12 */
    			AM62AX_IOPAD(0x0ec, PIN_OUTPUT, 0) /* (W19) VOUT0_DATA13 */
    			AM62AX_IOPAD(0x0f0, PIN_OUTPUT, 0) /* (Y21) VOUT0_DATA14 */
    			AM62AX_IOPAD(0x0f4, PIN_OUTPUT, 0) /* (Y22) VOUT0_DATA15 */
    			AM62AX_IOPAD(0x05c, PIN_OUTPUT, 1) /* (P22) GPMC0_AD8.VOUT0_DATA16 */
    			AM62AX_IOPAD(0x060, PIN_OUTPUT, 1) /* (R19) GPMC0_AD9.VOUT0_DATA17 */
    			AM62AX_IOPAD(0x064, PIN_OUTPUT, 1) /* (R20) GPMC0_AD10.VOUT0_DATA18 */
    			AM62AX_IOPAD(0x068, PIN_OUTPUT, 1) /* (R22) GPMC0_AD11.VOUT0_DATA19 */
    			AM62AX_IOPAD(0x06c, PIN_OUTPUT, 1) /* (T22) GPMC0_AD12.VOUT0_DATA20 */
    			AM62AX_IOPAD(0x070, PIN_OUTPUT, 1) /* (R21) GPMC0_AD13.VOUT0_DATA21 */
    			AM62AX_IOPAD(0x074, PIN_OUTPUT, 1) /* (T20) GPMC0_AD14.VOUT0_DATA22 */
    			AM62AX_IOPAD(0x078, PIN_OUTPUT, 1) /* (T21) GPMC0_AD15.VOUT0_DATA23 */
    		>;
    	};
    
    	vddshv_sdio_pins_default: vddshv-sdio-pins-default {
    		pinctrl-single,pins = <
    			AM62AX_IOPAD(0x07c, PIN_OUTPUT, 7) /* (M19) GPMC0_CLK.GPIO0_31 */
    		>;
    	};
    	ospi0_pins_default: ospi0-pins-default {
    		pinctrl-single,pins = <
    			AM62AX_IOPAD(0x000, PIN_OUTPUT, 0) /* (H24) OSPI0_CLK */
    			AM62AX_IOPAD(0x02c, PIN_OUTPUT, 0) /* (F23) OSPI0_CSn0 */
    			AM62AX_IOPAD(0x00c, PIN_INPUT, 0) /* (E25) OSPI0_D0 */
    			AM62AX_IOPAD(0x010, PIN_INPUT, 0) /* (G24) OSPI0_D1 */
    			AM62AX_IOPAD(0x014, PIN_INPUT, 0) /* (F25) OSPI0_D2 */
    			AM62AX_IOPAD(0x018, PIN_INPUT, 0) /* (F24) OSPI0_D3 */
    			AM62AX_IOPAD(0x01c, PIN_INPUT, 0) /* (J23) OSPI0_D4 */
    			AM62AX_IOPAD(0x020, PIN_INPUT, 0) /* (J25) OSPI0_D5 */
    			AM62AX_IOPAD(0x024, PIN_INPUT, 0) /* (H25) OSPI0_D6 */
    			AM62AX_IOPAD(0x028, PIN_INPUT, 0) /* (J22) OSPI0_D7 */
    			AM62AX_IOPAD(0x008, PIN_INPUT, 0) /* (J24) OSPI0_DQS */
    		>;
    	};
    
    	main_usb1_pins_default: main-usb1-pins-default {
    		pinctrl-single,pins = <
    			AM62AX_IOPAD(0x0258, PIN_OUTPUT, 0) /* (F18) USB1_DRVVBUS */
    		>;
    	};
    
    	main_mdio1_pins_default: main-mdio1-pins-default {
    		pinctrl-single,pins = <
    			AM62AX_IOPAD(0x160, PIN_OUTPUT, 0) /* (V12) MDIO0_MDC */
    			AM62AX_IOPAD(0x15c, PIN_INPUT, 0) /* (V13) MDIO0_MDIO */
    		>;
    	};
    
    	main_rgmii1_pins_default: main-rgmii1-pins-default {
    		pinctrl-single,pins = <
    			AM62AX_IOPAD(0x14c, PIN_INPUT, 0) /* (AB16) RGMII1_RD0 */
    			AM62AX_IOPAD(0x150, PIN_INPUT, 0) /* (V15) RGMII1_RD1 */
    			AM62AX_IOPAD(0x154, PIN_INPUT, 0) /* (W15) RGMII1_RD2 */
    			AM62AX_IOPAD(0x158, PIN_INPUT, 0) /* (V14) RGMII1_RD3 */
    			AM62AX_IOPAD(0x148, PIN_INPUT, 0) /* (AA16) RGMII1_RXC */
    			AM62AX_IOPAD(0x144, PIN_INPUT, 0) /* (AA15) RGMII1_RX_CTL */
    			AM62AX_IOPAD(0x134, PIN_INPUT, 0) /* (Y17) RGMII1_TD0 */
    			AM62AX_IOPAD(0x138, PIN_INPUT, 0) /* (V16) RGMII1_TD1 */
    			AM62AX_IOPAD(0x13c, PIN_INPUT, 0) /* (Y16) RGMII1_TD2 */
    			AM62AX_IOPAD(0x140, PIN_INPUT, 0) /* (AA17) RGMII1_TD3 */
    			AM62AX_IOPAD(0x130, PIN_INPUT, 0) /* (AB17) RGMII1_TXC */
    			AM62AX_IOPAD(0x12c, PIN_INPUT, 0) /* (W16) RGMII1_TX_CTL */
    		>;
    	};
    
    	main_mcan0_pins_default: main-mcan0-pins-default {
    		pinctrl-single,pins = <
    			AM62AX_IOPAD(0x1d8, PIN_OUTPUT, 0) /* (B17) MCAN0_TX.UART5_RXD */
    			AM62AX_IOPAD(0x1dc, PIN_INPUT, 0) /* (C18) MCAN0_RX.UART5_TXD */
    		>;
    	};
    	main_pwm0_pins_default: main-pwm0-pins-default {
    		pinctrl-single,pins = <
    			AM62AX_IOPAD(0x1b8, PIN_OUTPUT, 2) /* (C16) GPIO1_16.EHRPWM0_B */
    			AM62AX_IOPAD(0x168, PIN_INPUT, 7) /* (AB19) RGMII2_TXC.GPIO0_88 */
    		>;
    	};
    	main_mcasp1_pins_default: main-mcasp1-pins-default {
    		pinctrl-single,pins = <
    			AM62AX_IOPAD(0x090, PIN_INPUT, 2) /* (L19) GPMC0_BE0n_CLE.MCASP1_ACLKX */
    			AM62AX_IOPAD(0x098, PIN_INPUT, 2) /* (R18) GPMC0_WAIT0.MCASP1_AFSX */
    			AM62AX_IOPAD(0x08c, PIN_OUTPUT, 2) /* (K19) GPMC0_WEn.MCASP1_AXR0 */
    			AM62AX_IOPAD(0x084, PIN_INPUT, 2) /* (L18) GPMC0_ADVn_ALE.MCASP1_AXR2 */
    		>;
    	};
    	phy_reset_pins_default: phy-reset-pins-default {
    		pinctrl-single,pins = <
    			AM62AX_IOPAD(0x18c,PIN_OUTPUT, 7)/*(AB21) 88QB_RSTn */
    		>;
    	};
    	cam_pins_default: cam-pins-default {
    		pinctrl-single,pins = <
    			AM62AX_IOPAD(0x16c,PIN_OUTPUT, 7)/*(AA19) SoC_CAM_RST */
    			AM62AX_IOPAD(0x164,PIN_OUTPUT, 7)/*(Y19) SCO-CAM_ERROR */
    		>;
    	};
    	vcc3v_en_pins_default: vcc3v-en-pins-default {
    		pinctrl-single,pins = <
    			AM62AX_IOPAD(0x170,PIN_OUTPUT, 7)/*(Y18) cam_vcc_en */
    		>;
    	};
    	imuacc_pins_default: imuacc-pins-default {
    	         pinctrl-single,pins = <
    	                 AM62AX_IOPAD(0x1bc, PIN_INPUT, 7) /* (A17) SPI0_CLK GPIO1_17 */
    	         >;
    	 };
    	 imugyro_pins_default: imugyro-pins-default {
    	         pinctrl-single,pins = <
    	                 AM62AX_IOPAD(0x1d8, PIN_INPUT, 7) /* (B17) GPIO1_24 */
    	         >;
    	};
    };
    &mcu_pmx0 {
    	mcu_mcan0_pins_default: mcu-mcan0-pins-default {
    		pinctrl-single,pins = <
    			AM62AX_MCU_IOPAD(0x034, PIN_OUTPUT, 0) /* (C7) MCU_MCAN0_TX */
    			AM62AX_MCU_IOPAD(0x038, PIN_INPUT, 0) /* (E8) MCU_MCAN0_RX */
    		>;
    	};
    	mcu_mcan1_pins_default: mcu-mcan1-pins-default {
    		pinctrl-single,pins = <
    			AM62AX_MCU_IOPAD(0x03c, PIN_OUTPUT, 0) /* (D7) MCU_MCAN1_TX*/
    			AM62AX_MCU_IOPAD(0x040, PIN_INPUT, 0) /* (B9) MCU_MCAN1_RX */
    		>;
    	};
    	wakeup_i2c0_pins_default: wakeup-i2c0-pins-default {
    		pinctrl-single,pins = <
    			AM62AX_MCU_IOPAD(0x004c, PIN_INPUT, 0) /* (D13) WKUP_I2C0_SCL */
    			AM62AX_MCU_IOPAD(0x0050, PIN_INPUT, 0) /* (E13) WKUP_I2C0_SDA */
    		>;
    	};
    	wkup_uart0_pins_default: wkup-uart0-pins-default {
    		pinctrl-single,pins = <
    			AM62AX_MCU_IOPAD(0x0024, PIN_INPUT, 0) /* (C9) WKUP_UART0_RXD */
    			AM62AX_MCU_IOPAD(0x0028, PIN_OUTPUT, 0) /* (E9) WKUP_UART0_TXD */
    		>;
    	};
    	pmic_irq_pins_default: pmic-irq-pins-default {
    			pinctrl-single,pins = <
    				AM62AX_MCU_IOPAD(0x000, PIN_INPUT, 7) /* (E11) MCU_GPIO0_0 */
    			>;
    	};
    };
    &main_gpio1 {
    	status = "okay";
    };
    
    &main_i2c0 {
    	status = "okay";
    	pinctrl-names = "default";
    	pinctrl-0 = <&main_i2c0_pins_default>;
    	clock-frequency = <400000>;
    	tps659312: pmic@48 {
    		compatible = "ti,tps6593-q1";
    		reg = <0x48>;
    		ti,primary-pmic;
    		system-power-controller;
    
    		gpio-controller;
    		#gpio-cells = <2>;
    
    		pinctrl-names = "default";
    		pinctrl-0 = <&pmic_irq_pins_default>;
    		interrupt-parent = <&mcu_gpio0>;
    		interrupts = <0 IRQ_TYPE_EDGE_FALLING>;
    
    		buck123-supply = <&vcc_3v3_sys>;
    		buck4-supply = <&vcc_3v3_sys>;
    		buck5-supply = <&vcc_3v3_sys>;
    		ldo1-supply = <&vcc_3v3_sys>;
    		ldo2-supply = <&vcc_3v3_sys>;
    		ldo3-supply = <&buck5>;
    		ldo4-supply = <&vcc_3v3_sys>;
    
    		regulators {
    			buck123: buck123 {
    				regulator-name = "vcc_core";
    				regulator-min-microvolt = <715000>;
    				regulator-max-microvolt = <895000>;
    				regulator-boot-on;
    				regulator-always-on;
    			};
    
    			buck4: buck4 {
    				regulator-name = "vcc_1v1";
    				regulator-min-microvolt = <1100000>;
    				regulator-max-microvolt = <1100000>;
    				regulator-boot-on;
    				regulator-always-on;
    			};
    
    			buck5: buck5 {
    				regulator-name = "vcc_1v8_sys";
    				regulator-min-microvolt = <1800000>;
    				regulator-max-microvolt = <1800000>;
    				regulator-boot-on;
    				regulator-always-on;
    			};
    
    			ldo1: ldo1 {
    				regulator-name = "vddshv5_sdio";
    				regulator-min-microvolt = <3300000>;
    				regulator-max-microvolt = <3300000>;
    				regulator-boot-on;
    				regulator-always-on;
    			};
    
    			ldo2: ldo2 {
    				regulator-name = "vpp_1v8";
    				regulator-min-microvolt = <1800000>;
    				regulator-max-microvolt = <1800000>;
    				regulator-boot-on;
    				regulator-always-on;
    			};
    
    			ldo3: ldo3 {
    				regulator-name = "vcc_0v85";
    				regulator-min-microvolt = <850000>;
    				regulator-max-microvolt = <850000>;
    				regulator-boot-on;
    				regulator-always-on;
    			};
    
    			ldo4: ldo4 {
    				regulator-name = "vdda_1v8";
    				regulator-min-microvolt = <1800000>;
    				regulator-max-microvolt = <1800000>;
    				regulator-boot-on;
    				regulator-always-on;
    			};
    		};
    	};
    	typec_pd: usb-pd@3f {
    		compatible = "ti,tps6598x";
    		reg = <0x3f>;
    
    		connector {
    			ports {
    				#address-cells = <1>;
    				#size-cells = <0>;
    
    				port@1 {
    					reg = <1>;
    
    					usb_con_hs: endpoint {
    						remote-endpoint = <&typec_hs>;
    					};
    				};
    			};
    		};
    	};
    };
    
    &main_i2c1 {
    	status = "disabled";
    	pinctrl-names = "default";
    	pinctrl-0 = <&main_i2c1_pins_default>;
    	clock-frequency = <100000>;
    
    	exp1: gpio@22 {
    		compatible = "ti,tca6424";
    		reg = <0x22>;
    		gpio-controller;
    		#gpio-cells = <2>;
    		status = "disabled";
    		interrupt-parent = <&main_gpio1>;
    		interrupts = <23 IRQ_TYPE_EDGE_FALLING>;
    		interrupt-controller;
    		#interrupt-cells = <2>;
    		gpio-line-names = "GPIO_CPSW2_RST", "GPIO_CPSW1_RST",
    				   "BT_EN_SOC", "MMC1_SD_EN",
    				   "VPP_EN", "EXP_PS_3V3_En",
    				   "EXP_PS_5V0_En", "EXP_HAT_DETECT",
    				   "GPIO_AUD_RSTn", "GPIO_eMMC_RSTn",
    				   "UART1_FET_BUF_EN", "BT_UART_WAKE_SOC",
    				   "GPIO_HDMI_RSTn", "CSI_GPIO0",
    				   "CSI_GPIO1", "WLAN_ALERTn",
    				   "HDMI_INTn", "TEST_GPIO2",
    				   "MCASP1_FET_EN", "MCASP1_BUF_BT_EN",
    				   "MCASP1_FET_SEL", "UART1_FET_SEL",
    				   "PD_I2C_IRQ", "IO_EXP_TEST_LED";
    
    		pinctrl-names = "default";
    		pinctrl-0 = <&main_gpio1_ioexp_intr_pins_default>;
    	};
    
    	sii9022: sii9022@45 {
    		#sound-dai-cells = <0>;
    		compatible = "sil,sii9022";
    		reg = <0x45>;
    
    	/*	clocks = <&hdmi_mstrclk>;
    		clock-names = "mclk";*/
    
    	/*	interrupt-parent = <&exp1>;
    		interrupts = <16 IRQ_TYPE_EDGE_FALLING>;*/
    
    		sil,i2s-data-lanes = < 0 >;
    		reset-gpios = <&main_gpio1 14  GPIO_ACTIVE_LOW>;//##TP28_RST A21  GPIO1_14  332+14£½346
    		ahd_en-gpios = <&main_gpio1 3  GPIO_ACTIVE_LOW>;//##AHD-EN AA21  GPIO1_3  332+3=335
    		pwr_en-gpios = <&main_gpio1 12  GPIO_ACTIVE_LOW>;//##TP2803_PWR_EN A20  GPIO1_12  332+12=344
    
    		pinctrl-names = "default";
    		pinctrl-0 = <&main_tp2803_pins_default>;
    
    		ports {
    			#address-cells = <1>;
    			#size-cells = <0>;
    
    			port@0 {
    				reg = <0>;
    
    				sii9022_in: endpoint {
    					remote-endpoint = <&dpi1_out>;
    				};
    			};
    
    /*			port@1 {
    				reg = <1>;
    
    				sii9022_out: endpoint {
    					remote-endpoint = <&hdmi_connector_in>;
    				};
    			};*/
    		};
    	};
    
    	tlv320aic3106: audio-codec@1b {
    		#sound-dai-cells = <0>;
    		compatible = "ti,tlv320aic3106";
    		reg = <0x1b>;
    		ai3x-micbias-vg = <1>;		/* 2.0V */
    		status = "disabled";
    
    		/* Regulators */
    		AVDD-supply = <&vcc_3v3_sys>;
    		IOVDD-supply = <&vcc_3v3_sys>;
    		DRVDD-supply = <&vcc_3v3_sys>;
    	};
    
    	exp2: gpio@23 {
    		compatible = "ti,tca6424";
    		status = "disabled";
    		reg = <0x23>;
    		gpio-controller;
    		#gpio-cells = <2>;
    	};
    };
    
    &main_i2c2 {
    	status = "okay";
    	pinctrl-names = "default";
    	pinctrl-0 = <&main_i2c2_pins_default>;
    	clock-frequency = <400000>;
    };
    
    &wkup_i2c0 {
    	status = "okay";
    	pinctrl-names = "default";
    	pinctrl-0 = <&wakeup_i2c0_pins_default>;
    	clock-frequency = <400000>;
    	smi230gyro: smi230gyro@68 {
            compatible = "SMI230GYRO";
            reg = <0x68>;
            pinctrl-0 = <&imugyro_pins_default>;
            gpio_irq = <&main_gpio1 24 IRQ_TYPE_EDGE_RISING>; /*(B17) GPIO1_24 */
            status = "disabled";
    	};
    	smi230acc: smi230acc@18 {
            compatible = "SMI230ACC";
            pinctrl-names = "default";
            pinctrl-0 = <&imuacc_pins_default>;
            reg = <0x18>;
            gpio_irq = <&main_gpio1 17 IRQ_TYPE_EDGE_RISING>; /*(A17) SPI0_CLK GPIO1_17*/
            status = "disabled";
    	};
    };
    &mcasp1 {
    	status = "okay";
    	#sound-dai-cells = <0>;
    
    	pinctrl-names = "default";
    	pinctrl-0 = <&main_mcasp1_pins_default>;
    
    	op-mode = <0>;          /* MCASP_IIS_MODE */
    	tdm-slots = <2>;
    
    	serial-dir = <  /* 0: INACTIVE, 1: TX, 2: RX */
    	       1 0 2 0
    	       0 0 0 0
    	       0 0 0 0
    	       0 0 0 0
    	>;
    	tx-num-evt = <32>;
    	rx-num-evt = <32>;
    };
    
    &sdhci0 {
    	status = "okay";
    	pinctrl-names = "default";
    	pinctrl-0 = <&main_mmc0_pins_default>;
    	ti,driver-strength-ohm = <50>;
    	disable-wp;
    };
    
    &sdhci1 {
    	/* SD/MMC */
    	status = "okay";
    	vmmc-supply = <&vdd_mmc1>;
    	vqmmc-supply = <&vddshv_sdio>;
    	pinctrl-names = "default";
    	pinctrl-0 = <&main_mmc1_pins_default>;
    	ti,driver-strength-ohm = <50>;
    	disable-wp;
    };
    
    &main_gpio0 {
    	status = "okay";
    };
    
    &main_gpio1 {
    	status = "okay";
    };
    
    &main_gpio_intr {
    	status = "okay";
    };
    
    &main_uart0 {
    	status = "okay";
    	pinctrl-names = "default";
    	pinctrl-0 = <&main_uart0_pins_default>;
    };
    &wkup_uart0 {
    	status = "okay";
    	pinctrl-names = "default";
    	pinctrl-0 = <&wkup_uart0_pins_default>;
    };
    &dss {
    	pinctrl-names = "default";
    	pinctrl-0 = <&main_dss0_pins_default>;
    };
    
    &dss_ports {
    	/* VP2: DPI Output */
    	port@1 {
    		reg = <1>;
    
    		dpi1_out: endpoint {
    			remote-endpoint = <&sii9022_in>;
    		};
    	};
    };
    
    &usbss1 {
    	status = "okay";
    };
    
    &usb1 {
    	dr_mode = "host";
    	pinctrl-names = "default";
    	pinctrl-0 = <&main_usb1_pins_default>;
    };
    
    &cpsw3g {
    	status = "okay";
    	pinctrl-names = "default";
    	vccen-gpios = <&main_gpio0 90 GPIO_ACTIVE_HIGH>;//Y18 #GPIO0_90  VCC_EN
    	reset-gpios = <&main_gpio1 5 GPIO_ACTIVE_LOW>;//AB21 88QB_RSTn
    
    	pinctrl-0 = <&main_rgmii1_pins_default>,<&vcc3v_en_pins_default>;
    };
    
    &cpsw_port1 {
    	status = "okay";
    	phy-mode = "rgmii-rxid";
    	phy-handle = <&cpsw3g_phy1>;
    };
    
    &cpsw_port2 {
    	status = "disabled";
    };
    
    &cpsw3g_mdio {
    	status = "okay";
    	pinctrl-names = "default";
    	pinctrl-0 = <&main_mdio1_pins_default>,<&phy_reset_pins_default>;
    	reset-delay-us = <20>;
    	// cpsw3g_phy0: ethernet-phy@0 {
    	// 	reg = <0>;
    	// 	ti,rx-internal-delay = <DP83867_RGMIIDCTL_2_00_NS>;
    	// 	ti,fifo-depth = <DP83867_PHYCR_FIFO_DEPTH_4_B_NIB>;
    	// 	ti,min-output-impedance;
    	// };
    	cpsw3g_phy1: ethernet-phy{
    		//reg = <14>;
    		device_type = "ethernet-phy";
    		ti,rx-internal-delay = <DP83867_RGMIIDCTL_2_00_NS>;
    		ti,fifo-depth = <DP83867_PHYCR_FIFO_DEPTH_4_B_NIB>;
    		ti,min-output-impedance;
    		/* On - Link, Blink - Activity, Off - No Link - Dual LED mode*/
    		marvell,reg-init = <3 0x10 0 0x101e>;
    		//compatible = "ethernet-phy-id0141.0DD1", "ethernet-phy-ieee802.3-c22";
    	};
    };
    
    &usbss0 {
    	status = "okay";
    };
    
    &usb0 {
    	#address-cells = <1>;
    	#size-cells = <0>;
    	usb-role-switch;
    
    	port@1 {
    		reg = <1>;
    
    		typec_hs: endpoint {
    			remote-endpoint = <&usb_con_hs>;
    		};
    	};
    };
    
    &mailbox0_cluster0 {
    	mbox_r5_0: mbox-r5-0 {
    		ti,mbox-rx = <0 0 0>;
    		ti,mbox-tx = <1 0 0>;
    	};
    };
    
    &mailbox0_cluster1 {
    	mbox_c7x_0: mbox-c7x-0 {
    		ti,mbox-rx = <0 0 0>;
    		ti,mbox-tx = <1 0 0>;
    	};
    };
    
    &mailbox0_cluster2 {
    	mbox_mcu_r5_0: mbox-mcu_r5-0 {
    		ti,mbox-rx = <0 0 0>;
    		ti,mbox-tx = <1 0 0>;
    	};
    };
    
    &c7x_0 {
    	mboxes = <&mailbox0_cluster1 &mbox_c7x_0>;
    	memory-region = <&c7x_0_dma_memory_region>,
    			<&c7x_0_memory_region>;
    };
    
    &wkup_r5fss0_core0 {
    	mboxes = <&mailbox0_cluster0 &mbox_r5_0>;
    	memory-region = <&wkup_r5fss0_core0_dma_memory_region>,
    		<&wkup_r5fss0_core0_memory_region>;
    };
    
    &mcu_r5fss0_core0 {
    	mboxes = <&mailbox0_cluster2 &mbox_mcu_r5_0>;
    	memory-region = <&mcu_r5fss0_core0_dma_memory_region>,
    			<&mcu_r5fss0_core0_memory_region>;
    };
    
    &csi0_port0 {
    	status = "disabled";
    };
    
    &csi0_port1 {
    	status = "disabled";
    };
    
    &csi0_port2 {
    	status = "disabled";
    };
    
    &csi0_port3 {
    	status = "disabled";
    };
    
    &csi0_port4 {
    	status = "disabled";
    };
    
    &fss {
    	status = "okay";
    };
    
    &ospi0 {
    	status = "okay";
    	pinctrl-names = "default";
    	pinctrl-0 = <&ospi0_pins_default>;
    
    	flash@0 {
    		compatible = "spi-nand";
    		reg = <0x0>;
    		spi-tx-bus-width = <8>;
    		spi-rx-bus-width = <8>;
    		spi-max-frequency = <25000000>;
    		cdns,tshsl-ns = <60>;
    		cdns,tsd2d-ns = <60>;
    		cdns,tchsh-ns = <60>;
    		cdns,tslch-ns = <60>;
    		cdns,read-delay = <2>;
    		cdns,phy-mode;
    
    		partitions {
    			compatible = "fixed-partitions";
    			#address-cells = <1>;
    			#size-cells = <1>;
    
    			partition@0 {
    				label = "ospi.tiboot3";
    				reg = <0x0 0x80000>;
    			};
    
    			partition@80000 {
    				label = "ospi.tispl";
    				reg = <0x80000 0x200000>;
    			};
    
    			partition@280000 {
    				label = "ospi.u-boot";
    				reg = <0x280000 0x400000>;
    			};
    
    			partition@680000 {
    				label = "ospi.env";
    				reg = <0x680000 0x40000>;
    			};
    
    			partition@6c0000 {
    				label = "ospi.env.backup";
    				reg = <0x6c0000 0x40000>;
    			};
    
    			partition@2000000 {
    				label = "ospi.rootfs";
    				reg = <0x2000000 0x5fc0000>;
    			};
    
    			partition@7fc0000 {
    				label = "ospi.phypattern";
    				reg = <0x7fc0000 0x40000>;
    			};
    		};
    	};
    };
    &mcu_mcan0 {
    	status = "disabled";
    	pinctrl-names = "default";
    	pinctrl-0 = <&mcu_mcan0_pins_default>;
    //	phys = <&transceiver2>;
    
    };
    &mcu_mcan1 {
    	status = "disabled";
    	pinctrl-names = "default";
    	pinctrl-0 = <&mcu_mcan1_pins_default>;
    	// phys = <&transceiver3>;
    
    };
    
    
    &main_mcan0 {
    	status = "disabled";
    	pinctrl-names = "default";
    	pinctrl-0 = <&main_mcan0_pins_default>;
    	// phys = <&transceiver1>;
    };
    &epwm0 {
    	status = "okay";
    	pinctrl-names = "default";
    	pinctrl-0 = <&main_pwm0_pins_default>;
    };
    
     k3-am62a7-sk.dts

    // SPDX-License-Identifier: GPL-2.0
    /*
     * Device Tree Source for AM62A SoC Family Main Domain peripherals
     *
     * Copyright (C) 2022 Texas Instruments Incorporated - https://www.ti.com/
     */
    
    &cbass_main {
    	oc_sram: sram@70000000 {
    		compatible = "mmio-sram";
    		reg = <0x00 0x70000000 0x00 0x10000>;
    		#address-cells = <1>;
    		#size-cells = <1>;
    		ranges = <0x0 0x00 0x70000000 0x10000>;
    	};
    
    	gic500: interrupt-controller@1800000 {
    		compatible = "arm,gic-v3";
    		reg = <0x00 0x01800000 0x00 0x10000>,	/* GICD */
    		      <0x00 0x01880000 0x00 0xc0000>,	/* GICR */
    		      <0x00 0x01880000 0x00 0xc0000>,   /* GICR */
    		      <0x01 0x00000000 0x00 0x2000>,    /* GICC */
    		      <0x01 0x00010000 0x00 0x1000>,    /* GICH */
    		      <0x01 0x00020000 0x00 0x2000>;    /* GICV */
    		#address-cells = <2>;
    		#size-cells = <2>;
    		ranges;
    		#interrupt-cells = <3>;
    		interrupt-controller;
    		/*
    		 * vcpumntirq:
    		 * virtual CPU interface maintenance interrupt
    		 */
    		interrupts = <GIC_PPI 9 IRQ_TYPE_LEVEL_HIGH>;
    
    		gic_its: msi-controller@1820000 {
    			compatible = "arm,gic-v3-its";
    			reg = <0x00 0x01820000 0x00 0x10000>;
    			socionext,synquacer-pre-its = <0x1000000 0x400000>;
    			msi-controller;
    			#msi-cells = <1>;
    		};
    	};
    
    	main_conf: syscon@100000 {
    		compatible = "ti,j721e-system-controller", "syscon", "simple-mfd";
    		reg = <0x00 0x00100000 0x00 0x20000>;
    		#address-cells = <1>;
    		#size-cells = <1>;
    		ranges = <0x00 0x00 0x00100000 0x20000>;
    
    		phy_gmii_sel: phy@4044 {
    			compatible = "ti,am654-phy-gmii-sel";
    			reg = <0x4044 0x8>;
    			#phy-cells = <1>;
    		};
    
    		epwm_tbclk: clock@4130 {
    			compatible = "ti,am62-epwm-tbclk", "syscon";
    			reg = <0x4130 0x4>;
    			#clock-cells = <1>;
    		};
    	};
    
    	dmss: bus@48000000 {
    		compatible = "simple-bus";
    		#address-cells = <2>;
    		#size-cells = <2>;
    		dma-ranges;
    		ranges = <0x00 0x48000000 0x00 0x48000000 0x00 0x06000000>;
    
    		ti,sci-dev-id = <25>;
    
    		secure_proxy_main: mailbox@4d000000 {
    			compatible = "ti,am654-secure-proxy";
    			reg = <0x00 0x4d000000 0x00 0x80000>,
    			      <0x00 0x4a600000 0x00 0x80000>,
    			      <0x00 0x4a400000 0x00 0x80000>;
    			reg-names = "target_data", "rt", "scfg";
    			#mbox-cells = <1>;
    			interrupt-names = "rx_012";
    			interrupts = <GIC_SPI 34 IRQ_TYPE_LEVEL_HIGH>;
    		};
    
    		inta_main_dmss: interrupt-controller@48000000 {
    			compatible = "ti,sci-inta";
    			reg = <0x00 0x48000000 0x00 0x100000>;
    			#interrupt-cells = <0>;
    			interrupt-controller;
    			interrupt-parent = <&gic500>;
    			msi-controller;
    			ti,sci = <&dmsc>;
    			ti,sci-dev-id = <28>;
    			ti,interrupt-ranges = <6 70 34>;
    			ti,unmapped-event-sources = <&main_bcdma>, <&main_pktdma>;
    		};
    
    		main_bcdma: dma-controller@485c0100 {
    			compatible = "ti,am64-dmss-bcdma";
    			reg = <0x00 0x485c0100 0x00 0x100>,
    			      <0x00 0x4c000000 0x00 0x20000>,
    			      <0x00 0x4a820000 0x00 0x20000>,
    			      <0x00 0x4aa40000 0x00 0x20000>,
    			      <0x00 0x4bc00000 0x00 0x100000>;
    			reg-names = "gcfg", "bchanrt", "rchanrt", "tchanrt", "ringrt";
    			msi-parent = <&inta_main_dmss>;
    			#dma-cells = <3>;
    			ti,sci = <&dmsc>;
    			ti,sci-dev-id = <26>;
    			ti,sci-rm-range-bchan = <0x20>; /* BLOCK_COPY_CHAN */
    			ti,sci-rm-range-rchan = <0x21>; /* SPLIT_TR_RX_CHAN */
    			ti,sci-rm-range-tchan = <0x22>; /* SPLIT_TR_TX_CHAN */
    		};
    
    		main_pktdma: dma-controller@485c0000 {
    			compatible = "ti,am64-dmss-pktdma";
    			reg = <0x00 0x485c0000 0x00 0x100>,
    			      <0x00 0x4a800000 0x00 0x20000>,
    			      <0x00 0x4aa00000 0x00 0x40000>,
    			      <0x00 0x4b800000 0x00 0x400000>;
    			reg-names = "gcfg", "rchanrt", "tchanrt", "ringrt";
    			msi-parent = <&inta_main_dmss>;
    			#dma-cells = <2>;
    			ti,sci = <&dmsc>;
    			ti,sci-dev-id = <30>;
    			ti,sci-rm-range-tchan = <0x23>, /* UNMAPPED_TX_CHAN */
    						<0x24>, /* CPSW_TX_CHAN */
    						<0x25>, /* SAUL_TX_0_CHAN */
    						<0x26>; /* SAUL_TX_1_CHAN */
    			ti,sci-rm-range-tflow = <0x10>, /* RING_UNMAPPED_TX_CHAN */
    						<0x11>, /* RING_CPSW_TX_CHAN */
    						<0x12>, /* RING_SAUL_TX_0_CHAN */
    						<0x13>; /* RING_SAUL_TX_1_CHAN */
    			ti,sci-rm-range-rchan = <0x29>, /* UNMAPPED_RX_CHAN */
    						<0x2b>, /* CPSW_RX_CHAN */
    						<0x2d>, /* SAUL_RX_0_CHAN */
    						<0x2f>, /* SAUL_RX_1_CHAN */
    						<0x31>, /* SAUL_RX_2_CHAN */
    						<0x33>; /* SAUL_RX_3_CHAN */
    			ti,sci-rm-range-rflow = <0x2a>, /* FLOW_UNMAPPED_RX_CHAN */
    						<0x2c>, /* FLOW_CPSW_RX_CHAN */
    						<0x2e>, /* FLOW_SAUL_RX_0/1_CHAN */
    						<0x32>; /* FLOW_SAUL_RX_2/3_CHAN */
    		};
    	};
    
    	dmss_csi: bus@4e000000 {
    		compatible = "simple-bus";
    		#address-cells = <2>;
    		#size-cells = <2>;
    		dma-ranges;
    		ranges = <0x00 0x4e000000 0x00 0x4e000000 0x00 0x300000>;
    
    		ti,sci-dev-id = <198>;
    
    		inta_main_dmss_csi: interrupt-controller@4e0a0000 {
    			compatible = "ti,sci-inta";
    			reg = <0x00 0x4e0a0000 0x00 0x8000>;
    			#interrupt-cells = <0>;
    			interrupt-controller;
    			interrupt-parent = <&gic500>;
    			msi-controller;
    			ti,sci = <&dmsc>;
    			ti,sci-dev-id = <200>;
    			ti,interrupt-ranges = <0 237 8>;
    			ti,unmapped-event-sources = <&main_bcdma_csi>;
    			power-domains = <&k3_pds 182 TI_SCI_PD_EXCLUSIVE>;
    		};
    
    		main_bcdma_csi: dma-controller@4e230000 {
    			compatible = "ti,am62a-dmss-bcdma-csirx";
    			reg = <0x00 0x4e230000 0x00 0x100>,
    			      <0x00 0x4e180000 0x00 0x8000>,
    			      <0x00 0x4e100000 0x00 0x10000>;
    			reg-names = "gcfg", "rchanrt", "ringrt";
    			msi-parent = <&inta_main_dmss_csi>;
    			#dma-cells = <3>;
    			ti,sci = <&dmsc>;
    			ti,sci-dev-id = <199>;
    			ti,sci-rm-range-rchan = <0x21>;
    			power-domains = <&k3_pds 182 TI_SCI_PD_EXCLUSIVE>;
    		};
    	};
    
    	dmsc: system-controller@44043000 {
    		compatible = "ti,k2g-sci";
    		reg = <0x00 0x44043000 0x00 0xfe0>;
    		reg-names = "debug_messages";
    		ti,host-id = <12>;
    		mbox-names = "rx", "tx";
    		mboxes= <&secure_proxy_main 12>,
    			<&secure_proxy_main 13>;
    
    		k3_pds: power-controller {
    			compatible = "ti,sci-pm-domain";
    			#power-domain-cells = <2>;
    		};
    
    		k3_clks: clock-controller {
    			compatible = "ti,k2g-sci-clk";
    			#clock-cells = <2>;
    		};
    
    		k3_reset: reset-controller {
    			compatible = "ti,sci-reset";
    			#reset-cells = <2>;
    		};
    	};
    
    	crypto: crypto@40900000 {
    		compatible = "ti,am62-sa3ul";
    		reg = <0x00 0x40900000 0x00 0x1200>;
    		#address-cells = <2>;
    		#size-cells = <2>;
    		ranges = <0x00 0x40900000 0x00 0x40900000 0x00 0x30000>;
    
    		dmas = <&main_pktdma 0xf501 0>, <&main_pktdma 0x7506 0>,
    				<&main_pktdma 0x7507 0>;
    		dma-names = "tx", "rx1", "rx2";
    	};
    
    	main_pmx0: pinctrl@f4000 {
    		compatible = "pinctrl-single";
    		reg = <0x00 0xf4000 0x00 0x2ac>;
    		#pinctrl-cells = <1>;
    		pinctrl-single,register-width = <32>;
    		pinctrl-single,function-mask = <0xffffffff>;
    	};
    
    	main_uart0: serial@2800000 {
    		compatible = "ti,am64-uart", "ti,am654-uart";
    		reg = <0x00 0x02800000 0x00 0x100>;
    		interrupts = <GIC_SPI 178 IRQ_TYPE_LEVEL_HIGH>;
    		power-domains = <&k3_pds 146 TI_SCI_PD_EXCLUSIVE>;
    		clocks = <&k3_clks 146 0>;
    		clock-names = "fclk";
    		status = "disabled";
    	};
    
    	main_uart1: serial@2810000 {
    		compatible = "ti,am64-uart", "ti,am654-uart";
    		reg = <0x00 0x02810000 0x00 0x100>;
    		interrupts = <GIC_SPI 179 IRQ_TYPE_LEVEL_HIGH>;
    		power-domains = <&k3_pds 152 TI_SCI_PD_EXCLUSIVE>;
    		clocks = <&k3_clks 152 0>;
    		clock-names = "fclk";
    		status = "disabled";
    	};
    
    	main_uart2: serial@2820000 {
    		compatible = "ti,am64-uart", "ti,am654-uart";
    		reg = <0x00 0x02820000 0x00 0x100>;
    		interrupts = <GIC_SPI 180 IRQ_TYPE_LEVEL_HIGH>;
    		power-domains = <&k3_pds 153 TI_SCI_PD_EXCLUSIVE>;
    		clocks = <&k3_clks 153 0>;
    		clock-names = "fclk";
    		status = "disabled";
    	};
    
    	main_uart3: serial@2830000 {
    		compatible = "ti,am64-uart", "ti,am654-uart";
    		reg = <0x00 0x02830000 0x00 0x100>;
    		interrupts = <GIC_SPI 181 IRQ_TYPE_LEVEL_HIGH>;
    		power-domains = <&k3_pds 154 TI_SCI_PD_EXCLUSIVE>;
    		clocks = <&k3_clks 154 0>;
    		clock-names = "fclk";
    		status = "disabled";
    	};
    
    	main_uart4: serial@2840000 {
    		compatible = "ti,am64-uart", "ti,am654-uart";
    		reg = <0x00 0x02840000 0x00 0x100>;
    		interrupts = <GIC_SPI 182 IRQ_TYPE_LEVEL_HIGH>;
    		power-domains = <&k3_pds 155 TI_SCI_PD_EXCLUSIVE>;
    		clocks = <&k3_clks 155 0>;
    		clock-names = "fclk";
    		status = "disabled";
    	};
    
    	main_uart5: serial@2850000 {
    		compatible = "ti,am64-uart", "ti,am654-uart";
    		reg = <0x00 0x02850000 0x00 0x100>;
    		interrupts = <GIC_SPI 183 IRQ_TYPE_LEVEL_HIGH>;
    		power-domains = <&k3_pds 156 TI_SCI_PD_EXCLUSIVE>;
    		clocks = <&k3_clks 156 0>;
    		clock-names = "fclk";
    		status = "disabled";
    	};
    
    	main_uart6: serial@2860000 {
    		compatible = "ti,am64-uart", "ti,am654-uart";
    		reg = <0x00 0x02860000 0x00 0x100>;
    		interrupts = <GIC_SPI 184 IRQ_TYPE_LEVEL_HIGH>;
    		power-domains = <&k3_pds 158 TI_SCI_PD_EXCLUSIVE>;
    		clocks = <&k3_clks 158 0>;
    		clock-names = "fclk";
    		status = "disabled";
    	};
    
    	main_i2c0: i2c@20000000 {
    		compatible = "ti,am64-i2c", "ti,omap4-i2c";
    		reg = <0x00 0x20000000 0x00 0x100>;
    		interrupts = <GIC_SPI 161 IRQ_TYPE_LEVEL_HIGH>;
    		#address-cells = <1>;
    		#size-cells = <0>;
    		power-domains = <&k3_pds 102 TI_SCI_PD_EXCLUSIVE>;
    		clocks = <&k3_clks 102 2>;
    		clock-names = "fck";
    		status = "disabled";
    	};
    
    	main_i2c1: i2c@20010000 {
    		compatible = "ti,am64-i2c", "ti,omap4-i2c";
    		reg = <0x00 0x20010000 0x00 0x100>;
    		interrupts = <GIC_SPI 162 IRQ_TYPE_LEVEL_HIGH>;
    		#address-cells = <1>;
    		#size-cells = <0>;
    		power-domains = <&k3_pds 103 TI_SCI_PD_EXCLUSIVE>;
    		clocks = <&k3_clks 103 2>;
    		clock-names = "fck";
    		status = "disabled";
    	};
    
    	main_i2c2: i2c@20020000 {
    		compatible = "ti,am64-i2c", "ti,omap4-i2c";
    		reg = <0x00 0x20020000 0x00 0x100>;
    		interrupts = <GIC_SPI 163 IRQ_TYPE_LEVEL_HIGH>;
    		#address-cells = <1>;
    		#size-cells = <0>;
    		power-domains = <&k3_pds 104 TI_SCI_PD_EXCLUSIVE>;
    		clocks = <&k3_clks 104 2>;
    		clock-names = "fck";
    		status = "disabled";
    	};
    
    	main_i2c3: i2c@20030000 {
    		compatible = "ti,am64-i2c", "ti,omap4-i2c";
    		reg = <0x00 0x20030000 0x00 0x100>;
    		interrupts = <GIC_SPI 164 IRQ_TYPE_LEVEL_HIGH>;
    		#address-cells = <1>;
    		#size-cells = <0>;
    		power-domains = <&k3_pds 105 TI_SCI_PD_EXCLUSIVE>;
    		clocks = <&k3_clks 105 2>;
    		clock-names = "fck";
    		status = "disabled";
    	};
    
    	main_spi0: spi@20100000 {
    		compatible = "ti,am654-mcspi", "ti,omap4-mcspi";
    		reg = <0x00 0x20100000 0x00 0x400>;
    		interrupts = <GIC_SPI 172 IRQ_TYPE_LEVEL_HIGH>;
    		#address-cells = <1>;
    		#size-cells = <0>;
    		power-domains = <&k3_pds 141 TI_SCI_PD_EXCLUSIVE>;
    		clocks = <&k3_clks 141 0>;
    		status = "disabled";
    	};
    
    	main_spi1: spi@20110000 {
    		compatible = "ti,am654-mcspi","ti,omap4-mcspi";
    		reg = <0x00 0x20110000 0x00 0x400>;
    		interrupts = <GIC_SPI 173 IRQ_TYPE_LEVEL_HIGH>;
    		#address-cells = <1>;
    		#size-cells = <0>;
    		power-domains = <&k3_pds 142 TI_SCI_PD_EXCLUSIVE>;
    		clocks = <&k3_clks 142 0>;
    		status = "disabled";
    	};
    
    	main_spi2: spi@20120000 {
    		compatible = "ti,am654-mcspi","ti,omap4-mcspi";
    		reg = <0x00 0x20120000 0x00 0x400>;
    		interrupts = <GIC_SPI 174 IRQ_TYPE_LEVEL_HIGH>;
    		#address-cells = <1>;
    		#size-cells = <0>;
    		power-domains = <&k3_pds 143 TI_SCI_PD_EXCLUSIVE>;
    		clocks = <&k3_clks 143 0>;
    		status = "disabled";
    	};
    
    	main_gpio_intr: interrupt-controller@a00000 {
    		compatible = "ti,sci-intr";
    		reg = <0x00 0x00a00000 0x00 0x800>;
    		ti,intr-trigger-type = <1>;
    		interrupt-controller;
    		interrupt-parent = <&gic500>;
    		#interrupt-cells = <1>;
    		ti,sci = <&dmsc>;
    		ti,sci-dev-id = <3>;
    		ti,interrupt-ranges = <0 32 16>;
    		status = "disabled";
    	};
    
    	main_gpio0: gpio@600000 {
    		compatible = "ti,am64-gpio", "ti,keystone-gpio";
    		reg = <0x00 0x00600000 0x0 0x100>;
    		gpio-controller;
    		#gpio-cells = <2>;
    		interrupt-parent = <&main_gpio_intr>;
    		interrupts = <190>, <191>, <192>,
    			     <193>, <194>, <195>;
    		interrupt-controller;
    		#interrupt-cells = <2>;
    		ti,ngpio = <92>;
    		ti,davinci-gpio-unbanked = <0>;
    		power-domains = <&k3_pds 77 TI_SCI_PD_EXCLUSIVE>;
    		clocks = <&k3_clks 77 0>;
    		clock-names = "gpio";
    		status = "disabled";
    	};
    
    	main_gpio1: gpio@601000 {
    		compatible = "ti,am64-gpio", "ti,keystone-gpio";
    		reg = <0x00 0x00601000 0x0 0x100>;
    		gpio-controller;
    		#gpio-cells = <2>;
    		interrupt-parent = <&main_gpio_intr>;
    		interrupts = <180>, <181>, <182>,
    			     <183>, <184>, <185>;
    		interrupt-controller;
    		#interrupt-cells = <2>;
    		ti,ngpio = <88>;
    		ti,davinci-gpio-unbanked = <0>;
    		power-domains = <&k3_pds 78 TI_SCI_PD_EXCLUSIVE>;
    		clocks = <&k3_clks 78 0>;
    		clock-names = "gpio";
    		status = "disabled";
    	};
    
    	sdhci0: mmc@fa10000 {
    		compatible = "ti,am62-sdhci";
    		reg = <0x00 0xfa10000 0x00 0x260>, <0x00 0xfa18000 0x00 0x134>;
    		interrupts = <GIC_SPI 133 IRQ_TYPE_LEVEL_HIGH>;
    		power-domains = <&k3_pds 57 TI_SCI_PD_EXCLUSIVE>;
    		clocks = <&k3_clks 57 5>, <&k3_clks 57 6>;
    		clock-names = "clk_ahb", "clk_xin";
    		assigned-clocks = <&k3_clks 57 6>;
    		assigned-clock-parents = <&k3_clks 57 8>;
    		mmc-ddr-1_8v;
    		mmc-hs200-1_8v;
    		ti,trm-icp = <0x2>;
    		bus-width = <8>;
    		ti,clkbuf-sel = <0x7>;
    		ti,otap-del-sel-legacy = <0x0>;
    		ti,otap-del-sel-mmc-hs = <0x0>;
    		ti,otap-del-sel-ddr52 = <0x9>;
    		ti,otap-del-sel-hs200 = <0x6>;
    		status = "disabled";
    	};
    
    	sdhci1: mmc@fa00000 {
    		compatible = "ti,am62-sdhci";
    		reg = <0x00 0xfa00000 0x00 0x260>, <0x00 0xfa08000 0x00 0x134>;
    		interrupts = <GIC_SPI 83 IRQ_TYPE_LEVEL_HIGH>;
    		power-domains = <&k3_pds 58 TI_SCI_PD_EXCLUSIVE>;
    		clocks = <&k3_clks 58 5>, <&k3_clks 58 6>;
    		clock-names = "clk_ahb", "clk_xin";
    		ti,trm-icp = <0x2>;
    		ti,otap-del-sel-legacy = <0x8>;
    		ti,otap-del-sel-sd-hs = <0x0>;
    		ti,otap-del-sel-sdr12 = <0xf>;
    		ti,otap-del-sel-sdr25 = <0xf>;
    		ti,otap-del-sel-sdr50 = <0xc>;
    		ti,otap-del-sel-sdr104 = <0x6>;
    		ti,otap-del-sel-ddr50 = <0x9>;
    		ti,itap-del-sel-legacy = <0x0>;
    		ti,itap-del-sel-sd-hs = <0x0>;
    		ti,itap-del-sel-sdr12 = <0x0>;
    		ti,itap-del-sel-sdr25 = <0x0>;
    		ti,clkbuf-sel = <0x7>;
    		bus-width = <4>;
    		// no-1-8-v;
    		status = "disabled";
    	};
    
    	dss: dss@30200000 {
    		compatible = "ti,am625-dss";
    
    		reg = <0x00 0x30200000 0x00 0x1000>, /* common */
    		      <0x00 0x30201000 0x00 0x1000>, /* common1 */
    		      <0x00 0x30202000 0x00 0x1000>, /* vidl1 */
    		      <0x00 0x30206000 0x00 0x1000>, /* vid */
    		      <0x00 0x30207000 0x00 0x1000>, /* ovr1 */
    		      <0x00 0x30208000 0x00 0x1000>, /* ovr2 */
    		      <0x00 0x3020a000 0x00 0x1000>, /* vp1: OLDI: Tied OFF */
    		      <0x00 0x3020b000 0x00 0x1000>; /* vp2: Used as DPI Out */
    
    		reg-names = "common", "common1",
    			    "vidl1", "vid",
    			    "ovr1", "ovr2",
    			    "vp1", "vp2";
    
    		power-domains = <&k3_pds 186 TI_SCI_PD_EXCLUSIVE>;
    
    		clocks = <&k3_clks 186 6>,
    			 <&k3_clks 186 0>,
    			 <&k3_clks 186 2>;
    
    		clock-names = "fck", "vp1", "vp2";
    
    		interrupts = <GIC_SPI 84 IRQ_TYPE_LEVEL_HIGH>,
    			     <GIC_SPI 85 IRQ_TYPE_LEVEL_HIGH>;
    
    		dss_ports: ports {
    			#address-cells = <1>;
    			#size-cells = <0>;
    		};
    	};
    
    	vpu: video-codec@30210000 {
    		compatible = "cnm,cm521c-vpu";
    		reg = <0x00 0x30210000 0x00 0x10000>;
    		clocks = <&k3_clks 204 2>;
    		clock-names = "vcodec";
    		power-domains = <&k3_pds 204 TI_SCI_PD_EXCLUSIVE>;
    	};
    
    	sdhci2: mmc@fa20000 {
    		compatible = "ti,am62-sdhci";
    		reg = <0x00 0xfa20000 0x00 0x260>, <0x00 0xfa28000 0x00 0x134>;
    		interrupts = <GIC_SPI 82 IRQ_TYPE_LEVEL_HIGH>;
    		power-domains = <&k3_pds 184 TI_SCI_PD_EXCLUSIVE>;
    		clocks = <&k3_clks 184 5>, <&k3_clks 184 6>;
    		clock-names = "clk_ahb", "clk_xin";
    		ti,trm-icp = <0x2>;
    		ti,otap-del-sel-legacy = <0x0>;
    		ti,otap-del-sel-sd-hs = <0x0>;
    		ti,otap-del-sel-sdr12 = <0xf>;
    		ti,otap-del-sel-sdr25 = <0xf>;
    		ti,otap-del-sel-sdr50 = <0xc>;
    		ti,otap-del-sel-sdr104 = <0x6>;
    		ti,otap-del-sel-ddr50 = <0x9>;
    		ti,itap-del-sel-legacy = <0x0>;
    		ti,itap-del-sel-sd-hs = <0x0>;
    		ti,itap-del-sel-sdr12 = <0x0>;
    		ti,itap-del-sel-sdr25 = <0x0>;
    		ti,clkbuf-sel = <0x7>;
    		status = "disabled";
    	};
    
    	usbss0: dwc3-usb@f900000 {
    		compatible = "ti,am62-usb";
    		reg = <0x00 0x0f900000 0x00 0x800>;
    		clocks = <&k3_clks 161 3>;
    		clock-names = "ref";
    		ti,syscon-phy-pll-refclk = <&wkup_conf 0x4008>;
    		#address-cells = <2>;
    		#size-cells = <2>;
    		power-domains = <&k3_pds 178 TI_SCI_PD_EXCLUSIVE>;
    		ranges;
    		status = "disabled";
    
    		usb0: usb@31000000 {
    			compatible = "snps,dwc3";
    			reg =<0x00 0x31000000 0x00 0x50000>;
    			interrupts = <GIC_SPI 188 IRQ_TYPE_LEVEL_HIGH>, /* irq.0 */
    				     <GIC_SPI 188 IRQ_TYPE_LEVEL_HIGH>; /* irq.0 */
    			interrupt-names = "host", "peripheral";
    			maximum-speed = "high-speed";
    			dr_mode = "otg";
    		};
    	};
    
    	usbss1: dwc3-usb@f910000 {
    		compatible = "ti,am62-usb";
    		reg = <0x00 0x0f910000 0x00 0x800>;
    		clocks = <&k3_clks 162 3>;
    		clock-names = "ref";
    		ti,syscon-phy-pll-refclk = <&wkup_conf 0x4018>;
    		#address-cells = <2>;
    		#size-cells = <2>;
    		power-domains = <&k3_pds 179 TI_SCI_PD_EXCLUSIVE>;
    		ranges;
    		status = "disabled";
    
    		usb1: usb@31100000 {
    			compatible = "snps,dwc3";
    			reg =<0x00 0x31100000 0x00 0x50000>;
    			interrupts = <GIC_SPI 226 IRQ_TYPE_LEVEL_HIGH>, /* irq.0 */
    				     <GIC_SPI 226 IRQ_TYPE_LEVEL_HIGH>; /* irq.0 */
    			interrupt-names = "host", "peripheral";
    			maximum-speed = "high-speed";
    			dr_mode = "otg";
    		};
    	};
    
    	fss: bus@fc00000 {
    		compatible = "simple-bus";
    		reg = <0x00 0x0fc00000 0x00 0x70000>;
    		#address-cells = <2>;
    		#size-cells = <2>;
    		ranges;
    		status = "disabled";
    
    		ospi0: spi@fc40000 {
    			compatible = "ti,am654-ospi", "cdns,qspi-nor";
    			reg = <0x00 0x0fc40000 0x00 0x100>,
    			      <0x05 0x00000000 0x01 0x00000000>;
    			interrupts = <GIC_SPI 139 IRQ_TYPE_LEVEL_HIGH>;
    			cdns,fifo-depth = <256>;
    			cdns,fifo-width = <4>;
    			cdns,trigger-address = <0x0>;
    			clocks = <&k3_clks 75 7>;
    			assigned-clocks = <&k3_clks 75 7>;
    			assigned-clock-parents = <&k3_clks 75 8>;
    			assigned-clock-rates = <166666666>;
    			power-domains = <&k3_pds 75 TI_SCI_PD_EXCLUSIVE>;
    			#address-cells = <1>;
    			#size-cells = <0>;
    		};
    	};
    
    	cpsw3g: ethernet@8000000 {
    		compatible = "ti,am642-cpsw-nuss";
    		#address-cells = <2>;
    		#size-cells = <2>;
    		reg = <0x0 0x8000000 0x0 0x200000>;
    		reg-names = "cpsw_nuss";
    		ranges = <0x0 0x0 0x0 0x8000000 0x0 0x200000>;
    		clocks = <&k3_clks 13 0>;
    		assigned-clocks = <&k3_clks 13 3>;
    		assigned-clock-parents = <&k3_clks 13 11>;
    		clock-names = "fck";
    		power-domains = <&k3_pds 13 TI_SCI_PD_EXCLUSIVE>;
    		status = "disabled";
    
    		dmas = <&main_pktdma 0xc600 15>,
    		       <&main_pktdma 0xc601 15>,
    		       <&main_pktdma 0xc602 15>,
    		       <&main_pktdma 0xc603 15>,
    		       <&main_pktdma 0xc604 15>,
    		       <&main_pktdma 0xc605 15>,
    		       <&main_pktdma 0xc606 15>,
    		       <&main_pktdma 0xc607 15>,
    		       <&main_pktdma 0x4600 15>;
    		dma-names = "tx0", "tx1", "tx2", "tx3", "tx4", "tx5", "tx6",
    			    "tx7", "rx";
    
    		ethernet-ports {
    			#address-cells = <1>;
    			#size-cells = <0>;
    
    			cpsw_port1: port@1 {
    				reg = <1>;
    				ti,mac-only;
    				label = "port1";
    				phys = <&phy_gmii_sel 1>;
    				mac-address = [00 00 00 00 00 00];
    				ti,syscon-efuse = <&wkup_conf 0x200>;
    			};
    
    			cpsw_port2: port@2 {
    				reg = <2>;
    				ti,mac-only;
    				label = "port2";
    				phys = <&phy_gmii_sel 2>;
    				mac-address = [00 00 00 00 00 00];
    			};
    		};
    
    		cpsw3g_mdio: mdio@f00 {
    			compatible = "ti,cpsw-mdio","ti,davinci_mdio";
    			reg = <0x0 0xf00 0x0 0x100>;
    			#address-cells = <1>;
    			#size-cells = <0>;
    			clocks = <&k3_clks 13 0>;
    			clock-names = "fck";
    			bus_freq = <1000000>;
    		};
    
    		cpts@3d000 {
    			compatible = "ti,j721e-cpts";
    			reg = <0x0 0x3d000 0x0 0x400>;
    			clocks = <&k3_clks 13 3>;
    			clock-names = "cpts";
    			interrupts-extended = <&gic500 GIC_SPI 102 IRQ_TYPE_LEVEL_HIGH>;
    			interrupt-names = "cpts";
    			ti,cpts-ext-ts-inputs = <4>;
    			ti,cpts-periodic-outputs = <2>;
    		};
    	};
    
    	hwspinlock: spinlock@2a000000 {
    		compatible = "ti,am64-hwspinlock";
    		reg = <0x00 0x2a000000 0x00 0x1000>;
    		#hwlock-cells = <1>;
    	};
    
    	mailbox0_cluster0: mailbox@29000000 {
    		compatible = "ti,am64-mailbox";
    		reg = <0x00 0x29000000 0x00 0x200>;
    		interrupts = <GIC_SPI 76 IRQ_TYPE_LEVEL_HIGH>;
    		#mbox-cells = <1>;
    		ti,mbox-num-users = <4>;
    		ti,mbox-num-fifos = <16>;
    	};
    
    	mailbox0_cluster1: mailbox@29010000 {
    		compatible = "ti,am64-mailbox";
    		reg = <0x00 0x29010000 0x00 0x200>;
    		interrupts = <GIC_SPI 77 IRQ_TYPE_LEVEL_HIGH>;
    		#mbox-cells = <1>;
    		ti,mbox-num-users = <4>;
    		ti,mbox-num-fifos = <16>;
    	};
    
    	mailbox0_cluster2: mailbox@29020000 {
    		compatible = "ti,am64-mailbox";
    		reg = <0x00 0x29020000 0x00 0x200>;
    		interrupts = <GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH>;
    		#mbox-cells = <1>;
    		ti,mbox-num-users = <4>;
    		ti,mbox-num-fifos = <16>;
    	};
    
    	mailbox0_cluster3: mailbox@29030000 {
    		compatible = "ti,am64-mailbox";
    		reg = <0x00 0x29030000 0x00 0x200>;
    		interrupts = <GIC_SPI 109 IRQ_TYPE_LEVEL_HIGH>;
    		#mbox-cells = <1>;
    		ti,mbox-num-users = <4>;
    		ti,mbox-num-fifos = <16>;
    	};
    
    	ti_csi2rx0: ticsi2rx@30102000 {
    		compatible = "ti,j721e-csi2rx";
    		dmas = <&main_bcdma_csi 0 0x5000 0>, <&main_bcdma_csi 0 0x5001 0>,
    			<&main_bcdma_csi 0 0x5002 0>, <&main_bcdma_csi 0 0x5003 0>,
    			<&main_bcdma_csi 0 0x5004 0>, <&main_bcdma_csi 0 0x5005 0>;
    		dma-names = "rx0", "rx1", "rx2", "rx3", "rx4", "rx5";
    		reg = <0x00 0x30102000 0x00 0x1000>;
    		power-domains = <&k3_pds 182 TI_SCI_PD_EXCLUSIVE>;
    		#address-cells = <2>;
    		#size-cells = <2>;
    		ranges;
    
    		cdns_csi2rx0: csi-bridge@30101000 {
    			compatible = "cdns,csi2rx";
    			reg = <0x00 0x30101000 0x00 0x1000>;
    			clocks = <&k3_clks 182 0>, <&k3_clks 182 3>, <&k3_clks 182 0>,
    				<&k3_clks 182 0>, <&k3_clks 182 4>, <&k3_clks 182 4>;
    			clock-names = "sys_clk", "p_clk", "pixel_if0_clk",
    				"pixel_if1_clk", "pixel_if2_clk", "pixel_if3_clk";
    			phys = <&dphy0>;
    			phy-names = "dphy";
    			power-domains = <&k3_pds 182 TI_SCI_PD_EXCLUSIVE>;
    
    			ports {
    				#address-cells = <1>;
    				#size-cells = <0>;
    
    				csi0_port0: port@0 {
    					reg = <0>;
    				};
    
    				csi0_port1: port@1 {
    					reg = <1>;
    				};
    
    				csi0_port2: port@2 {
    					reg = <2>;
    				};
    
    				csi0_port3: port@3 {
    					reg = <3>;
    				};
    
    				csi0_port4: port@4 {
    					reg = <4>;
    				};
    			};
    		};
    	};
    
    	dphy0: phy@30110000 {
    		compatible = "ti,j721e-dphy", "cdns,dphy";
    		reg = <0x00 0x30110000 0x00 0x1100>;
    		#phy-cells = <0>;
    		power-domains = <&k3_pds 185 TI_SCI_PD_EXCLUSIVE>;
    	};
    
    	main_mcan0: can@20701000 {
    		compatible = "bosch,m_can";
    		reg = <0x00 0x20701000 0x00 0x200>,
    		      <0x00 0x20708000 0x00 0x8000>;
    		reg-names = "m_can", "message_ram";
    		power-domains = <&k3_pds 98 TI_SCI_PD_EXCLUSIVE>;
    		clocks = <&k3_clks 98 6>, <&k3_clks 98 1>;
    		clock-names = "hclk", "cclk";
    		interrupts = <GIC_SPI 155 IRQ_TYPE_LEVEL_HIGH>,
    			     <GIC_SPI 156 IRQ_TYPE_LEVEL_HIGH>;
    		interrupt-names = "int0", "int1";
    		bosch,mram-cfg = <0x0 128 64 64 64 64 32 32>;
    		status = "disabled";
    	};
    
    	epwm0: pwm@23000000 {
    		compatible = "ti,am64-epwm", "ti,am3352-ehrpwm";
    		#pwm-cells = <3>;
    		reg = <0x00 0x23000000 0x00 0x100>;
    		power-domains = <&k3_pds 86 TI_SCI_PD_EXCLUSIVE>;
    		clocks = <&epwm_tbclk 0>, <&k3_clks 86 0>;
    		clock-names = "tbclk", "fck";
    		status = "disabled";
    	};
    
    	epwm1: pwm@23010000 {
    		compatible = "ti,am64-epwm", "ti,am3352-ehrpwm";
    		#pwm-cells = <3>;
    		reg = <0x00 0x23010000 0x00 0x100>;
    		power-domains = <&k3_pds 87 TI_SCI_PD_EXCLUSIVE>;
    		clocks = <&epwm_tbclk 1>, <&k3_clks 87 0>;
    		clock-names = "tbclk", "fck";
    		status = "disabled";
    	};
    
    	epwm2: pwm@23020000 {
    		compatible = "ti,am64-epwm", "ti,am3352-ehrpwm";
    		#pwm-cells = <3>;
    		reg = <0x00 0x23020000 0x00 0x100>;
    		power-domains = <&k3_pds 88 TI_SCI_PD_EXCLUSIVE>;
    		clocks = <&epwm_tbclk 2>, <&k3_clks 88 0>;
    		clock-names = "tbclk", "fck";
    		status = "disabled";
    	};
    
    	ecap0: pwm@23100000 {
    		compatible = "ti,am3352-ecap";
    		#pwm-cells = <3>;
    		reg = <0x00 0x23100000 0x00 0x100>;
    		power-domains = <&k3_pds 51 TI_SCI_PD_EXCLUSIVE>;
    		clocks = <&k3_clks 51 0>;
    		clock-names = "fck";
    		status = "disabled";
    	};
    
    	ecap1: pwm@23110000 {
    		compatible = "ti,am3352-ecap";
    		#pwm-cells = <3>;
    		reg = <0x00 0x23110000 0x00 0x100>;
    		power-domains = <&k3_pds 52 TI_SCI_PD_EXCLUSIVE>;
    		clocks = <&k3_clks 52 0>;
    		clock-names = "fck";
    		status = "disabled";
    	};
    
    	ecap2: pwm@23120000 {
    		compatible = "ti,am3352-ecap";
    		#pwm-cells = <3>;
    		reg = <0x00 0x23120000 0x00 0x100>;
    		power-domains = <&k3_pds 53 TI_SCI_PD_EXCLUSIVE>;
    		clocks = <&k3_clks 53 0>;
    		clock-names = "fck";
    		status = "disabled";
    	};
    
    	mcasp0: mcasp@2b00000 {
    		compatible = "ti,am33xx-mcasp-audio";
    		reg = <0x00 0x02b00000 0x00 0x2000>,
    		      <0x00 0x02b08000 0x00 0x400>;
    		reg-names = "mpu","dat";
    		interrupts = <GIC_SPI 236 IRQ_TYPE_LEVEL_HIGH>,
    				<GIC_SPI 235 IRQ_TYPE_LEVEL_HIGH>;
    		interrupt-names = "tx", "rx";
    
    		dmas = <&main_bcdma 0 0xc500 0>, <&main_bcdma 0 0x4500 0>;
    		dma-names = "tx", "rx";
    
    		clocks = <&k3_clks 190 0>;
    		clock-names = "fck";
    		power-domains = <&k3_pds 190 TI_SCI_PD_EXCLUSIVE>;
    		assigned-clocks = <&k3_clks 190 0>;
    		assigned-clock-parents = <&k3_clks 190 2>;
    		status = "disabled";
    	};
    
    	mcasp1: mcasp@2b10000 {
    		compatible = "ti,am33xx-mcasp-audio";
    		reg = <0x00 0x02b10000 0x00 0x2000>,
    		      <0x00 0x02b18000 0x00 0x400>;
    		reg-names = "mpu","dat";
    		interrupts = <GIC_SPI 238 IRQ_TYPE_LEVEL_HIGH>,
    				<GIC_SPI 237 IRQ_TYPE_LEVEL_HIGH>;
    		interrupt-names = "tx", "rx";
    
    		dmas = <&main_bcdma 0 0xc501 0>, <&main_bcdma 0 0x4501 0>;
    		dma-names = "tx", "rx";
    
    		clocks = <&k3_clks 191 0>;
    		clock-names = "fck";
    		power-domains = <&k3_pds 191 TI_SCI_PD_EXCLUSIVE>;
    		assigned-clocks = <&k3_clks 191 0>;
    		assigned-clock-parents = <&k3_clks 191 2>;
    		status = "disabled";
    	};
    
    	mcasp2: mcasp@2b20000 {
    		compatible = "ti,am33xx-mcasp-audio";
    		reg = <0x00 0x02b20000 0x00 0x2000>,
    		      <0x00 0x02b28000 0x00 0x400>;
    		reg-names = "mpu","dat";
    		interrupts = <GIC_SPI 240 IRQ_TYPE_LEVEL_HIGH>,
    				<GIC_SPI 239 IRQ_TYPE_LEVEL_HIGH>;
    		interrupt-names = "tx", "rx";
    
    		dmas = <&main_bcdma 0 0xc502 0>, <&main_bcdma 0 0x4502 0>;
    		dma-names = "tx", "rx";
    
    		clocks = <&k3_clks 192 0>;
    		clock-names = "fck";
    		power-domains = <&k3_pds 192 TI_SCI_PD_EXCLUSIVE>;
    		assigned-clocks = <&k3_clks 192 0>;
    		assigned-clock-parents = <&k3_clks 192 2>;
    		status = "disabled";
    	};
    
    	c7x_0: dsp@7e000000 {
    		compatible = "ti,am62a-c7xv-dsp";
    		reg = <0x00 0x7e000000 0x00 0x00100000>;
    		reg-names = "l2sram";
    		ti,sci = <&dmsc>;
    		ti,sci-dev-id = <208>;
    		ti,sci-proc-ids = <0x04 0xff>;
    		resets = <&k3_reset 208 1>;
    		firmware-name = "am62a-c71_0-fw";
    	};
    };
    
    k3-am62a-main.dtsi

  • Hello Wu,

    Thank you for providing the files. Allow me sometime to go through them and follow up with you in sometime.

    Regards,

    Vaibhav

  • Hello Wu,

    Thank you for your patience.

    I went through your dts and dtsi files. Looks good to me. I am also assuming that k3-am62a-main.dtsi gets overwritten by k3-am62a7-sk,dts file as in the file k3-am62a-main.dtsi every instance has status as disbaled.

    Can you please match the frequency settings from MCU PLUS SDK MAIN_I2C1 configuration and MAIN_I2C2 master configuration?

    &main_i2c2 {
    status = "okay";
    pinctrl-names = "default";
    pinctrl-0 = <&main_i2c2_pins_default>;
    clock-frequency = <400000>;       -----------------------> Please update this to the frequency mentioned in the MCU PLUS SDK SysConfig configuration for MAIN_I2C1.
    };

    After his change can you rebuild the dtb and try again?

    Regards,

    Vaibhav