#include <stdint.h>
#include <stdbool.h>  
#include "I2CBUS.h"

// Define necessary macros (based on hw_i2c.h)
#ifndef I2C_MDR_IRS  // I2C Module Reset
#define I2C_MDR_IRS    0x20U    
#endif
#ifndef I2C_MDR_TRX   // Transmitter Mode
#define I2C_MDR_TRX    0x200U  
#endif
#ifndef I2C_MDR_MST   // Master Mode
#define I2C_MDR_MST    0x400U   
#endif
#ifndef I2C_FFTX_TXFFRST  // Transmit FIFO Reset
#define I2C_FFTX_TXFFRST 0x2000U 
#endif
#ifndef  I2C_FFRX_RXFFRST  // Receive FIFO Reset
#define I2C_FFRX_RXFFRST 0x2000U 
#endif

extern volatile uint16_t tick;

#define I2C_DEVICE_TIMEOUT 50   //MAX=65535 ms, now it is 50ms
#define I2C_MAX_RE_TRY     8    //Max 255
uint8_t I2CWriteRead(I2CBUS_t * pI2CObj);

#ifdef USE_I2C1
static uint8_t ReTry_1;
static uint16_t Delay_1 = 0;
I2C_Handle hi2c1;
#endif

#ifdef USE_I2C2
static uint8_t ReTry_2;
static uint16_t Delay_2 = 0;

I2C_Handle hi2c2;
#endif

#ifdef USE_I2C3
static uint8_t ReTry_3;
static uint16_t Delay_3 = 0;

I2C_Handle hi2c3;
#endif

#ifdef USE_I2C4
static uint8_t ReTry_4;
static uint16_t Delay_4 = 0;
I2C_Handle hi2c4;
#endif


/**
 * I2C Write-only/ Read-only/ Write-first and then read   Function
 * @param pI2CObj --- I2C Bus object
 * 
 * @return 
 * 0: Success
 * 1: Continue
 * negative: fail
 */
