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

#define tick   uwTick
#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
extern volatile bool transferStatus1;
extern volatile bool ErrorI2C_1;
static uint8_t ReTry_1;
static uint16_t Delay_1 = 0;
#endif




#ifdef USE_I2C2
extern volatile bool transferStatus2;
extern volatile bool ErrorI2C_2;
static uint8_t ReTry_2;
static uint16_t Delay_2 = 0;
#endif

#ifdef USE_I2C3
extern volatile bool transferStatus3;
extern volatile bool ErrorI2C_3;
static uint8_t ReTry_3;
static uint16_t Delay_3 = 0;
#endif

#ifdef USE_I2C4
extern volatile bool transferStatus4;
extern volatile bool ErrorI2C_4;
static uint8_t ReTry_4;
static uint16_t Delay_4 = 0;
#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   
                transferStatus1 = false;
                ErrorI2C_1 = false;
                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 (HAL_OK != HAL_I2C_Master_Seq_Transmit_IT(&hi2c1, /*uint16_t DevAddress*/(pI2CObj->I2CAddr[pI2CObj->PresentSeqNo]<<1), /*uint8_t *pData */pI2CObj->pWriteData[pI2CObj->PresentSeqNo],
                                /*uint16_t Size*/pI2CObj->QTY4Write[pI2CObj->PresentSeqNo], /*uint32_t XferOptions*/I2C_FIRST_FRAME)) {
                            //fail to request
                            return -1; //fail
                        }
                        else
                        {
                            //success to request
                        	Delay_1=0;
                            pI2CObj->state++;
                        }
                        
                       
                    } 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 (HAL_OK != HAL_I2C_Master_Seq_Transmit_IT(&hi2c1, /*uint16_t DevAddress*/(pI2CObj->I2CAddr[pI2CObj->PresentSeqNo]<<1), /*uint8_t *pData*/pI2CObj->pWriteData[pI2CObj->PresentSeqNo],
                                /*uint16_t Size*/ pI2CObj->QTY4Write[pI2CObj->PresentSeqNo], I2C_FIRST_AND_LAST_FRAME)) {
                            //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 (HAL_OK != HAL_I2C_Master_Seq_Receive_IT(&hi2c1, /*uint16_t DevAddress*/(pI2CObj->I2CAddr[pI2CObj->PresentSeqNo]<<1), /*uint8_t *pData */pI2CObj->pReadData[pI2CObj->PresentSeqNo],
                                /*uint16_t Size*/pI2CObj->QTY4Read[pI2CObj->PresentSeqNo],I2C_FIRST_AND_LAST_FRAME)) {
                            //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
                transferStatus2 = false;
                ErrorI2C_2=false;
                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 (HAL_OK != HAL_I2C_Master_Seq_Transmit_IT(&hi2c2, /*uint16_t DevAddress*/(pI2CObj->I2CAddr[pI2CObj->PresentSeqNo]<<1), /*uint8_t *pData */pI2CObj->pWriteData[pI2CObj->PresentSeqNo],
                    	                                /*uint16_t Size*/pI2CObj->QTY4Write[pI2CObj->PresentSeqNo], /*uint32_t XferOptions*/I2C_FIRST_FRAME)) {
                            //fail to request
                    		return -1; //fail
                        }
                        else
                        {
                            //success to request
                        	Delay_2=0;
                            pI2CObj->state++;
                        }
                        
                       
                    } 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 (HAL_OK != HAL_I2C_Master_Seq_Transmit_IT(&hi2c2, /*uint16_t DevAddress*/(pI2CObj->I2CAddr[pI2CObj->PresentSeqNo]<<1), /*uint8_t *pData*/pI2CObj->pWriteData[pI2CObj->PresentSeqNo],
                    	                                /*uint16_t Size*/ pI2CObj->QTY4Write[pI2CObj->PresentSeqNo],I2C_FIRST_AND_LAST_FRAME)) {
                            //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 (HAL_OK != HAL_I2C_Master_Seq_Receive_IT(&hi2c2, /*uint16_t DevAddress*/(pI2CObj->I2CAddr[pI2CObj->PresentSeqNo]<<1), /*uint8_t *pData */pI2CObj->pReadData[pI2CObj->PresentSeqNo],
                    	                                /*uint16_t Size*/pI2CObj->QTY4Read[pI2CObj->PresentSeqNo],I2C_FIRST_AND_LAST_FRAME)) {
                            //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     
                transferStatus3 = false;
                ErrorI2C_3=false;
                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 (HAL_OK != HAL_I2C_Master_Seq_Transmit_IT(&hi2c3, /*uint16_t DevAddress*/(pI2CObj->I2CAddr[pI2CObj->PresentSeqNo]<<1), /*uint8_t *pData */pI2CObj->pWriteData[pI2CObj->PresentSeqNo],
                    	                                /*uint16_t Size*/pI2CObj->QTY4Write[pI2CObj->PresentSeqNo], /*uint32_t XferOptions*/I2C_FIRST_FRAME)) {
                            //fail to request
                            return -1; //fail
                        }
                        else
                        {
                            //success to request
                        	Delay_3=0;
                            pI2CObj->state++;
                        }
                        
                       
                    } 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 (HAL_OK != HAL_I2C_Master_Seq_Transmit_IT(&hi2c3, /*uint16_t DevAddress*/(pI2CObj->I2CAddr[pI2CObj->PresentSeqNo]<<1), /*uint8_t *pData*/pI2CObj->pWriteData[pI2CObj->PresentSeqNo],
                    	                                /*uint16_t Size*/ pI2CObj->QTY4Write[pI2CObj->PresentSeqNo],I2C_FIRST_AND_LAST_FRAME)) {
                            //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 (HAL_OK != HAL_I2C_Master_Seq_Receive_IT(&hi2c3, /*uint16_t DevAddress*/(pI2CObj->I2CAddr[pI2CObj->PresentSeqNo]<<1), /*uint8_t *pData */pI2CObj->pReadData[pI2CObj->PresentSeqNo],
                    	                                /*uint16_t Size*/pI2CObj->QTY4Read[pI2CObj->PresentSeqNo],I2C_FIRST_AND_LAST_FRAME)) {
                            //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                  
                transferStatus4 = false;
                ErrorI2C_4=false;
                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 (HAL_OK != HAL_I2C_Master_Seq_Transmit_IT(&hi2c4, /*uint16_t DevAddress*/(pI2CObj->I2CAddr[pI2CObj->PresentSeqNo]<<1), /*uint8_t *pData */pI2CObj->pWriteData[pI2CObj->PresentSeqNo],
                    	                                /*uint16_t Size*/pI2CObj->QTY4Write[pI2CObj->PresentSeqNo], /*uint32_t XferOptions*/I2C_FIRST_FRAME)) {
                            //fail to request
                            return -1; //fail
                        }
                        else
                        {
                            //success to request
                        	Delay_4 = 0;
                            pI2CObj->state++;
                        }
                        
                       
                    } 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 (HAL_OK != HAL_I2C_Master_Seq_Transmit_IT(&hi2c4, /*uint16_t DevAddress*/(pI2CObj->I2CAddr[pI2CObj->PresentSeqNo]<<1), /*uint8_t *pData*/pI2CObj->pWriteData[pI2CObj->PresentSeqNo],
                    	                                /*uint16_t Size*/ pI2CObj->QTY4Write[pI2CObj->PresentSeqNo],I2C_FIRST_AND_LAST_FRAME)) {
                            //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 (HAL_OK != HAL_I2C_Master_Seq_Receive_IT(&hi2c4, /*uint16_t DevAddress*/(pI2CObj->I2CAddr[pI2CObj->PresentSeqNo]<<1), /*uint8_t *pData */pI2CObj->pReadData[pI2CObj->PresentSeqNo],
                    	                                /*uint16_t Size*/pI2CObj->QTY4Read[pI2CObj->PresentSeqNo],I2C_FIRST_AND_LAST_FRAME)) {
                            //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 1:
        	//need to read from re-start
        	if (1 == pI2CObj->I2C_Peripheral_No) {
#ifdef USE_I2C1
        		if (transferStatus1)
        		{
        			transferStatus1=0;
        			/* successfully done I2C Action: first writing, so now reading */
        			if (HAL_OK == HAL_I2C_Master_Seq_Receive_IT(/* I2C_HandleTypeDef *hi2c */ &hi2c1, /*uint16_t DevAddress*/(pI2CObj->I2CAddr[pI2CObj->PresentSeqNo]<<1) ,
        					/*uint8_t *pData */pI2CObj->pReadData[pI2CObj->PresentSeqNo],
							/* uint16_t Size */pI2CObj->QTY4Read[pI2CObj->PresentSeqNo], /*uint32_t XferOptions*/I2C_LAST_FRAME)) {
        				pI2CObj->state = 2;
        				Delay_1 = 0;
        				ReTry_1=0;
        			}
        			else {
        				pI2CObj->state =0;
        				Delay_1 = 0;
        				ReTry_1=0;
        				return -1; //fail
        			}

        		}
        		else if (ErrorI2C_1)  {
        			ErrorI2C_1=false;
        			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
        		{
        			/* NOT success 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;
        				return (-1); //fail
        			} else {
        				ReTry_1++;
        				pI2CObj->state = 0;
        				Delay_1 = 0;
        				return 1; //continue
        			}
        		}
        		return 1; //continue
#else
                pI2CObj->state = 0;
                return -1;
#endif

        	}
        	else if (2 == pI2CObj->I2C_Peripheral_No) {
#ifdef USE_I2C2
        		if (transferStatus2)
        		{
        			transferStatus2=false;
        			/* successfully done I2C Action: first writing, so now reading */
        			if (HAL_OK == HAL_I2C_Master_Seq_Receive_IT(/* I2C_HandleTypeDef *hi2c */ &hi2c2, /*uint16_t DevAddress*/(pI2CObj->I2CAddr[pI2CObj->PresentSeqNo]<<1) ,
        					/*uint8_t *pData */pI2CObj->pReadData[pI2CObj->PresentSeqNo],
							/* uint16_t Size */pI2CObj->QTY4Read[pI2CObj->PresentSeqNo], /*uint32_t XferOptions*/I2C_LAST_FRAME)) {
        				pI2CObj->state = 2;
        				Delay_2 = 0;
        				ReTry_2=0;
        			}
        			else {
        				pI2CObj->state =0;
        				Delay_2 = 0;
        				ReTry_2=0;
        				return -1; //fail
        			}

        		}
        		else if (ErrorI2C_2)  {
        			ErrorI2C_2=false;
        			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
        		{
        			/* NOT success 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;
        				return (-1); //fail
        			} else {
        				ReTry_2++;
        				pI2CObj->state = 0;
        				Delay_2 = 0;
        				return 1; //continue
        			}
        		}
        		return 1; //continue
#else
                pI2CObj->state = 0;
                return -1;
#endif

        	}
        	else if (3 == pI2CObj->I2C_Peripheral_No) {
#ifdef USE_I2C3
        		if (transferStatus3)
        		{
        			transferStatus3=false;
        			/* successfully done I2C Action: first writing, so now reading */
        			if (HAL_OK == HAL_I2C_Master_Seq_Receive_IT(/* I2C_HandleTypeDef *hi2c */ &hi2c3, /*uint16_t DevAddress*/(pI2CObj->I2CAddr[pI2CObj->PresentSeqNo]<<1) ,
        					/*uint8_t *pData */pI2CObj->pReadData[pI2CObj->PresentSeqNo],
							/* uint16_t Size */pI2CObj->QTY4Read[pI2CObj->PresentSeqNo], /*uint32_t XferOptions*/I2C_LAST_FRAME)) {
        				pI2CObj->state = 2;
        				Delay_3 = 0;
        				ReTry_3=0;
        			}
        			else {
        				pI2CObj->state =0;
        				Delay_3 = 0;
        				ReTry_3=0;
        				return -1; //fail
        			}

        		}
        		else if (ErrorI2C_3)  {
        			ErrorI2C_3=false;
        			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
        		{
        			/* NOT success 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;
        				return (-1); //fail
        			} else {
        				ReTry_3++;
        				pI2CObj->state = 0;
        				Delay_3 = 0;
        				return 1; //continue
        			}
        		}
        		return 1; //continue
#else
        		pI2CObj->state = 0;
        		return -1;
#endif

        	}
        	else if (4 == pI2CObj->I2C_Peripheral_No) {
#ifdef USE_I2C4
        		if (transferStatus4)
        		{
        			transferStatus4=false;
        			/* successfully done I2C Action: first writing, so now reading */
        			if (HAL_OK == HAL_I2C_Master_Seq_Receive_IT(/* I2C_HandleTypeDef *hi2c */ &hi2c4, /*uint16_t DevAddress*/(pI2CObj->I2CAddr[pI2CObj->PresentSeqNo]<<1) ,
        					/*uint8_t *pData */pI2CObj->pReadData[pI2CObj->PresentSeqNo],
							/* uint16_t Size */pI2CObj->QTY4Read[pI2CObj->PresentSeqNo], /*uint32_t XferOptions*/I2C_LAST_FRAME)) {
        				pI2CObj->state = 2;
        				Delay_4 = 0;
        				ReTry_4=0;
        			}
        			else {
        				pI2CObj->state =0;
        				Delay_4 = 0;
        				ReTry_4=0;
        				return -1; //fail
        			}

        		}
        		else if (ErrorI2C_4)  {
        			ErrorI2C_4=false;
        			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
        		{
        			/* NOT success 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;
        				return (-1); //fail
        			} else {
        				ReTry_4++;
        				pI2CObj->state = 0;
        				Delay_4 = 0;
        				return 1; //continue
        			}
        		}
        		return 1; //continue
#else
        		pI2CObj->state = 0;
        		return -1;
#endif

        	}
        	break;
        case 2:
            //Done?
            if (1 == pI2CObj->I2C_Peripheral_No) {
#ifdef USE_I2C1   
                if (transferStatus1)
                {
                    /* successfully done I2C Action */                    
                    pI2CObj->state = 0;
                    Delay_1 = 0;
                    ReTry_1=0;
                    return 0; //success
                }
                else if (ErrorI2C_1)  {
                	ErrorI2C_1=false;
                	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
                {
                    /* NOT success 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;
                        return (-1); //fail
                    } else {
                        ReTry_1++;
                        pI2CObj->state = 0;
                        Delay_1 = 0;
                        return 1; //continue
                    }
                }              
                return 1; //continue
                
#else
                pI2CObj->state = 0;
                return -1;
#endif
            } else if (2 == pI2CObj->I2C_Peripheral_No) {
#ifdef USE_I2C2     
                if (transferStatus2 )
                {
                    /* successfully done I2C Action */                    
                    pI2CObj->state = 0;
                    Delay_2 = 0;
                    ReTry_2=0;
                    return 0; //success
                }
                else if (ErrorI2C_2)  {
                	ErrorI2C_2=false;
                	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
                {
                    /* Error 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;
                        return (-1); //fail
                    } else {
                        ReTry_2++;
                        pI2CObj->state = 0;
                        Delay_2 = 0;
                        return 1; //continue
                    }
                }              
                return 1; //continue                                               
#else
                pI2CObj->state = 0;
                return -1;
#endif
            } else if (3 == pI2CObj->I2C_Peripheral_No) {
#ifdef USE_I2C3 
                if (transferStatus3)
                {
                    /* successfully done I2C Action */                    
                    pI2CObj->state = 0;
                    Delay_3 = 0;
                    ReTry_3=0;
                    return 0; //success
                }
                else if (ErrorI2C_3)  {
                	ErrorI2C_3=false;
                	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
                {
                    /* Error 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;
                        return (-1); //fail
                    } else {
                        ReTry_3++;
                        pI2CObj->state = 0;
                        Delay_3 = 0;
                        return 1; //continue
                    }
                }              
                return 1; //continue         
#else
                pI2CObj->state = 0;
                return -1;
#endif
            } else if (4 == pI2CObj->I2C_Peripheral_No) {
#ifdef USE_I2C4 
                if (transferStatus4 )
                {
                    /* successfully done I2C Action */                    
                    pI2CObj->state = 0;
                    Delay_4 = 0;
                    ReTry_4=0;
                    return 0; //success
                }
                else if (ErrorI2C_4)  {
                	ErrorI2C_4=false;
                	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
                {
                    /* Error 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;
                        return (-1); //fail
                    } else {
                        ReTry_4++;
                        pI2CObj->state = 0;
                        Delay_4 = 0;
                        return 1; //continue
                    }
                }              
                return 1; //continue                  
                
#else           
                pI2CObj->state = 0;
                return -1;
#endif
            }

    }
    return 1;
}