uint8_t I2CWriteRead(I2CBUS_t * pI2CObj) {
    switch (pI2CObj->state) {
        case 0:
            //prepare all I2C1 transaction REQUEST (TRB))
            if (1 == pI2CObj->I2C_Peripheral_No) {
#ifdef USE_I2C1                   
                if (pI2CObj->QTY4Write[pI2CObj->PresentSeqNo] > 0) {
                    //writing exists
                    if (pI2CObj->QTY4Read[pI2CObj->PresentSeqNo] > 0) {
                        //both writing and reading
                    	//if (I2C1_WriteRead(/*uint16_t address*/pI2CObj->I2CAddr[pI2CObj->PresentSeqNo] ,  /*uint8_t *writeData*/pI2CObj->pWriteData[pI2CObj->PresentSeqNo], /*size_t writeLength*/pI2CObj->QTY4Write[pI2CObj->PresentSeqNo],  /*uint8_t *readData*/pI2CObj->pReadData[pI2CObj->PresentSeqNo], /*size_t readLength*/pI2CObj->QTY4Read[pI2CObj->PresentSeqNo]) == false) {
                    	if (true !=HAL_I2C_Master_Seq_Transmit_then_Receive_IT(&hi2c1, (pI2CObj->I2CAddr[pI2CObj->PresentSeqNo]), pI2CObj->pWriteData[pI2CObj->PresentSeqNo], pI2CObj->QTY4Write[pI2CObj->PresentSeqNo], pI2CObj->pReadData[pI2CObj->PresentSeqNo], pI2CObj->QTY4Read[pI2CObj->PresentSeqNo])) {
                            //fail to request
                            return -1; //fail
                        }
                        else
                        {
                            //success to request
                        	Delay_1=0;
                            pI2CObj->state=2;
                        }
                        
                       
                    } else {
                        //no reading, so only writing
                    	//if (I2C1_Write(/*uint16_t address*/pI2CObj->I2CAddr[pI2CObj->PresentSeqNo], /*uint8_t *data*/pI2CObj->pWriteData[pI2CObj->PresentSeqNo], /*size_t dataLength*/pI2CObj->QTY4Write[pI2CObj->PresentSeqNo]) == false) {
                    	if (true != HAL_I2C_Master_Seq_Transmit_IT(&hi2c1, /*uint16_t DevAddress*/(pI2CObj->I2CAddr[pI2CObj->PresentSeqNo]), /*uint8_t *pData*/pI2CObj->pWriteData[pI2CObj->PresentSeqNo],
                                /*uint16_t Size*/ pI2CObj->QTY4Write[pI2CObj->PresentSeqNo], true)) {
                            //fail to request
                            return -1; //fail
                        }
                        else
                        {
                            //success to request
                        	Delay_1=0;
                            //pI2CObj->state++;
                        	pI2CObj->state=2;
                        }
                            
                       
                    }
                }
                else
                {
                    //no writing
                    if (pI2CObj->QTY4Read[pI2CObj->PresentSeqNo] > 0) {
                        //only reading
                    	//if (I2C1_Read(/*uint16_t address*/pI2CObj->I2CAddr[pI2CObj->PresentSeqNo], /*uint8_t* rdata*/pI2CObj->pReadData[pI2CObj->PresentSeqNo], /*size_t rlength*/pI2CObj->QTY4Read[pI2CObj->PresentSeqNo]) == false) {
                    	if (true != HAL_I2C_Master_Seq_Receive_IT(&hi2c1, /*uint16_t DevAddress*/(pI2CObj->I2CAddr[pI2CObj->PresentSeqNo]), /*uint8_t *pData */pI2CObj->pReadData[pI2CObj->PresentSeqNo],
                                /*uint16_t Size*/pI2CObj->QTY4Read[pI2CObj->PresentSeqNo],true)) {
                            //fail to request
                            return -1; //fail
                        }
                        else
                        {
                            //success to request
                        	Delay_1=0;
                            //pI2CObj->state++;
                        	pI2CObj->state=2;
                        }                        
                        
                    } else {
                        //no reading and no reading
                        return 0; //success because no need any action
                    }
                }                    

#else
                return -1;
#endif
            } else if (2 == pI2CObj->I2C_Peripheral_No) {
#ifdef USE_I2C2
                if (pI2CObj->QTY4Write[pI2CObj->PresentSeqNo] > 0) {
                    //writing exists
                    if (pI2CObj->QTY4Read[pI2CObj->PresentSeqNo] > 0) {
                        //both writing and reading
                        //if (I2C2_WriteRead(/*uint16_t address*/pI2CObj->I2CAddr[pI2CObj->PresentSeqNo] ,  /*uint8_t *writeData*/pI2CObj->pWriteData[pI2CObj->PresentSeqNo], /*size_t writeLength*/pI2CObj->QTY4Write[pI2CObj->PresentSeqNo],  /*uint8_t *readData*/pI2CObj->pReadData[pI2CObj->PresentSeqNo], /*size_t readLength*/pI2CObj->QTY4Read[pI2CObj->PresentSeqNo]) == false) {
                    	if (true !=HAL_I2C_Master_Seq_Transmit_then_Receive_IT(&hi2c2, (pI2CObj->I2CAddr[pI2CObj->PresentSeqNo]), pI2CObj->pWriteData[pI2CObj->PresentSeqNo], pI2CObj->QTY4Write[pI2CObj->PresentSeqNo], pI2CObj->pReadData[pI2CObj->PresentSeqNo], pI2CObj->QTY4Read[pI2CObj->PresentSeqNo])) {
                            //fail to request
                    		return -1; //fail
                        }
                        else
                        {
                            //success to request
                        	Delay_2=0;
                            pI2CObj->state=2;
                        }
                        
                       
                    } else {
                        //no reading, so only writing
                        //if (I2C2_Write(/*uint16_t address*/pI2CObj->I2CAddr[pI2CObj->PresentSeqNo], /*uint8_t *data*/pI2CObj->pWriteData[pI2CObj->PresentSeqNo], /*size_t dataLength*/pI2CObj->QTY4Write[pI2CObj->PresentSeqNo]) == false) {
                    	if (true != HAL_I2C_Master_Seq_Transmit_IT(&hi2c2, /*uint16_t DevAddress*/(pI2CObj->I2CAddr[pI2CObj->PresentSeqNo]), /*uint8_t *pData*/pI2CObj->pWriteData[pI2CObj->PresentSeqNo],
                    	                                /*uint16_t Size*/ pI2CObj->QTY4Write[pI2CObj->PresentSeqNo],true)) {
                            //fail to request
                            return -1; //fail
                        }
                        else
                        {
                            //success to request
                        	Delay_2 = 0;
                            pI2CObj->state=2;
                        }
                            
                       
                    }
                }
                else
                {
                    //no writing
                    if (pI2CObj->QTY4Read[pI2CObj->PresentSeqNo] > 0) {
                        //only reading
                        //if (I2C2_Read(/*uint16_t address*/pI2CObj->I2CAddr[pI2CObj->PresentSeqNo], /*uint8_t* rdata*/pI2CObj->pReadData[pI2CObj->PresentSeqNo], /*size_t rlength*/pI2CObj->QTY4Read[pI2CObj->PresentSeqNo]) == false) {
                    	if (true != HAL_I2C_Master_Seq_Receive_IT(&hi2c2, /*uint16_t DevAddress*/(pI2CObj->I2CAddr[pI2CObj->PresentSeqNo]), /*uint8_t *pData */pI2CObj->pReadData[pI2CObj->PresentSeqNo],
                    	                                /*uint16_t Size*/pI2CObj->QTY4Read[pI2CObj->PresentSeqNo],true)) {
                            //fail to request
                            return -1; //fail
                        }
                        else
                        {
                            //success to request
                        	Delay_2 = 0;
                            pI2CObj->state=2;
                        }                        
                        
                    } else {
                        //no reading and no reading
                        return 0; //success because no need any action
                    }
                }                    

#else
                return -1;
#endif
            } else if (3 == pI2CObj->I2C_Peripheral_No) {
#ifdef USE_I2C3     
                if (pI2CObj->QTY4Write[pI2CObj->PresentSeqNo] > 0) {
                    //writing exists
                    if (pI2CObj->QTY4Read[pI2CObj->PresentSeqNo] > 0) {
                        //both writing and reading
                        //if (I2C3_WriteRead(/*uint16_t address*/pI2CObj->I2CAddr[pI2CObj->PresentSeqNo] ,  /*uint8_t *writeData*/pI2CObj->pWriteData[pI2CObj->PresentSeqNo], /*size_t writeLength*/pI2CObj->QTY4Write[pI2CObj->PresentSeqNo],  /*uint8_t *readData*/pI2CObj->pReadData[pI2CObj->PresentSeqNo], /*size_t readLength*/pI2CObj->QTY4Read[pI2CObj->PresentSeqNo]) == false) {
                    	if (true !=HAL_I2C_Master_Seq_Transmit_then_Receive_IT(&hi2c3, (pI2CObj->I2CAddr[pI2CObj->PresentSeqNo]), pI2CObj->pWriteData[pI2CObj->PresentSeqNo], pI2CObj->QTY4Write[pI2CObj->PresentSeqNo], pI2CObj->pReadData[pI2CObj->PresentSeqNo], pI2CObj->QTY4Read[pI2CObj->PresentSeqNo])) {
                            //fail to request
                            return -1; //fail
                        }
                        else
                        {
                            //success to request
                        	Delay_3=0;
                            pI2CObj->state=2;
                        }
                        
                       
                    } else {
                        //no reading, so only writing
                        //if (I2C3_Write(/*uint16_t address*/pI2CObj->I2CAddr[pI2CObj->PresentSeqNo], /*uint8_t *data*/pI2CObj->pWriteData[pI2CObj->PresentSeqNo], /*size_t dataLength*/pI2CObj->QTY4Write[pI2CObj->PresentSeqNo]) == false) {
                    	if (true != HAL_I2C_Master_Seq_Transmit_IT(&hi2c3, /*uint16_t DevAddress*/(pI2CObj->I2CAddr[pI2CObj->PresentSeqNo]), /*uint8_t *pData*/pI2CObj->pWriteData[pI2CObj->PresentSeqNo],
                    	                                /*uint16_t Size*/ pI2CObj->QTY4Write[pI2CObj->PresentSeqNo],true)) {
                            //fail to request
                            Delay_3++;
                            return -1; //fail
                        }
                        else
                        {
                            //success to request
                        	Delay_3=0;
                            pI2CObj->state=2;
                        }
                            
                       
                    }
                }
                else
                {
                    //no writing
                    if (pI2CObj->QTY4Read[pI2CObj->PresentSeqNo] > 0) {
                        //only reading
                        //if (I2C3_Read(/*uint16_t address*/pI2CObj->I2CAddr[pI2CObj->PresentSeqNo], /*uint8_t* rdata*/pI2CObj->pReadData[pI2CObj->PresentSeqNo], /*size_t rlength*/pI2CObj->QTY4Read[pI2CObj->PresentSeqNo]) == false) {
                    	if (true != HAL_I2C_Master_Seq_Receive_IT(&hi2c3, /*uint16_t DevAddress*/(pI2CObj->I2CAddr[pI2CObj->PresentSeqNo]), /*uint8_t *pData */pI2CObj->pReadData[pI2CObj->PresentSeqNo],
                    	                                /*uint16_t Size*/pI2CObj->QTY4Read[pI2CObj->PresentSeqNo],true)) {
                            //fail to request
                            return -1; //fail
                        }
                        else
                        {
                            //success to request
                        	Delay_3=0;
                            pI2CObj->state=2;
                        }                        
                        
                    } else {
                        //no reading and no reading
                        return 0; //success because no need any action
                    }
                }                                 
                
#else
                return -1;
#endif
            } else if (4 == pI2CObj->I2C_Peripheral_No) {
#ifdef USE_I2C4                  
                if (pI2CObj->QTY4Write[pI2CObj->PresentSeqNo] > 0) {
                    //writing exists
                    if (pI2CObj->QTY4Read[pI2CObj->PresentSeqNo] > 0) {
                        //both writing and reading
                        //if (I2C4_WriteRead(/*uint16_t address*/pI2CObj->I2CAddr[pI2CObj->PresentSeqNo] ,  /*uint8_t *writeData*/pI2CObj->pWriteData[pI2CObj->PresentSeqNo], /*size_t writeLength*/pI2CObj->QTY4Write[pI2CObj->PresentSeqNo],  /*uint8_t *readData*/pI2CObj->pReadData[pI2CObj->PresentSeqNo], /*size_t readLength*/pI2CObj->QTY4Read[pI2CObj->PresentSeqNo]) == false) {
                    	if (true !=HAL_I2C_Master_Seq_Transmit_then_Receive_IT(&hi2c4, (pI2CObj->I2CAddr[pI2CObj->PresentSeqNo]), pI2CObj->pWriteData[pI2CObj->PresentSeqNo], pI2CObj->QTY4Write[pI2CObj->PresentSeqNo], pI2CObj->pReadData[pI2CObj->PresentSeqNo], pI2CObj->QTY4Read[pI2CObj->PresentSeqNo])) {
                            //fail to request
                            return -1; //fail
                        }
                        else
                        {
                            //success to request
                        	Delay_4 = 0;
                            pI2CObj->state=2;
                        }
                        
                       
                    } else {
                        //no reading, so only writing
                        //if (I2C4_Write(/*uint16_t address*/pI2CObj->I2CAddr[pI2CObj->PresentSeqNo], /*uint8_t *data*/pI2CObj->pWriteData[pI2CObj->PresentSeqNo], /*size_t dataLength*/pI2CObj->QTY4Write[pI2CObj->PresentSeqNo]) == false) {
                    	if (true != HAL_I2C_Master_Seq_Transmit_IT(&hi2c4, /*uint16_t DevAddress*/(pI2CObj->I2CAddr[pI2CObj->PresentSeqNo]), /*uint8_t *pData*/pI2CObj->pWriteData[pI2CObj->PresentSeqNo],
                    	                                /*uint16_t Size*/ pI2CObj->QTY4Write[pI2CObj->PresentSeqNo],true)) {
                            //fail to request
                            return -1; //fail
                        }
                        else
                        {
                            //success to request
                        	Delay_4 = 0;
                            pI2CObj->state=2;
                        }
                            
                       
                    }
                }
                else
                {
                    //no writing
                    if (pI2CObj->QTY4Read[pI2CObj->PresentSeqNo] > 0) {
                        //only reading
                        //if (I2C4_Read(/*uint16_t address*/pI2CObj->I2CAddr[pI2CObj->PresentSeqNo], /*uint8_t* rdata*/pI2CObj->pReadData[pI2CObj->PresentSeqNo], /*size_t rlength*/pI2CObj->QTY4Read[pI2CObj->PresentSeqNo]) == false) {
                    	if (true != HAL_I2C_Master_Seq_Receive_IT(&hi2c4, /*uint16_t DevAddress*/(pI2CObj->I2CAddr[pI2CObj->PresentSeqNo]), /*uint8_t *pData */pI2CObj->pReadData[pI2CObj->PresentSeqNo],
                    	                                /*uint16_t Size*/pI2CObj->QTY4Read[pI2CObj->PresentSeqNo],true)) {
                            //fail to request
                            return -1; //fail
                        }
                        else
                        {
                            //success to request
                        	Delay_4 = 0;
                            pI2CObj->state=2;
                        }                        
                        
                    } else {
                        //no reading and no reading
                        return 0; //success because no need any action
                    }
                }                
                                
#else                
                return -1;
#endif
            }
            return 1; //continue
            break;

        case 2:
            //Done?
            if (1 == pI2CObj->I2C_Peripheral_No) {
#ifdef USE_I2C1   
                if (!hi2c1.busy)
                {
                    if (hi2c1.Success) {
                        /* successfully done I2C Action */                    
                        pI2CObj->state = 0;
                        Delay_1 = 0;
                        ReTry_1=0;                        
                        return 0; //success
                    }
                    else {
                        //fail
                        if (ReTry_1 >= I2C_MAX_RE_TRY) {
                            pI2CObj->state = 0;
                            Delay_1=0;
                            ReTry_1=0;
                            return (-1); //fail
                        } else {
                            ReTry_1++;
                            pI2CObj->state = 0;
                            Delay_1 = 0;
                            return 1; //continue
                        }
                    }
                }                
                else
                {
                    /* progress in I2C Transaction */
                    Delay_1++;
                    if (Delay_1 < I2C_DEVICE_TIMEOUT) return 1;
                    if (ReTry_1 >= I2C_MAX_RE_TRY) {
                        pI2CObj->state = 0;
                        Delay_1=0;
                        ReTry_1=0;
                        hi2c1.busy=false;    
                        // Step 1: Abort controller
                        HWREGH(I2C1_SL_base + I2C_O_MDR) = 0x0000;
                        // Step 2: Clear status
                        #ifdef I2C1_USE_FIFO
                        I2C_clearInterruptStatus(I2C1_SL_base, I2C_INT_NO_ACK|I2C_INT_RX_DATA_RDY|I2C_INT_TX_DATA_RDY|I2C_INT_ARB_LOST|I2C_INT_RXFF|I2C_INT_TXFF|I2C_INT_STOP_CONDITION);
                        #else
                        I2C_clearInterruptStatus(I2C1_SL_base, I2C_INT_NO_ACK|I2C_INT_RX_DATA_RDY|I2C_INT_TX_DATA_RDY|I2C_INT_ARB_LOST|I2C_INT_STOP_CONDITION);
                        #endif       
                        return (-1); //fail
                    } else {
                        ReTry_1++;
                        pI2CObj->state = 0;
                        Delay_1 = 0;
                        hi2c1.busy=false;    
                        // Step 1: Abort controller
                        HWREGH(I2C1_SL_base + I2C_O_MDR) = 0x0000;
                        // Step 2: Clear status
                        #ifdef I2C1_USE_FIFO
                        I2C_clearInterruptStatus(I2C1_SL_base, I2C_INT_NO_ACK|I2C_INT_RX_DATA_RDY|I2C_INT_TX_DATA_RDY|I2C_INT_ARB_LOST|I2C_INT_RXFF|I2C_INT_TXFF|I2C_INT_STOP_CONDITION);
                        #else
                        I2C_clearInterruptStatus(I2C1_SL_base, I2C_INT_NO_ACK|I2C_INT_RX_DATA_RDY|I2C_INT_TX_DATA_RDY|I2C_INT_ARB_LOST|I2C_INT_STOP_CONDITION);
                        #endif       
                        return 1; //continue
                    }
                }              
                return 1; //continue
                
#else
                pI2CObj->state = 0;
                return -1;
#endif
            } else if (2 == pI2CObj->I2C_Peripheral_No) {
#ifdef USE_I2C2     
                if (!hi2c2.busy)
                {
                    if (hi2c2.Success) {
                        /* successfully done I2C Action */                    
                        pI2CObj->state = 0;
                        Delay_2 = 0;
                        ReTry_2=0;                                        
                        return 0; //success
                    }
                    else {
                        //fail
                        if (ReTry_2 >= I2C_MAX_RE_TRY) {
                            pI2CObj->state = 0;
                            Delay_2=0;
                            ReTry_2=0;
                            return (-1); //fail
                        } else {
                            ReTry_2++;
                            pI2CObj->state = 0;
                            Delay_2 = 0;
                            return 1; //continue
                        }
                    }
                }                
                else
                {
                    /* Progress in I2C Transaction */                    
                    Delay_2++;
                    if (Delay_2 < I2C_DEVICE_TIMEOUT) return 1;
                    if (ReTry_2 >= I2C_MAX_RE_TRY) {
                        pI2CObj->state = 0;
                        Delay_2=0;
                        ReTry_2=0;
                        hi2c2.busy=false;    
                        // Step 1: Abort controller
                        HWREGH(I2C2_SL_base + I2C_O_MDR) = 0x0000;
                        // Step 2: Clear status
                        #ifdef I2C2_USE_FIFO
                        I2C_clearInterruptStatus(I2C2_SL_base, I2C_INT_NO_ACK|I2C_INT_RX_DATA_RDY|I2C_INT_TX_DATA_RDY|I2C_INT_ARB_LOST|I2C_INT_RXFF|I2C_INT_TXFF|I2C_INT_STOP_CONDITION);
                        #else
                        I2C_clearInterruptStatus(I2C2_SL_base, I2C_INT_NO_ACK|I2C_INT_RX_DATA_RDY|I2C_INT_TX_DATA_RDY|I2C_INT_ARB_LOST|I2C_INT_STOP_CONDITION);
                        #endif      
                        return (-1); //fail
                    } else {
                        ReTry_2++;
                        pI2CObj->state = 0;
                        Delay_2 = 0;
                        hi2c2.busy=false;    
                        // Step 1: Abort controller
                        HWREGH(I2C2_SL_base + I2C_O_MDR) = 0x0000;
                        // Step 2: Clear status
                        #ifdef I2C2_USE_FIFO
                        I2C_clearInterruptStatus(I2C2_SL_base, I2C_INT_NO_ACK|I2C_INT_RX_DATA_RDY|I2C_INT_TX_DATA_RDY|I2C_INT_ARB_LOST|I2C_INT_RXFF|I2C_INT_TXFF|I2C_INT_STOP_CONDITION);
                        #else
                        I2C_clearInterruptStatus(I2C2_SL_base, I2C_INT_NO_ACK|I2C_INT_RX_DATA_RDY|I2C_INT_TX_DATA_RDY|I2C_INT_ARB_LOST|I2C_INT_STOP_CONDITION);
                        #endif      
                        return 1; //continue
                    }
                }              
                return 1; //continue                                               
#else
                pI2CObj->state = 0;
                return -1;
#endif
            } else if (3 == pI2CObj->I2C_Peripheral_No) {
#ifdef USE_I2C3 
                if (!hi2c3.busy)
                {
                    if (hi2c3.Success) {
                        /* successfully done I2C Action */                    
                        pI2CObj->state = 0;
                        Delay_3 = 0;
                        ReTry_3=0;
                        return 0; //success
                    }
                    else {
                        //fail
                        if (ReTry_3 >= I2C_MAX_RE_TRY) {
                            pI2CObj->state = 0;
                            Delay_3=0;
                            ReTry_3=0;
                            return (-1); //fail
                        } else {
                            ReTry_3++;
                            pI2CObj->state = 0;
                            Delay_3 = 0;
                            return 1; //continue
                        }
                    }
                }               
                else
                {
                    /* Progress in I2C Transaction */                    
                    Delay_3++;
                    if (Delay_3 < I2C_DEVICE_TIMEOUT) return 1;
                    if (ReTry_3 >= I2C_MAX_RE_TRY) {
                        pI2CObj->state = 0;
                        Delay_3=0;
                        ReTry_3=0;
                        hi2c3.busy=false;    
                        // Step 1: Abort controller
                        HWREGH(I2C3_SL_base + I2C_O_MDR) = 0x0000;
                        // Step 2: Clear status
                        #ifdef I2C3_USE_FIFO
                        I2C_clearInterruptStatus(I2C3_SL_base, I2C_INT_NO_ACK|I2C_INT_RX_DATA_RDY|I2C_INT_TX_DATA_RDY|I2C_INT_ARB_LOST|I2C_INT_RXFF|I2C_INT_TXFF|I2C_INT_STOP_CONDITION);
                        #else
                        I2C_clearInterruptStatus(I2C3_SL_base, I2C_INT_NO_ACK|I2C_INT_RX_DATA_RDY|I2C_INT_TX_DATA_RDY|I2C_INT_ARB_LOST|I2C_INT_STOP_CONDITION);
                        #endif      
                        return (-1); //fail
                    } else {
                        ReTry_3++;
                        pI2CObj->state = 0;
                        Delay_3 = 0;
                        hi2c3.busy=false;    
                        // Step 1: Abort controller
                        HWREGH(I2C3_SL_base + I2C_O_MDR) = 0x0000;
                        // Step 2: Clear status
                        #ifdef I2C3_USE_FIFO
                        I2C_clearInterruptStatus(I2C3_SL_base, I2C_INT_NO_ACK|I2C_INT_RX_DATA_RDY|I2C_INT_TX_DATA_RDY|I2C_INT_ARB_LOST|I2C_INT_RXFF|I2C_INT_TXFF|I2C_INT_STOP_CONDITION);
                        #else
                        I2C_clearInterruptStatus(I2C3_SL_base, I2C_INT_NO_ACK|I2C_INT_RX_DATA_RDY|I2C_INT_TX_DATA_RDY|I2C_INT_ARB_LOST|I2C_INT_STOP_CONDITION);
                        #endif      
                        return 1; //continue
                    }
                }              
                return 1; //continue         
#else
                pI2CObj->state = 0;
                return -1;
#endif
            } else if (4 == pI2CObj->I2C_Peripheral_No) {
#ifdef USE_I2C4 
                if (!hi2c4.busy)
                {
                    if (hi2c4.Success) {
                        /* successfully done I2C Action */                    
                        pI2CObj->state = 0;
                        Delay_4 = 0;
                        ReTry_4=0;
                        return 0; //success
                    }
                    else {
                        //fail
                        if (ReTry_4 >= I2C_MAX_RE_TRY) {
                            pI2CObj->state = 0;
                            Delay_4=0;
                            ReTry_4=0;
                            return (-1); //fail
                        } else {
                            ReTry_4++;
                            pI2CObj->state = 0;
                            Delay_4 = 0;
                            return 1; //continue
                        }
                    }
                }                
                else
                {
                    /* Progress in I2C Transaction */                    
                    Delay_4++;
                    if (Delay_4 < I2C_DEVICE_TIMEOUT) return 1;
                    if (ReTry_4 >= I2C_MAX_RE_TRY) {
                        pI2CObj->state = 0;
                        Delay_4=0;
                        ReTry_4=0;
                        hi2c4.busy=false;    
                        // Step 1: Abort controller
                        HWREGH(I2C4_SL_base + I2C_O_MDR) = 0x0000;
                        // Step 2: Clear status
                        #ifdef I2C4_USE_FIFO
                        I2C_clearInterruptStatus(I2C4_SL_base, I2C_INT_NO_ACK|I2C_INT_RX_DATA_RDY|I2C_INT_TX_DATA_RDY|I2C_INT_ARB_LOST|I2C_INT_RXFF|I2C_INT_TXFF|I2C_INT_STOP_CONDITION);
                        #else
                        I2C_clearInterruptStatus(I2C4_SL_base, I2C_INT_NO_ACK|I2C_INT_RX_DATA_RDY|I2C_INT_TX_DATA_RDY|I2C_INT_ARB_LOST|I2C_INT_STOP_CONDITION);
                        #endif      
                        return (-1); //fail
                    } else {
                        ReTry_4++;
                        pI2CObj->state = 0;
                        Delay_4 = 0;
                        hi2c4.busy=false;    
                        // Step 1: Abort controller
                        HWREGH(I2C4_SL_base + I2C_O_MDR) = 0x0000;
                        // Step 2: Clear status
                        #ifdef I2C4_USE_FIFO
                        I2C_clearInterruptStatus(I2C4_SL_base, I2C_INT_NO_ACK|I2C_INT_RX_DATA_RDY|I2C_INT_TX_DATA_RDY|I2C_INT_ARB_LOST|I2C_INT_RXFF|I2C_INT_TXFF|I2C_INT_STOP_CONDITION);
                        #else
                        I2C_clearInterruptStatus(I2C4_SL_base, I2C_INT_NO_ACK|I2C_INT_RX_DATA_RDY|I2C_INT_TX_DATA_RDY|I2C_INT_ARB_LOST|I2C_INT_STOP_CONDITION);
                        #endif     
                        return 1; //continue
                    }
                }              
                return 1; //continue                  
                
#else           
                pI2CObj->state = 0;
                return -1;
#endif
            }

    }
    return 1;
}


bool HAL_I2C_Master_Seq_Transmit_IT(I2C_Handle * hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size, bool NeedStopEnd) 
{
    if (1 == hi2c->I2C_Peripheral_No) {
        #if defined(USE_I2C1) 
        if (hi2c->busy) return false;       
        hi2c->pBuffPtr=pData;
        hi2c->XferSize=Size;
        hi2c->XferCount =0;
        hi2c->needLastStop=NeedStopEnd;
        hi2c->Success=false;
        hi2c->isRead=false;
        hi2c->busy=true;       
        hi2c->numofSixteenByte  = (hi2c->XferSize) / I2C1_FIFO_DEEP;  
        hi2c->remainingBytes    = (hi2c->XferSize) % I2C1_FIFO_DEEP;

        
        #ifdef I2C1_USE_FIFO
            //FIFO version
//##########################
// --- CRITICAL FINAL FIX: FORCE MODULE AND FIFO STATE RESET ---

// --- MINIMAL HIGH-LEVEL PRE-TRANSACTION RESET ---

// 1. Save and disable the module (IRS=0)
uint16_t mdR_config = HWREGH(I2C1_SL_base + I2C_O_MDR); 
HWREGH(I2C1_SL_base + I2C_O_MDR) &= ~I2C_MDR_IRS; // Disable Module

// 2. Re-enable the module (IRS=1) with the full Master Transmit config
// This restores the I2C module's state machine to a known-good start state.
HWREGH(I2C1_SL_base + I2C_O_MDR) = I2C_MDR_MST | I2C_MDR_IRS | I2C_MDR_TRX; // Re-enable

// --- END OF MINIMAL FIX ---
//#####################            
            I2C_clearInterruptStatus(I2C1_SL_base, I2C_INT_ARB_LOST | I2C_INT_NO_ACK);
            I2C_setFIFOInterruptLevel(I2C1_SL_base, I2C_FIFO_TXEMPTY, I2C_FIFO_RX2);  //For transmit, rx threshold does not matter
            I2C_enableInterrupt(I2C1_SL_base, I2C_INT_ADDR_TARGET | I2C_INT_ARB_LOST | I2C_INT_NO_ACK | I2C_INT_STOP_CONDITION);
            I2C_disableInterrupt(I2C1_SL_base, I2C_INT_TX_DATA_RDY);
            I2C_disableInterrupt(I2C1_SL_base, I2C_INT_RX_DATA_RDY);

            I2C_enableFIFO(I2C1_SL_base);         
            if(I2C_isBusBusy(I2C1_SL_base))
            {
                hi2c->busy=false;
                return false;
            }   
            if(I2C_getStopConditionStatus(I2C1_SL_base))
            {
                hi2c->busy=false;
                return false;
            }
            I2C_disableFIFO(I2C1_SL_base);
            I2C_setConfig(I2C1_SL_base, (I2C_CONTROLLER_SEND_MODE));
            if (DevAddress<128)
                I2C_setAddressMode(I2C1_SL_base, I2C_ADDR_MODE_7BITS);
            else
                I2C_setAddressMode(I2C1_SL_base, I2C_ADDR_MODE_10BITS);
            I2C_setTargetAddress(I2C1_SL_base, DevAddress);
            I2C_setBitCount(I2C1_SL_base, I2C_BITCOUNT_8);    
            I2C_setDataCount(I2C1_SL_base, 0);
            I2C_enableFIFO(I2C1_SL_base);                   
            I2C_sendStartCondition(I2C1_SL_base);
            
            I2C_setDataCount(I2C1_SL_base, hi2c->XferSize);        

            I2C_setFIFOInterruptLevel(I2C1_SL_base, I2C_FIFO_TXEMPTY, I2C_FIFO_RXFULL);  //For transmit, rx threshold does not matter

            I2C_enableInterrupt(I2C1_SL_base, (I2C_INT_STOP_CONDITION | I2C_INT_ARB_LOST | I2C_INT_NO_ACK));
            I2C_enableInterrupt(I2C1_SL_base, I2C_INT_TXFF);
            I2C_clearInterruptStatus(I2C1_SL_base, I2C_INT_TXFF);


	                  
        #else
            //Non fifo version  
            I2C_clearInterruptStatus(I2C1_SL_base, I2C_INT_ARB_LOST | I2C_INT_NO_ACK);
            I2C_enableInterrupt(I2C1_SL_base, I2C_INT_ADDR_TARGET | I2C_INT_ARB_LOST | I2C_INT_NO_ACK | I2C_INT_STOP_CONDITION);            
            //I2C_setTargetAddress(I2C1_SL_base, DevAddress);
            I2C_setConfig(I2C1_SL_base, I2C_CONTROLLER_SEND_MODE |I2C_REPEAT_MODE );   
            //I2C_setDataCount(I2C1_SL_base, hi2c->XferSize);
            I2C_setBitCount(I2C1_SL_base, I2C_BITCOUNT_8);        
            if (DevAddress<128)
                I2C_setAddressMode(I2C1_SL_base, I2C_ADDR_MODE_7BITS);
            else
                I2C_setAddressMode(I2C1_SL_base, I2C_ADDR_MODE_10BITS);
            I2C_setTargetAddress(I2C1_SL_base, DevAddress);
            I2C_setDataCount(I2C1_SL_base, hi2c->XferSize);
            //I2C_clearInterruptStatus(I2C1_SL_base, I2C_INT_NO_ACK | I2C_INT_RX_DATA_RDY | I2C_INT_TX_DATA_RDY);                  
            I2C_putData(I2C1_SL_base, hi2c->pBuffPtr[hi2c->XferCount++]);            

            I2C_enableInterrupt(I2C1_SL_base, (I2C_INT_STOP_CONDITION | I2C_INT_ARB_LOST | I2C_INT_NO_ACK));
            I2C_enableInterrupt(I2C1_SL_base, I2C_INT_TX_DATA_RDY);
            //I2C_clearInterruptStatus(I2C1_SL_base, I2C_INT_TX_DATA_RDY);
            I2C_sendStartCondition(I2C1_SL_base);
           
        #endif        
        #else
        return false;
        #endif
        return true;
    }
    else if (2 == hi2c->I2C_Peripheral_No) {
        #if defined(USE_I2C2) 
        if (hi2c->busy) return false;       
        hi2c->pBuffPtr=pData;
        hi2c->XferSize=Size;
        hi2c->XferCount =0;
        hi2c->needLastStop=NeedStopEnd;
        hi2c->Success=false;
        hi2c->isRead=false;
        hi2c->busy=true;       
        hi2c->numofSixteenByte  = (hi2c->XferSize) / I2C2_FIFO_DEEP;  
        hi2c->remainingBytes    = (hi2c->XferSize) % I2C2_FIFO_DEEP;
        
        #ifdef I2C2_USE_FIFO
            //FIFO version
//##########################
// --- CRITICAL FINAL FIX: FORCE MODULE AND FIFO STATE RESET ---

// --- MINIMAL HIGH-LEVEL PRE-TRANSACTION RESET ---

// 1. Save and disable the module (IRS=0)
uint16_t mdR_config = HWREGH(I2C2_SL_base + I2C_O_MDR); 
HWREGH(I2C2_SL_base + I2C_O_MDR) &= ~I2C_MDR_IRS; // Disable Module

// 2. Re-enable the module (IRS=1) with the full Master Transmit config
// This restores the I2C module's state machine to a known-good start state.
HWREGH(I2C2_SL_base + I2C_O_MDR) = I2C_MDR_MST | I2C_MDR_IRS | I2C_MDR_TRX; // Re-enable

// --- END OF MINIMAL FIX ---
//#####################
            I2C_clearInterruptStatus(I2C2_SL_base, I2C_INT_ARB_LOST | I2C_INT_NO_ACK);
            I2C_setFIFOInterruptLevel(I2C2_SL_base, I2C_FIFO_TXEMPTY, I2C_FIFO_RX2);  //For transmit, rx threshold does not matter
            I2C_enableInterrupt(I2C2_SL_base, I2C_INT_ADDR_TARGET | I2C_INT_ARB_LOST | I2C_INT_NO_ACK | I2C_INT_STOP_CONDITION);
            I2C_disableInterrupt(I2C2_SL_base, I2C_INT_TX_DATA_RDY);
            I2C_disableInterrupt(I2C2_SL_base, I2C_INT_RX_DATA_RDY);

            I2C_enableFIFO(I2C2_SL_base);         
            if(I2C_isBusBusy(I2C2_SL_base))
            {
                hi2c->busy=false;
                return false;
            }   
            if(I2C_getStopConditionStatus(I2C2_SL_base))
            {
                hi2c->busy=false;
                return false;
            }
            I2C_disableFIFO(I2C2_SL_base);
            I2C_setConfig(I2C2_SL_base, (I2C_CONTROLLER_SEND_MODE));
            if (DevAddress<128)
                I2C_setAddressMode(I2C2_SL_base, I2C_ADDR_MODE_7BITS);
            else
                I2C_setAddressMode(I2C2_SL_base, I2C_ADDR_MODE_10BITS);
            I2C_setTargetAddress(I2C2_SL_base, DevAddress);
            I2C_setBitCount(I2C2_SL_base, I2C_BITCOUNT_8);    
            I2C_setDataCount(I2C2_SL_base, 0);
            I2C_enableFIFO(I2C2_SL_base);                   
            I2C_sendStartCondition(I2C2_SL_base);
            
            I2C_setDataCount(I2C2_SL_base, hi2c->XferSize);        

            I2C_setFIFOInterruptLevel(I2C2_SL_base, I2C_FIFO_TXEMPTY, I2C_FIFO_RXFULL);  //For transmit, rx threshold does not matter

            I2C_enableInterrupt(I2C2_SL_base, (I2C_INT_STOP_CONDITION | I2C_INT_ARB_LOST | I2C_INT_NO_ACK));
            I2C_enableInterrupt(I2C2_SL_base, I2C_INT_TXFF);
            I2C_clearInterruptStatus(I2C2_SL_base, I2C_INT_TXFF);


	                  
        #else
            //Non fifo version  
            I2C_clearInterruptStatus(I2C2_SL_base, I2C_INT_ARB_LOST | I2C_INT_NO_ACK);
            I2C_enableInterrupt(I2C2_SL_base, I2C_INT_ADDR_TARGET | I2C_INT_ARB_LOST | I2C_INT_NO_ACK | I2C_INT_STOP_CONDITION);            
            //I2C_setTargetAddress(I2C2_SL_base, DevAddress);
            I2C_setConfig(I2C2_SL_base, I2C_CONTROLLER_SEND_MODE |I2C_REPEAT_MODE);   
            //I2C_setDataCount(I2C2_SL_base, hi2c->XferSize);
            I2C_setBitCount(I2C2_SL_base, I2C_BITCOUNT_8);        
            if (DevAddress<128)
                I2C_setAddressMode(I2C2_SL_base, I2C_ADDR_MODE_7BITS);
            else
                I2C_setAddressMode(I2C2_SL_base, I2C_ADDR_MODE_10BITS);
            I2C_setTargetAddress(I2C2_SL_base, DevAddress);
            I2C_setDataCount(I2C2_SL_base, hi2c->XferSize);
            //I2C_clearInterruptStatus(I2C2_SL_base, I2C_INT_NO_ACK | I2C_INT_RX_DATA_RDY | I2C_INT_TX_DATA_RDY);                  
            I2C_putData(I2C2_SL_base, hi2c->pBuffPtr[hi2c->XferCount++]);            

            I2C_enableInterrupt(I2C2_SL_base, (I2C_INT_STOP_CONDITION | I2C_INT_ARB_LOST | I2C_INT_NO_ACK));
            I2C_enableInterrupt(I2C2_SL_base, I2C_INT_TX_DATA_RDY);
            //I2C_clearInterruptStatus(I2C2_SL_base, I2C_INT_TX_DATA_RDY);
            I2C_sendStartCondition(I2C2_SL_base);
           
           
        #endif        
        #else
        return false;
        #endif
        return true;
    }
    else if (3 == hi2c->I2C_Peripheral_No) {
        #if defined(USE_I2C3) 
        if (hi2c->busy) return false;       
        hi2c->pBuffPtr=pData;
        hi2c->XferSize=Size;
        hi2c->XferCount =0;
        hi2c->needLastStop=NeedStopEnd;
        hi2c->Success=false;
        hi2c->isRead=false;
        hi2c->busy=true;       
        hi2c->numofSixteenByte  = (hi2c->XferSize) / I2C3_FIFO_DEEP;  
        hi2c->remainingBytes    = (hi2c->XferSize) % I2C3_FIFO_DEEP;
        
        #ifdef I2C3_USE_FIFO
            //FIFO version
//##########################
// --- CRITICAL FINAL FIX: FORCE MODULE AND FIFO STATE RESET ---

// --- MINIMAL HIGH-LEVEL PRE-TRANSACTION RESET ---

// 1. Save and disable the module (IRS=0)
uint16_t mdR_config = HWREGH(I2C3_SL_base + I2C_O_MDR); 
HWREGH(I2C3_SL_base + I2C_O_MDR) &= ~I2C_MDR_IRS; // Disable Module

// 2. Re-enable the module (IRS=1) with the full Master Transmit config
// This restores the I2C module's state machine to a known-good start state.
HWREGH(I2C3_SL_base + I2C_O_MDR) = I2C_MDR_MST | I2C_MDR_IRS | I2C_MDR_TRX; // Re-enable

// --- END OF MINIMAL FIX ---
//#####################            
            I2C_clearInterruptStatus(I2C3_SL_base, I2C_INT_ARB_LOST | I2C_INT_NO_ACK);
            I2C_setFIFOInterruptLevel(I2C3_SL_base, I2C_FIFO_TXEMPTY, I2C_FIFO_RX2);  //For transmit, rx threshold does not matter
            I2C_enableInterrupt(I2C3_SL_base, I2C_INT_ADDR_TARGET | I2C_INT_ARB_LOST | I2C_INT_NO_ACK | I2C_INT_STOP_CONDITION);
            I2C_disableInterrupt(I2C3_SL_base, I2C_INT_TX_DATA_RDY);
            I2C_disableInterrupt(I2C3_SL_base, I2C_INT_RX_DATA_RDY);

            I2C_enableFIFO(I2C3_SL_base);         
            if(I2C_isBusBusy(I2C3_SL_base))
            {
                hi2c->busy=false;
                return false;
            }   
            if(I2C_getStopConditionStatus(I2C3_SL_base))
            {
                hi2c->busy=false;
                return false;
            }
            I2C_disableFIFO(I2C3_SL_base);
            I2C_setConfig(I2C3_SL_base, (I2C_CONTROLLER_SEND_MODE));
            if (DevAddress<128)
                I2C_setAddressMode(I2C3_SL_base, I2C_ADDR_MODE_7BITS);
            else
                I2C_setAddressMode(I2C3_SL_base, I2C_ADDR_MODE_10BITS);
            I2C_setTargetAddress(I2C3_SL_base, DevAddress);
            I2C_setBitCount(I2C3_SL_base, I2C_BITCOUNT_8);    
            I2C_setDataCount(I2C3_SL_base, 0);
            I2C_enableFIFO(I2C3_SL_base);                   
            I2C_sendStartCondition(I2C3_SL_base);
            
            I2C_setDataCount(I2C3_SL_base, hi2c->XferSize);        

            I2C_setFIFOInterruptLevel(I2C3_SL_base, I2C_FIFO_TXEMPTY, I2C_FIFO_RXFULL);  //For transmit, rx threshold does not matter

            I2C_enableInterrupt(I2C3_SL_base, (I2C_INT_STOP_CONDITION | I2C_INT_ARB_LOST | I2C_INT_NO_ACK));
            I2C_enableInterrupt(I2C3_SL_base, I2C_INT_TXFF);
            I2C_clearInterruptStatus(I2C3_SL_base, I2C_INT_TXFF);


	                  
        #else
            //Non fifo version  
            I2C_clearInterruptStatus(I2C3_SL_base, I2C_INT_ARB_LOST | I2C_INT_NO_ACK);
            I2C_enableInterrupt(I2C3_SL_base, I2C_INT_ADDR_TARGET | I2C_INT_ARB_LOST | I2C_INT_NO_ACK | I2C_INT_STOP_CONDITION);            
            //I2C_setTargetAddress(I2C3_SL_base, DevAddress);
            I2C_setConfig(I2C3_SL_base, I2C_CONTROLLER_SEND_MODE |I2C_REPEAT_MODE);   
            //I2C_setDataCount(I2C3_SL_base, hi2c->XferSize);
            I2C_setBitCount(I2C3_SL_base, I2C_BITCOUNT_8);        
            if (DevAddress<128)
                I2C_setAddressMode(I2C3_SL_base, I2C_ADDR_MODE_7BITS);
            else
                I2C_setAddressMode(I2C3_SL_base, I2C_ADDR_MODE_10BITS);
            I2C_setTargetAddress(I2C3_SL_base, DevAddress);
            I2C_setDataCount(I2C3_SL_base, hi2c->XferSize);
            //I2C_clearInterruptStatus(I2C3_SL_base, I2C_INT_NO_ACK | I2C_INT_RX_DATA_RDY | I2C_INT_TX_DATA_RDY);                  
            I2C_putData(I2C3_SL_base, hi2c->pBuffPtr[hi2c->XferCount++]);            

            I2C_enableInterrupt(I2C3_SL_base, (I2C_INT_STOP_CONDITION | I2C_INT_ARB_LOST | I2C_INT_NO_ACK));
            I2C_enableInterrupt(I2C3_SL_base, I2C_INT_TX_DATA_RDY);
            //I2C_clearInterruptStatus(I2C3_SL_base, I2C_INT_TX_DATA_RDY);
            I2C_sendStartCondition(I2C3_SL_base);
           
        #endif        
        #else
        return false;
        #endif
        return true;
    }
    else if (4 == hi2c->I2C_Peripheral_No) {
        #if defined(USE_I2C4) 
        if (hi2c->busy) return false;       
        hi2c->pBuffPtr=pData;
        hi2c->XferSize=Size;
        hi2c->XferCount =0;
        hi2c->needLastStop=NeedStopEnd;
        hi2c->Success=false;
        hi2c->isRead=false;
        hi2c->busy=true;       
        hi2c->numofSixteenByte  = (hi2c->XferSize) / I2C4_FIFO_DEEP;  
        hi2c->remainingBytes    = (hi2c->XferSize) % I2C4_FIFO_DEEP;
        
        #ifdef I2C4_USE_FIFO
            //FIFO version
//##########################
// --- CRITICAL FINAL FIX: FORCE MODULE AND FIFO STATE RESET ---

// --- MINIMAL HIGH-LEVEL PRE-TRANSACTION RESET ---

// 1. Save and disable the module (IRS=0)
uint16_t mdR_config = HWREGH(I2C4_SL_base + I2C_O_MDR); 
HWREGH(I2C4_SL_base + I2C_O_MDR) &= ~I2C_MDR_IRS; // Disable Module

// 2. Re-enable the module (IRS=1) with the full Master Transmit config
// This restores the I2C module's state machine to a known-good start state.
HWREGH(I2C4_SL_base + I2C_O_MDR) = I2C_MDR_MST | I2C_MDR_IRS | I2C_MDR_TRX; // Re-enable

// --- END OF MINIMAL FIX ---
//#####################            
            I2C_clearInterruptStatus(I2C4_SL_base, I2C_INT_ARB_LOST | I2C_INT_NO_ACK);
            I2C_setFIFOInterruptLevel(I2C4_SL_base, I2C_FIFO_TXEMPTY, I2C_FIFO_RX2);  //For transmit, rx threshold does not matter
            I2C_enableInterrupt(I2C4_SL_base, I2C_INT_ADDR_TARGET | I2C_INT_ARB_LOST | I2C_INT_NO_ACK | I2C_INT_STOP_CONDITION);
            I2C_disableInterrupt(I2C4_SL_base, I2C_INT_TX_DATA_RDY);
            I2C_disableInterrupt(I2C4_SL_base, I2C_INT_RX_DATA_RDY);

            I2C_enableFIFO(I2C4_SL_base);         
            if(I2C_isBusBusy(I2C4_SL_base))
            {
                hi2c->busy=false;
                return false;
            }   
            if(I2C_getStopConditionStatus(I2C4_SL_base))
            {
                hi2c->busy=false;
                return false;
            }
            I2C_disableFIFO(I2C4_SL_base);
            I2C_setConfig(I2C4_SL_base, (I2C_CONTROLLER_SEND_MODE));
            if (DevAddress<128)
                I2C_setAddressMode(I2C4_SL_base, I2C_ADDR_MODE_7BITS);
            else
                I2C_setAddressMode(I2C4_SL_base, I2C_ADDR_MODE_10BITS);
            I2C_setTargetAddress(I2C4_SL_base, DevAddress);
            I2C_setBitCount(I2C4_SL_base, I2C_BITCOUNT_8);    
            I2C_setDataCount(I2C4_SL_base, 0);
            I2C_enableFIFO(I2C4_SL_base);                   
            I2C_sendStartCondition(I2C4_SL_base);
            
            I2C_setDataCount(I2C4_SL_base, hi2c->XferSize);        

            I2C_setFIFOInterruptLevel(I2C4_SL_base, I2C_FIFO_TXEMPTY, I2C_FIFO_RXFULL);  //For transmit, rx threshold does not matter

            I2C_enableInterrupt(I2C4_SL_base, (I2C_INT_STOP_CONDITION | I2C_INT_ARB_LOST | I2C_INT_NO_ACK));
            I2C_enableInterrupt(I2C4_SL_base, I2C_INT_TXFF);
            I2C_clearInterruptStatus(I2C4_SL_base, I2C_INT_TXFF);


	                  
        #else
            //Non fifo version  
            I2C_clearInterruptStatus(I2C4_SL_base, I2C_INT_ARB_LOST | I2C_INT_NO_ACK);
            I2C_enableInterrupt(I2C4_SL_base, I2C_INT_ADDR_TARGET | I2C_INT_ARB_LOST | I2C_INT_NO_ACK | I2C_INT_STOP_CONDITION);            
            //I2C_setTargetAddress(I2C4_SL_base, DevAddress);
            I2C_setConfig(I2C4_SL_base, I2C_CONTROLLER_SEND_MODE |I2C_REPEAT_MODE);   
            //I2C_setDataCount(I2C4_SL_base, hi2c->XferSize);
            I2C_setBitCount(I2C4_SL_base, I2C_BITCOUNT_8);        
            if (DevAddress<128)
                I2C_setAddressMode(I2C4_SL_base, I2C_ADDR_MODE_7BITS);
            else
                I2C_setAddressMode(I2C4_SL_base, I2C_ADDR_MODE_10BITS);
            I2C_setTargetAddress(I2C4_SL_base, DevAddress);
            I2C_setDataCount(I2C4_SL_base, hi2c->XferSize);
            //I2C_clearInterruptStatus(I2C4_SL_base, I2C_INT_NO_ACK | I2C_INT_RX_DATA_RDY | I2C_INT_TX_DATA_RDY);                  
            I2C_putData(I2C4_SL_base, hi2c->pBuffPtr[hi2c->XferCount++]);            

            I2C_enableInterrupt(I2C4_SL_base, (I2C_INT_STOP_CONDITION | I2C_INT_ARB_LOST | I2C_INT_NO_ACK));
            I2C_enableInterrupt(I2C4_SL_base, I2C_INT_TX_DATA_RDY);
            //I2C_clearInterruptStatus(I2C4_SL_base, I2C_INT_TX_DATA_RDY);
            I2C_sendStartCondition(I2C4_SL_base);
           
        #endif        
        #else
        return false;
        #endif
        return true;
    }

}
bool HAL_I2C_Master_Seq_Receive_IT(I2C_Handle *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size, bool NeedStopEnd)
{
    if (1 == hi2c->I2C_Peripheral_No) {
        #if defined(USE_I2C1) 
        if (hi2c->busy) return false;       
        hi2c->pBuffPtr=pData;
        hi2c->XferSize=Size;
        hi2c->XferCount =0;
        hi2c->needLastStop=NeedStopEnd;
        hi2c->Success=false;
        hi2c->isRead=true;
        hi2c->busy=true;

        hi2c->numofSixteenByte  = (hi2c->XferSize) / I2C1_FIFO_DEEP;  
        hi2c->remainingBytes    = (hi2c->XferSize) % I2C1_FIFO_DEEP;

        
       if (DevAddress<128)
            I2C_setAddressMode(I2C1_SL_base, I2C_ADDR_MODE_7BITS);
        else
            I2C_setAddressMode(I2C1_SL_base, I2C_ADDR_MODE_10BITS);
        I2C_setTargetAddress(I2C1_SL_base, DevAddress);    
        if(I2C_isBusBusy(I2C1_SL_base))
        {
            hi2c->busy=false;
            return false;
        }   
        if(I2C_getStopConditionStatus(I2C1_SL_base))
        {
            hi2c->busy=false;
            return false;
        }    
        #ifdef I2C1_USE_FIFO
            //FIFO version           
//##########################
// --- CRITICAL FINAL FIX: FORCE MODULE AND FIFO STATE RESET ---

// --- MINIMAL HIGH-LEVEL PRE-TRANSACTION RESET ---

// 1. Save and disable the module (IRS=0)
uint16_t mdR_config = HWREGH(I2C1_SL_base + I2C_O_MDR); 
HWREGH(I2C1_SL_base + I2C_O_MDR) &= ~I2C_MDR_IRS; // Disable Module

// 2. Re-enable the module (IRS=1) with the full Master Transmit config
// This restores the I2C module's state machine to a known-good start state.
HWREGH(I2C1_SL_base + I2C_O_MDR) = I2C_MDR_MST | I2C_MDR_IRS | I2C_MDR_TRX; // Re-enable

// --- END OF MINIMAL FIX ---
//#####################                          
            I2C_disableInterrupt(I2C1_SL_base, I2C_INT_REG_ACCESS_RDY);
            I2C_disableInterrupt(I2C1_SL_base, I2C_INT_TXFF);
            I2C_disableInterrupt(I2C1_SL_base, I2C_INT_TX_DATA_RDY);
            I2C_disableInterrupt(I2C1_SL_base, I2C_INT_RX_DATA_RDY);
            I2C_disableFIFO(I2C1_SL_base);
            I2C_enableFIFO(I2C1_SL_base);
            I2C_setConfig(I2C1_SL_base, (I2C_CONTROLLER_RECEIVE_MODE ));
            I2C_clearInterruptStatus(I2C1_SL_base, I2C_INT_TXFF);
            if(hi2c->numofSixteenByte)
            {
                I2C_setFIFOInterruptLevel(I2C1_SL_base, I2C_FIFO_TXEMPTY, (I2C_RxFIFOLevel)I2C1_FIFO_DEEP);
            }
            else
            {
                I2C_setFIFOInterruptLevel(I2C1_SL_base, I2C_FIFO_TXEMPTY, (I2C_RxFIFOLevel)hi2c->remainingBytes);                
            }
            I2C_setBitCount(I2C1_SL_base, I2C_BITCOUNT_8);
            I2C_setDataCount(I2C1_SL_base, hi2c->XferSize);            
            I2C_sendStartCondition(I2C1_SL_base);
            I2C_sendStopCondition(I2C1_SL_base);

            I2C_enableInterrupt(I2C1_SL_base,  I2C_INT_ARB_LOST | I2C_INT_NO_ACK | I2C_INT_RXFF | I2C_INT_STOP_CONDITION);        
	        
        #else
            //Non fifo version           
            I2C_disableInterrupt(I2C1_SL_base, I2C_INT_REG_ACCESS_RDY);
            I2C_disableInterrupt(I2C1_SL_base, I2C_INT_TX_DATA_RDY);
            I2C_disableInterrupt(I2C1_SL_base, I2C_INT_RX_DATA_RDY);            

            I2C_setConfig(I2C1_SL_base, I2C_CONTROLLER_RECEIVE_MODE);   //DSP will send stop automatically without I2C_REPEAT_MODE
            I2C_setDataCount(I2C1_SL_base, hi2c->XferSize);
            I2C_setBitCount(I2C1_SL_base, I2C_BITCOUNT_8);
            //I2C_clearInterruptStatus(I2C1_SL_base, I2C_INT_NO_ACK | I2C_INT_RX_DATA_RDY | I2C_INT_TX_DATA_RDY); 

            I2C_enableInterrupt(I2C1_SL_base,  I2C_INT_ARB_LOST | I2C_INT_NO_ACK | I2C_INT_RX_DATA_RDY | I2C_INT_STOP_CONDITION);
            I2C_sendStartCondition(I2C1_SL_base);
            I2C_sendStopCondition(I2C1_SL_base);            
            
        #endif
        
        #else
        return false;
        #endif
        return true;
    }
    else if (2 == hi2c->I2C_Peripheral_No) {
        #if defined(USE_I2C2) 
        if (hi2c->busy) return false;       
        hi2c->pBuffPtr=pData;
        hi2c->XferSize=Size;
        hi2c->XferCount =0;
        hi2c->needLastStop=NeedStopEnd;
        hi2c->Success=false;
        hi2c->isRead=true;
        hi2c->busy=true;

        hi2c->numofSixteenByte  = (hi2c->XferSize) / I2C2_FIFO_DEEP;  
        hi2c->remainingBytes    = (hi2c->XferSize) % I2C2_FIFO_DEEP;

        
       if (DevAddress<128)
            I2C_setAddressMode(I2C2_SL_base, I2C_ADDR_MODE_7BITS);
        else
            I2C_setAddressMode(I2C2_SL_base, I2C_ADDR_MODE_10BITS);
        I2C_setTargetAddress(I2C2_SL_base, DevAddress);    
        if(I2C_isBusBusy(I2C2_SL_base))
        {
            hi2c->busy=false;
            return false;
        }   
        if(I2C_getStopConditionStatus(I2C2_SL_base))
        {
            hi2c->busy=false;
            return false;
        }    
        #ifdef I2C2_USE_FIFO
            //FIFO version         
//##########################
// --- CRITICAL FINAL FIX: FORCE MODULE AND FIFO STATE RESET ---

// --- MINIMAL HIGH-LEVEL PRE-TRANSACTION RESET ---

// 1. Save and disable the module (IRS=0)
uint16_t mdR_config = HWREGH(I2C2_SL_base + I2C_O_MDR); 
HWREGH(I2C2_SL_base + I2C_O_MDR) &= ~I2C_MDR_IRS; // Disable Module

// 2. Re-enable the module (IRS=1) with the full Master Transmit config
// This restores the I2C module's state machine to a known-good start state.
HWREGH(I2C2_SL_base + I2C_O_MDR) = I2C_MDR_MST | I2C_MDR_IRS | I2C_MDR_TRX; // Re-enable

// --- END OF MINIMAL FIX ---
//#####################              
            I2C_disableInterrupt(I2C2_SL_base, I2C_INT_REG_ACCESS_RDY);
            I2C_disableInterrupt(I2C2_SL_base, I2C_INT_TXFF);
            I2C_disableInterrupt(I2C2_SL_base, I2C_INT_TX_DATA_RDY);
            I2C_disableInterrupt(I2C2_SL_base, I2C_INT_RX_DATA_RDY);
            I2C_disableFIFO(I2C2_SL_base);
            I2C_enableFIFO(I2C2_SL_base);
            I2C_setConfig(I2C2_SL_base, (I2C_CONTROLLER_RECEIVE_MODE ));
            I2C_clearInterruptStatus(I2C2_SL_base, I2C_INT_TXFF);
            if(hi2c->numofSixteenByte)
            {
                I2C_setFIFOInterruptLevel(I2C2_SL_base, I2C_FIFO_TXEMPTY, (I2C_RxFIFOLevel)I2C2_FIFO_DEEP);
            }
            else
            {
                I2C_setFIFOInterruptLevel(I2C2_SL_base, I2C_FIFO_TXEMPTY, (I2C_RxFIFOLevel)hi2c->remainingBytes);                
            }
            I2C_setBitCount(I2C2_SL_base, I2C_BITCOUNT_8);
            I2C_setDataCount(I2C2_SL_base, hi2c->XferSize);            
            I2C_sendStartCondition(I2C2_SL_base);
            I2C_sendStopCondition(I2C2_SL_base);

            I2C_enableInterrupt(I2C2_SL_base,  I2C_INT_ARB_LOST | I2C_INT_NO_ACK | I2C_INT_RXFF | I2C_INT_STOP_CONDITION);        
	        
        #else
            //Non fifo version           
            I2C_disableInterrupt(I2C2_SL_base, I2C_INT_REG_ACCESS_RDY);
            I2C_disableInterrupt(I2C2_SL_base, I2C_INT_TX_DATA_RDY);
            I2C_disableInterrupt(I2C2_SL_base, I2C_INT_RX_DATA_RDY);            

            I2C_setConfig(I2C2_SL_base, I2C_CONTROLLER_RECEIVE_MODE);   //DSP will send stop automatically without I2C_REPEAT_MODE
            I2C_setDataCount(I2C2_SL_base, hi2c->XferSize);
            I2C_setBitCount(I2C2_SL_base, I2C_BITCOUNT_8);
            //I2C_clearInterruptStatus(I2C2_SL_base, I2C_INT_NO_ACK | I2C_INT_RX_DATA_RDY | I2C_INT_TX_DATA_RDY);            
            
            I2C_sendStartCondition(I2C2_SL_base);
            I2C_sendStopCondition(I2C2_SL_base);            
            I2C_enableInterrupt(I2C2_SL_base,  I2C_INT_ARB_LOST | I2C_INT_NO_ACK | I2C_INT_RX_DATA_RDY | I2C_INT_STOP_CONDITION);
        #endif
        
        #else
        return false;
        #endif
        return true;
    }
    else if (3 == hi2c->I2C_Peripheral_No) {
        #if defined(USE_I2C3) 
        if (hi2c->busy) return false;       
        hi2c->pBuffPtr=pData;
        hi2c->XferSize=Size;
        hi2c->XferCount =0;
        hi2c->needLastStop=NeedStopEnd;
        hi2c->Success=false;
        hi2c->isRead=true;
        hi2c->busy=true;

        hi2c->numofSixteenByte  = (hi2c->XferSize) / I2C3_FIFO_DEEP;  
        hi2c->remainingBytes    = (hi2c->XferSize) % I2C3_FIFO_DEEP;

        
       if (DevAddress<128)
            I2C_setAddressMode(I2C3_SL_base, I2C_ADDR_MODE_7BITS);
        else
            I2C_setAddressMode(I2C3_SL_base, I2C_ADDR_MODE_10BITS);
        I2C_setTargetAddress(I2C3_SL_base, DevAddress);    
        if(I2C_isBusBusy(I2C3_SL_base))
        {
            hi2c->busy=false;
            return false;
        }   
        if(I2C_getStopConditionStatus(I2C3_SL_base))
        {
            hi2c->busy=false;
            return false;
        }    
        #ifdef I2C3_USE_FIFO
            //FIFO version           
//##########################
// --- CRITICAL FINAL FIX: FORCE MODULE AND FIFO STATE RESET ---

// --- MINIMAL HIGH-LEVEL PRE-TRANSACTION RESET ---

// 1. Save and disable the module (IRS=0)
uint16_t mdR_config = HWREGH(I2C3_SL_base + I2C_O_MDR); 
HWREGH(I2C3_SL_base + I2C_O_MDR) &= ~I2C_MDR_IRS; // Disable Module

// 2. Re-enable the module (IRS=1) with the full Master Transmit config
// This restores the I2C module's state machine to a known-good start state.
HWREGH(I2C3_SL_base + I2C_O_MDR) = I2C_MDR_MST | I2C_MDR_IRS | I2C_MDR_TRX; // Re-enable

// --- END OF MINIMAL FIX ---
//#####################                          
            I2C_disableInterrupt(I2C3_SL_base, I2C_INT_REG_ACCESS_RDY);
            I2C_disableInterrupt(I2C3_SL_base, I2C_INT_TXFF);
            I2C_disableInterrupt(I2C3_SL_base, I2C_INT_TX_DATA_RDY);
            I2C_disableInterrupt(I2C3_SL_base, I2C_INT_RX_DATA_RDY);
            I2C_disableFIFO(I2C3_SL_base);
            I2C_enableFIFO(I2C3_SL_base);
            I2C_setConfig(I2C3_SL_base, (I2C_CONTROLLER_RECEIVE_MODE ));
            I2C_clearInterruptStatus(I2C3_SL_base, I2C_INT_TXFF);
            if(hi2c->numofSixteenByte)
            {
                I2C_setFIFOInterruptLevel(I2C3_SL_base, I2C_FIFO_TXEMPTY, (I2C_RxFIFOLevel)I2C3_FIFO_DEEP);
            }
            else
            {
                I2C_setFIFOInterruptLevel(I2C3_SL_base, I2C_FIFO_TXEMPTY, (I2C_RxFIFOLevel)hi2c->remainingBytes);                
            }
            I2C_setBitCount(I2C3_SL_base, I2C_BITCOUNT_8);
            I2C_setDataCount(I2C3_SL_base, hi2c->XferSize);            
            I2C_sendStartCondition(I2C3_SL_base);
            I2C_sendStopCondition(I2C3_SL_base);

            I2C_enableInterrupt(I2C3_SL_base,  I2C_INT_ARB_LOST | I2C_INT_NO_ACK | I2C_INT_RXFF | I2C_INT_STOP_CONDITION);        
	        
        #else
            //Non fifo version           
            I2C_disableInterrupt(I2C3_SL_base, I2C_INT_REG_ACCESS_RDY);
            I2C_disableInterrupt(I2C3_SL_base, I2C_INT_TX_DATA_RDY);
            I2C_disableInterrupt(I2C3_SL_base, I2C_INT_RX_DATA_RDY);            

            I2C_setConfig(I2C3_SL_base, I2C_CONTROLLER_RECEIVE_MODE);   //DSP will send stop automatically without I2C_REPEAT_MODE
            I2C_setDataCount(I2C3_SL_base, hi2c->XferSize);
            I2C_setBitCount(I2C3_SL_base, I2C_BITCOUNT_8);
            //I2C_clearInterruptStatus(I2C3_SL_base, I2C_INT_NO_ACK | I2C_INT_RX_DATA_RDY | I2C_INT_TX_DATA_RDY);            
            
            I2C_sendStartCondition(I2C3_SL_base);
            I2C_sendStopCondition(I2C3_SL_base);            
            I2C_enableInterrupt(I2C3_SL_base,  I2C_INT_ARB_LOST | I2C_INT_NO_ACK | I2C_INT_RX_DATA_RDY | I2C_INT_STOP_CONDITION);
        #endif
        
        #else
        return false;
        #endif
        return true;
    }
    else if (4 == hi2c->I2C_Peripheral_No) {
        #if defined(USE_I2C4) 
        if (hi2c->busy) return false;       
        hi2c->pBuffPtr=pData;
        hi2c->XferSize=Size;
        hi2c->XferCount =0;
        hi2c->needLastStop=NeedStopEnd;
        hi2c->Success=false;
        hi2c->isRead=true;
        hi2c->busy=true;

        hi2c->numofSixteenByte  = (hi2c->XferSize) / I2C4_FIFO_DEEP;  
        hi2c->remainingBytes    = (hi2c->XferSize) % I2C4_FIFO_DEEP;

        
       if (DevAddress<128)
            I2C_setAddressMode(I2C4_SL_base, I2C_ADDR_MODE_7BITS);
        else
            I2C_setAddressMode(I2C4_SL_base, I2C_ADDR_MODE_10BITS);
        I2C_setTargetAddress(I2C4_SL_base, DevAddress);    
        if(I2C_isBusBusy(I2C4_SL_base))
        {
            hi2c->busy=false;
            return false;
        }   
        if(I2C_getStopConditionStatus(I2C4_SL_base))
        {
            hi2c->busy=false;
            return false;
        }    
        #ifdef I2C4_USE_FIFO
            //FIFO version        
//##########################
// --- CRITICAL FINAL FIX: FORCE MODULE AND FIFO STATE RESET ---

// --- MINIMAL HIGH-LEVEL PRE-TRANSACTION RESET ---

// 1. Save and disable the module (IRS=0)
uint16_t mdR_config = HWREGH(I2C4_SL_base + I2C_O_MDR); 
HWREGH(I2C4_SL_base + I2C_O_MDR) &= ~I2C_MDR_IRS; // Disable Module

// 2. Re-enable the module (IRS=1) with the full Master Transmit config
// This restores the I2C module's state machine to a known-good start state.
HWREGH(I2C4_SL_base + I2C_O_MDR) = I2C_MDR_MST | I2C_MDR_IRS | I2C_MDR_TRX; // Re-enable

// --- END OF MINIMAL FIX ---
//#####################                             
            I2C_disableInterrupt(I2C4_SL_base, I2C_INT_REG_ACCESS_RDY);
            I2C_disableInterrupt(I2C4_SL_base, I2C_INT_TXFF);
            I2C_disableInterrupt(I2C4_SL_base, I2C_INT_TX_DATA_RDY);
            I2C_disableInterrupt(I2C4_SL_base, I2C_INT_RX_DATA_RDY);
            I2C_disableFIFO(I2C4_SL_base);
            I2C_enableFIFO(I2C4_SL_base);
            I2C_setConfig(I2C4_SL_base, (I2C_CONTROLLER_RECEIVE_MODE ));
            I2C_clearInterruptStatus(I2C4_SL_base, I2C_INT_TXFF);
            if(hi2c->numofSixteenByte)
            {
                I2C_setFIFOInterruptLevel(I2C4_SL_base, I2C_FIFO_TXEMPTY, (I2C_RxFIFOLevel)I2C4_FIFO_DEEP);
            }
            else
            {
                I2C_setFIFOInterruptLevel(I2C4_SL_base, I2C_FIFO_TXEMPTY, (I2C_RxFIFOLevel)hi2c->remainingBytes);                
            }
            I2C_setBitCount(I2C4_SL_base, I2C_BITCOUNT_8);
            I2C_setDataCount(I2C4_SL_base, hi2c->XferSize);            
            I2C_sendStartCondition(I2C4_SL_base);
            I2C_sendStopCondition(I2C4_SL_base);

            I2C_enableInterrupt(I2C4_SL_base,  I2C_INT_ARB_LOST | I2C_INT_NO_ACK | I2C_INT_RXFF | I2C_INT_STOP_CONDITION);        
	        
        #else
            //Non fifo version           
            I2C_disableInterrupt(I2C4_SL_base, I2C_INT_REG_ACCESS_RDY);
            I2C_disableInterrupt(I2C4_SL_base, I2C_INT_TX_DATA_RDY);
            I2C_disableInterrupt(I2C4_SL_base, I2C_INT_RX_DATA_RDY);            

            I2C_setConfig(I2C4_SL_base, I2C_CONTROLLER_RECEIVE_MODE);   //DSP will send stop automatically without I2C_REPEAT_MODE
            I2C_setDataCount(I2C4_SL_base, hi2c->XferSize);
            I2C_setBitCount(I2C4_SL_base, I2C_BITCOUNT_8);
            //I2C_clearInterruptStatus(I2C4_SL_base, I2C_INT_NO_ACK | I2C_INT_RX_DATA_RDY | I2C_INT_TX_DATA_RDY);            
            
            I2C_sendStartCondition(I2C4_SL_base);
            I2C_sendStopCondition(I2C4_SL_base);            
            I2C_enableInterrupt(I2C4_SL_base,  I2C_INT_ARB_LOST | I2C_INT_NO_ACK | I2C_INT_RX_DATA_RDY | I2C_INT_STOP_CONDITION);
        #endif
        
        #else
        return false;
        #endif
        return true;
    }
}

bool HAL_I2C_Master_Seq_Transmit_then_Receive_IT(I2C_Handle *hi2c, uint16_t DevAddress, uint8_t *pWriteData, uint16_t WriteSize, uint8_t *pReadData, uint16_t ReadSize) {
    if (1 == hi2c->I2C_Peripheral_No) {
        #if defined(USE_I2C1) 
        if (hi2c->busy) return false;       
        
        hi2c->XferCount =0;
        hi2c->needLastStop=false;  //use for first tx , don't send stop for non-fifo version
        hi2c->Success=false;
        hi2c->isRead=true;
        hi2c->busy=true;

        hi2c->numofSixteenByte  = (hi2c->XferSize) / I2C1_FIFO_DEEP;  
        hi2c->remainingBytes    = (hi2c->XferSize) % I2C1_FIFO_DEEP;        
       
        #ifdef I2C1_USE_FIFO
            //FIFO version
//##########################
// --- CRITICAL FINAL FIX: FORCE MODULE AND FIFO STATE RESET ---

// --- MINIMAL HIGH-LEVEL PRE-TRANSACTION RESET ---

// 1. Save and disable the module (IRS=0)
uint16_t mdR_config = HWREGH(I2C1_SL_base + I2C_O_MDR); 
HWREGH(I2C1_SL_base + I2C_O_MDR) &= ~I2C_MDR_IRS; // Disable Module

// 2. Re-enable the module (IRS=1) with the full Master Transmit config
// This restores the I2C module's state machine to a known-good start state.
HWREGH(I2C1_SL_base + I2C_O_MDR) = I2C_MDR_MST | I2C_MDR_IRS | I2C_MDR_TRX; // Re-enable

// --- END OF MINIMAL FIX ---
//#####################                          
            hi2c->pBuffPtr=pReadData;
            hi2c->XferSize=ReadSize;
            hi2c->needLastStop=true;   //FIFO itself control ok

            hi2c->numofSixteenByte  = (hi2c->XferSize) / I2C1_FIFO_DEEP;  
            hi2c->remainingBytes    = (hi2c->XferSize) % I2C1_FIFO_DEEP;  
            
            I2C_disableInterrupt(I2C1_SL_base, I2C_INT_TXFF|I2C_INT_RXFF);
            I2C_disableInterrupt(I2C1_SL_base, I2C_INT_TX_DATA_RDY);
            I2C_disableInterrupt(I2C1_SL_base, I2C_INT_RX_DATA_RDY);
            I2C_clearInterruptStatus(I2C1_SL_base, (I2C_INT_REG_ACCESS_RDY|I2C_INT_TXFF|I2C_INT_RXFF));
            I2C_enableInterrupt(I2C1_SL_base, I2C_INT_REG_ACCESS_RDY);

            //I2C_disableFIFO(base);
            //I2C_enableFIFO(I2C1_SL_base);         
            if(I2C_isBusBusy(I2C1_SL_base))
            {
                hi2c->busy=false;
                return false;
            }   
            if(I2C_getStopConditionStatus(I2C1_SL_base))
            {
                hi2c->busy=false;
                return false;
            }
            I2C_disableFIFO(I2C1_SL_base);
            I2C_setConfig(I2C1_SL_base, (I2C_CONTROLLER_SEND_MODE));
            if (DevAddress<128)
                I2C_setAddressMode(I2C1_SL_base, I2C_ADDR_MODE_7BITS);
            else
                I2C_setAddressMode(I2C1_SL_base, I2C_ADDR_MODE_10BITS);
            I2C_setTargetAddress(I2C1_SL_base, DevAddress); 
            I2C_setBitCount(I2C1_SL_base, I2C_BITCOUNT_8);           
            I2C_setDataCount(I2C1_SL_base, WriteSize);
            I2C_enableFIFO(I2C1_SL_base);
            int16_t i;
            for(i=0;i<WriteSize;i++)
            {
            I2C_putData(I2C1_SL_base, pWriteData[i] & 0xFF);
            }
            I2C_sendStartCondition(I2C1_SL_base);
            SysCtl_delay(50); //Adding delay to correctly read I2C bus status
            return true;            
    
	        
        #else
            //Non fifo version
            hi2c->pBuffPtr2=pReadData;
            hi2c->XferSize2=ReadSize;
            hi2c->pBuffPtr=pWriteData;
            hi2c->XferSize=WriteSize;            

            I2C_clearInterruptStatus(I2C1_SL_base, I2C_INT_ARB_LOST | I2C_INT_NO_ACK);
            I2C_enableInterrupt(I2CA_BASE, I2C_INT_ADDR_TARGET | I2C_INT_ARB_LOST | I2C_INT_NO_ACK | I2C_INT_STOP_CONDITION);
            
            //I2C_setTargetAddress(I2C1_SL_base, DevAddress);
            I2C_setConfig(I2C1_SL_base, I2C_CONTROLLER_SEND_MODE | I2C_REPEAT_MODE);   
            //I2C_setDataCount(I2C1_SL_base, hi2c->XferSize);
            I2C_setBitCount(I2C1_SL_base, I2C_BITCOUNT_8);        
            if (DevAddress<128)
                I2C_setAddressMode(I2C1_SL_base, I2C_ADDR_MODE_7BITS);
            else
                I2C_setAddressMode(I2C1_SL_base, I2C_ADDR_MODE_10BITS);
            I2C_setTargetAddress(I2C1_SL_base, DevAddress);
            I2C_setDataCount(I2C1_SL_base, hi2c->XferSize);                  
            //I2C_clearInterruptStatus(I2C1_SL_base, I2C_INT_NO_ACK | I2C_INT_RX_DATA_RDY | I2C_INT_TX_DATA_RDY);                  
            I2C_putData(I2C1_SL_base, hi2c->pBuffPtr[hi2c->XferCount++]);
            //I2C_sendStartCondition(I2C1_SL_base);           
            I2C_enableInterrupt(I2C1_SL_base, (I2C_INT_STOP_CONDITION | I2C_INT_ARB_LOST | I2C_INT_NO_ACK));
            I2C_enableInterrupt(I2C1_SL_base, I2C_INT_TX_DATA_RDY);
            //I2C_clearInterruptStatus(I2C1_SL_base, I2C_INT_TX_DATA_RDY);
            //I2C_enableInterrupt(I2C1_SL_base, I2C_INT_REG_ACCESS_RDY);                
            I2C_sendStartCondition(I2C1_SL_base);           

            return true;            
        #endif        
        #else
        return false;
        #endif
        return true;
    }
    else if (2 == hi2c->I2C_Peripheral_No) {
        #if defined(USE_I2C2) 
        if (hi2c->busy) return false;       
        
        hi2c->XferCount =0;
        hi2c->needLastStop=false;  //use for first tx , don't send stop for non-fifo version
        hi2c->Success=false;
        hi2c->isRead=true;
        hi2c->busy=true;

        hi2c->numofSixteenByte  = (hi2c->XferSize) / I2C2_FIFO_DEEP;  
        hi2c->remainingBytes    = (hi2c->XferSize) % I2C2_FIFO_DEEP;        
       
        #ifdef I2C2_USE_FIFO
            //FIFO version
//##########################
// --- CRITICAL FINAL FIX: FORCE MODULE AND FIFO STATE RESET ---

// --- MINIMAL HIGH-LEVEL PRE-TRANSACTION RESET ---

// 1. Save and disable the module (IRS=0)
uint16_t mdR_config = HWREGH(I2C2_SL_base + I2C_O_MDR); 
HWREGH(I2C2_SL_base + I2C_O_MDR) &= ~I2C_MDR_IRS; // Disable Module

// 2. Re-enable the module (IRS=1) with the full Master Transmit config
// This restores the I2C module's state machine to a known-good start state.
HWREGH(I2C2_SL_base + I2C_O_MDR) = I2C_MDR_MST | I2C_MDR_IRS | I2C_MDR_TRX; // Re-enable

// --- END OF MINIMAL FIX ---
//#####################                          
            hi2c->pBuffPtr=pReadData;
            hi2c->XferSize=ReadSize;
            hi2c->needLastStop=true;   //FIFO itself control ok

            hi2c->numofSixteenByte  = (hi2c->XferSize) / I2C2_FIFO_DEEP;  
            hi2c->remainingBytes    = (hi2c->XferSize) % I2C2_FIFO_DEEP; 

            I2C_disableInterrupt(I2C2_SL_base, I2C_INT_TXFF|I2C_INT_RXFF);
            I2C_disableInterrupt(I2C2_SL_base, I2C_INT_TX_DATA_RDY);
            I2C_disableInterrupt(I2C2_SL_base, I2C_INT_RX_DATA_RDY);
            I2C_clearInterruptStatus(I2C2_SL_base, (I2C_INT_REG_ACCESS_RDY|I2C_INT_TXFF|I2C_INT_RXFF));
            I2C_enableInterrupt(I2C2_SL_base, I2C_INT_REG_ACCESS_RDY);

            //I2C_disableFIFO(base);
            //I2C_enableFIFO(I2C2_SL_base);         
            if(I2C_isBusBusy(I2C2_SL_base))
            {
                hi2c->busy=false;
                return false;
            }   
            if(I2C_getStopConditionStatus(I2C2_SL_base))
            {
                hi2c->busy=false;
                return false;
            }
            I2C_disableFIFO(I2C2_SL_base);
            I2C_setConfig(I2C2_SL_base, (I2C_CONTROLLER_SEND_MODE));
            if (DevAddress<128)
                I2C_setAddressMode(I2C2_SL_base, I2C_ADDR_MODE_7BITS);
            else
                I2C_setAddressMode(I2C2_SL_base, I2C_ADDR_MODE_10BITS);
            I2C_setTargetAddress(I2C2_SL_base, DevAddress); 
            I2C_setBitCount(I2C2_SL_base, I2C_BITCOUNT_8);           
            I2C_setDataCount(I2C2_SL_base, WriteSize);
            I2C_enableFIFO(I2C2_SL_base);
            int16_t i;
            for(i=0;i<WriteSize;i++)
            {
            I2C_putData(I2C2_SL_base, pWriteData[i] & 0xFF);
            }
            I2C_sendStartCondition(I2C2_SL_base);
            SysCtl_delay(50); //Adding delay to correctly read I2C bus status
            return true;            
    
	        
        #else
            //Non fifo version
            hi2c->pBuffPtr2=pReadData;
            hi2c->XferSize2=ReadSize;
            hi2c->pBuffPtr=pWriteData;
            hi2c->XferSize=WriteSize;

            I2C_clearInterruptStatus(I2C2_SL_base, I2C_INT_ARB_LOST | I2C_INT_NO_ACK);
            I2C_enableInterrupt(I2CA_BASE, I2C_INT_ADDR_TARGET | I2C_INT_ARB_LOST | I2C_INT_NO_ACK | I2C_INT_STOP_CONDITION);
            
            //I2C_setTargetAddress(I2C2_SL_base, DevAddress);
            I2C_setConfig(I2C2_SL_base, I2C_CONTROLLER_SEND_MODE | I2C_REPEAT_MODE);   
            //I2C_setDataCount(I2C2_SL_base, hi2c->XferSize);
            I2C_setBitCount(I2C2_SL_base, I2C_BITCOUNT_8);        
            if (DevAddress<128)
                I2C_setAddressMode(I2C2_SL_base, I2C_ADDR_MODE_7BITS);
            else
                I2C_setAddressMode(I2C2_SL_base, I2C_ADDR_MODE_10BITS);
            I2C_setTargetAddress(I2C2_SL_base, DevAddress);
            I2C_setDataCount(I2C2_SL_base, hi2c->XferSize);                  
            //I2C_clearInterruptStatus(I2C2_SL_base, I2C_INT_NO_ACK | I2C_INT_RX_DATA_RDY | I2C_INT_TX_DATA_RDY);                  
            I2C_putData(I2C2_SL_base, hi2c->pBuffPtr[hi2c->XferCount++]);
            //I2C_sendStartCondition(I2C2_SL_base);           
            I2C_enableInterrupt(I2C2_SL_base, (I2C_INT_STOP_CONDITION | I2C_INT_ARB_LOST | I2C_INT_NO_ACK));
            I2C_enableInterrupt(I2C2_SL_base, I2C_INT_TX_DATA_RDY);
            //I2C_clearInterruptStatus(I2C2_SL_base, I2C_INT_TX_DATA_RDY);
            //I2C_enableInterrupt(I2C2_SL_base, I2C_INT_REG_ACCESS_RDY);                
            I2C_sendStartCondition(I2C2_SL_base);          
            return true;            
        #endif        
        #else
        return false;
        #endif
        return true;
    }
    else if (3 == hi2c->I2C_Peripheral_No) {
        #if defined(USE_I2C3) 
        if (hi2c->busy) return false;       
        
        hi2c->XferCount =0;
        hi2c->needLastStop=false;  //use for first tx , don't send stop for non-fifo version
        hi2c->Success=false;
        hi2c->isRead=true;
        hi2c->busy=true;

        hi2c->numofSixteenByte  = (hi2c->XferSize) / I2C3_FIFO_DEEP;  
        hi2c->remainingBytes    = (hi2c->XferSize) % I2C3_FIFO_DEEP;        
       
        #ifdef I2C3_USE_FIFO
            //FIFO version
//##########################
// --- CRITICAL FINAL FIX: FORCE MODULE AND FIFO STATE RESET ---

// --- MINIMAL HIGH-LEVEL PRE-TRANSACTION RESET ---

// 1. Save and disable the module (IRS=0)
uint16_t mdR_config = HWREGH(I2C3_SL_base + I2C_O_MDR); 
HWREGH(I2C3_SL_base + I2C_O_MDR) &= ~I2C_MDR_IRS; // Disable Module

// 2. Re-enable the module (IRS=1) with the full Master Transmit config
// This restores the I2C module's state machine to a known-good start state.
HWREGH(I2C3_SL_base + I2C_O_MDR) = I2C_MDR_MST | I2C_MDR_IRS | I2C_MDR_TRX; // Re-enable

// --- END OF MINIMAL FIX ---
//#####################                          
            hi2c->pBuffPtr=pReadData;
            hi2c->XferSize=ReadSize;
            hi2c->needLastStop=true;   //FIFO itself control ok

            hi2c->numofSixteenByte  = (hi2c->XferSize) / I2C3_FIFO_DEEP;  
            hi2c->remainingBytes    = (hi2c->XferSize) % I2C3_FIFO_DEEP; 

            I2C_disableInterrupt(I2C3_SL_base, I2C_INT_TXFF|I2C_INT_RXFF);
            I2C_disableInterrupt(I2C3_SL_base, I2C_INT_TX_DATA_RDY);
            I2C_disableInterrupt(I2C3_SL_base, I2C_INT_RX_DATA_RDY);
            I2C_clearInterruptStatus(I2C3_SL_base, (I2C_INT_REG_ACCESS_RDY|I2C_INT_TXFF|I2C_INT_RXFF));
            I2C_enableInterrupt(I2C3_SL_base, I2C_INT_REG_ACCESS_RDY);

            //I2C_disableFIFO(base);
            //I2C_enableFIFO(I2C3_SL_base);         
            if(I2C_isBusBusy(I2C3_SL_base))
            {
                hi2c->busy=false;
                return false;
            }   
            if(I2C_getStopConditionStatus(I2C3_SL_base))
            {
                hi2c->busy=false;
                return false;
            }
            I2C_disableFIFO(I2C3_SL_base);
            I2C_setConfig(I2C3_SL_base, (I2C_CONTROLLER_SEND_MODE));
            if (DevAddress<128)
                I2C_setAddressMode(I2C3_SL_base, I2C_ADDR_MODE_7BITS);
            else
                I2C_setAddressMode(I2C3_SL_base, I2C_ADDR_MODE_10BITS);
            I2C_setTargetAddress(I2C3_SL_base, DevAddress); 
            I2C_setBitCount(I2C3_SL_base, I2C_BITCOUNT_8);           
            I2C_setDataCount(I2C3_SL_base, WriteSize);
            I2C_enableFIFO(I2C3_SL_base);
            int16_t i;
            for(i=0;i<WriteSize;i++)
            {
            I2C_putData(I2C3_SL_base, pWriteData[i] & 0xFF);
            }
            I2C_sendStartCondition(I2C3_SL_base);
            SysCtl_delay(50); //Adding delay to correctly read I2C bus status
            return true;            
    
	        
        #else
            //Non fifo version
            hi2c->pBuffPtr2=pReadData;
            hi2c->XferSize2=ReadSize;
            hi2c->pBuffPtr=pWriteData;
            hi2c->XferSize=WriteSize;

            I2C_clearInterruptStatus(I2C3_SL_base, I2C_INT_ARB_LOST | I2C_INT_NO_ACK);
            I2C_enableInterrupt(I2CA_BASE, I2C_INT_ADDR_TARGET | I2C_INT_ARB_LOST | I2C_INT_NO_ACK | I2C_INT_STOP_CONDITION);
            
            //I2C_setTargetAddress(I2C3_SL_base, DevAddress);
            I2C_setConfig(I2C3_SL_base, I2C_CONTROLLER_SEND_MODE | I2C_REPEAT_MODE);   
            //I2C_setDataCount(I2C3_SL_base, hi2c->XferSize);
            I2C_setBitCount(I2C3_SL_base, I2C_BITCOUNT_8);        
            if (DevAddress<128)
                I2C_setAddressMode(I2C3_SL_base, I2C_ADDR_MODE_7BITS);
            else
                I2C_setAddressMode(I2C3_SL_base, I2C_ADDR_MODE_10BITS);
            I2C_setTargetAddress(I2C3_SL_base, DevAddress);
            I2C_setDataCount(I2C3_SL_base, hi2c->XferSize);                  
            //I2C_clearInterruptStatus(I2C3_SL_base, I2C_INT_NO_ACK | I2C_INT_RX_DATA_RDY | I2C_INT_TX_DATA_RDY);                  
            I2C_putData(I2C3_SL_base, hi2c->pBuffPtr[hi2c->XferCount++]);
            //I2C_sendStartCondition(I2C3_SL_base);           
            I2C_enableInterrupt(I2C3_SL_base, (I2C_INT_STOP_CONDITION | I2C_INT_ARB_LOST | I2C_INT_NO_ACK));
            I2C_enableInterrupt(I2C3_SL_base, I2C_INT_TX_DATA_RDY);
            //I2C_clearInterruptStatus(I2C3_SL_base, I2C_INT_TX_DATA_RDY);
            //I2C_enableInterrupt(I2C3_SL_base, I2C_INT_REG_ACCESS_RDY);                
            I2C_sendStartCondition(I2C3_SL_base);  
            return true;            
        #endif        
        #else
        return false;
        #endif
        return true;
    }
    else if (4 == hi2c->I2C_Peripheral_No) {
        #if defined(USE_I2C4) 
        if (hi2c->busy) return false;       
        
        hi2c->XferCount =0;
        hi2c->needLastStop=false;  //use for first tx , don't send stop for non-fifo version
        hi2c->Success=false;
        hi2c->isRead=true;
        hi2c->busy=true;

        hi2c->numofSixteenByte  = (hi2c->XferSize) / I2C4_FIFO_DEEP;  
        hi2c->remainingBytes    = (hi2c->XferSize) % I2C4_FIFO_DEEP;        
       
        #ifdef I2C4_USE_FIFO
            //FIFO version
            //##########################
// --- CRITICAL FINAL FIX: FORCE MODULE AND FIFO STATE RESET ---

// --- MINIMAL HIGH-LEVEL PRE-TRANSACTION RESET ---

// 1. Save and disable the module (IRS=0)
uint16_t mdR_config = HWREGH(I2C4_SL_base + I2C_O_MDR); 
HWREGH(I2C4_SL_base + I2C_O_MDR) &= ~I2C_MDR_IRS; // Disable Module

// 2. Re-enable the module (IRS=1) with the full Master Transmit config
// This restores the I2C module's state machine to a known-good start state.
HWREGH(I2C4_SL_base + I2C_O_MDR) = I2C_MDR_MST | I2C_MDR_IRS | I2C_MDR_TRX; // Re-enable

// --- END OF MINIMAL FIX ---
//#####################              
            hi2c->pBuffPtr=pReadData;
            hi2c->XferSize=ReadSize;
            hi2c->needLastStop=true;   //FIFO itself control ok

            hi2c->numofSixteenByte  = (hi2c->XferSize) / I2C4_FIFO_DEEP;  
            hi2c->remainingBytes    = (hi2c->XferSize) % I2C4_FIFO_DEEP; 

            I2C_disableInterrupt(I2C4_SL_base, I2C_INT_TXFF|I2C_INT_RXFF);
            I2C_disableInterrupt(I2C4_SL_base, I2C_INT_TX_DATA_RDY);
            I2C_disableInterrupt(I2C4_SL_base, I2C_INT_RX_DATA_RDY);
            I2C_clearInterruptStatus(I2C4_SL_base, (I2C_INT_REG_ACCESS_RDY|I2C_INT_TXFF|I2C_INT_RXFF));
            I2C_enableInterrupt(I2C4_SL_base, I2C_INT_REG_ACCESS_RDY);

            //I2C_disableFIFO(base);
            //I2C_enableFIFO(I2C4_SL_base);         
            if(I2C_isBusBusy(I2C4_SL_base))
            {
                hi2c->busy=false;
                return false;
            }   
            if(I2C_getStopConditionStatus(I2C4_SL_base))
            {
                hi2c->busy=false;
                return false;
            }
            I2C_disableFIFO(I2C4_SL_base);
            I2C_setConfig(I2C4_SL_base, (I2C_CONTROLLER_SEND_MODE));
            if (DevAddress<128)
                I2C_setAddressMode(I2C4_SL_base, I2C_ADDR_MODE_7BITS);
            else
                I2C_setAddressMode(I2C4_SL_base, I2C_ADDR_MODE_10BITS);
            I2C_setTargetAddress(I2C4_SL_base, DevAddress); 
            I2C_setBitCount(I2C4_SL_base, I2C_BITCOUNT_8);           
            I2C_setDataCount(I2C4_SL_base, WriteSize);
            I2C_enableFIFO(I2C4_SL_base);
            int16_t i;
            for(i=0;i<WriteSize;i++)
            {
            I2C_putData(I2C4_SL_base, pWriteData[i] & 0xFF);
            }
            I2C_sendStartCondition(I2C4_SL_base);
            SysCtl_delay(50); //Adding delay to correctly read I2C bus status
            return true;            
    
	        
        #else
            //Non fifo version
            hi2c->pBuffPtr2=pReadData;
            hi2c->XferSize2=ReadSize;
            hi2c->pBuffPtr=pWriteData;
            hi2c->XferSize=WriteSize;

            I2C_clearInterruptStatus(I2C4_SL_base, I2C_INT_ARB_LOST | I2C_INT_NO_ACK);
            I2C_enableInterrupt(I2CA_BASE, I2C_INT_ADDR_TARGET | I2C_INT_ARB_LOST | I2C_INT_NO_ACK | I2C_INT_STOP_CONDITION);
            
            //I2C_setTargetAddress(I2C4_SL_base, DevAddress);
            I2C_setConfig(I2C4_SL_base, I2C_CONTROLLER_SEND_MODE | I2C_REPEAT_MODE);   
            //I2C_setDataCount(I2C4_SL_base, hi2c->XferSize);
            I2C_setBitCount(I2C4_SL_base, I2C_BITCOUNT_8);        
            if (DevAddress<128)
                I2C_setAddressMode(I2C4_SL_base, I2C_ADDR_MODE_7BITS);
            else
                I2C_setAddressMode(I2C4_SL_base, I2C_ADDR_MODE_10BITS);
            I2C_setTargetAddress(I2C4_SL_base, DevAddress);
            I2C_setDataCount(I2C4_SL_base, hi2c->XferSize);                  
            //I2C_clearInterruptStatus(I2C4_SL_base, I2C_INT_NO_ACK | I2C_INT_RX_DATA_RDY | I2C_INT_TX_DATA_RDY);                  
            I2C_putData(I2C4_SL_base, hi2c->pBuffPtr[hi2c->XferCount++]);
            //I2C_sendStartCondition(I2C4_SL_base);           
            I2C_enableInterrupt(I2C4_SL_base, (I2C_INT_STOP_CONDITION | I2C_INT_ARB_LOST | I2C_INT_NO_ACK));
            I2C_enableInterrupt(I2C4_SL_base, I2C_INT_TX_DATA_RDY);
            //I2C_clearInterruptStatus(I2C4_SL_base, I2C_INT_TX_DATA_RDY);
            //I2C_enableInterrupt(I2C4_SL_base, I2C_INT_REG_ACCESS_RDY);                
            I2C_sendStartCondition(I2C4_SL_base);  
            return true;            
        #endif        
        #else
        return false;
        #endif
        return true;
    } 
}



                                

