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

#ifndef __KPM32xx_DDL_SCI_I2C_H
#define __KPM32xx_DDL_SCI_I2C_H

#ifdef __cplusplus
extern "C" {
#endif

#include "kpm32xx_ddl_def.h"
#include "kpm32xx_ddl_sci_common.h"




/* SCI IIC init Structure definition */
typedef struct
{
	uint32_t baudRate;        /* I2C baudrate*/
	uint32_t mlsb;            /* MSB or LSB */
	uint32_t workMode;        /* Only support Master mode */
	uint32_t sdaHold;         /* Setup SDA Hold Time */
	uint32_t fastMode;        /* I2C Fast Mode, for 1Mbps baudrate */
    uint32_t clkPres;         /* clkPres and brDiv1And2 are used for SCI I2C baudrate */
	uint32_t brDiv1And2;      /* clkPres and brDiv1And2 are used for SCI I2C baudrate */
} SCII2C_Init_T;


/* SCI I2C dummy data*/
#define __I2C_08BIT_DUMMY_DATA__                            0x99

/* SCI I2C lsb and msb chose */
#define SCII2C_LSB_FIRST                                    SCI_MC_DATDIR
#define SCII2C_MSB_FIRST                                    0

/* SCI I2C clksync enable or disable */
#define SCII2C_CLKSYNC_ENABLE                               SCI_MI2C_CLKSYNC
#define SCII2C_CLKSYNC_DISABLE                              0

/* SCI I2C fastmode enable or disable */
#define SCII2C_FASTMODE_ENABLE                              SCI_MI2C_FSTMOD
#define SCII2C_FASTMODE_DISABLE                             0

/* SCI I2C error code*/
#define DDL_SCII2C_ERROR_NONE                               ((uint32_t)0x00000000U)    /* No error                */
#define DDL_SCII2C_ERROR_PE                                 ((uint32_t)0x00000001U)    /* parity error            */
#define DDL_SCII2C_ERROR_FE                                 ((uint32_t)0x00000002U)    /* Frame error             */
#define DDL_SCII2C_ERROR_ORE                                ((uint32_t)0x00000004U)    /* Overrun error           */
#define DDL_SCII2C_ERROR_DMA                                ((uint32_t)0x00000008U)    /* DMA transfer error      */

/* SCI I2C Tx and Rx Mode */
#define SCII2C_MODE_RX                                      ((uint32_t)0x00000001U)    /* RX mode */
#define SCII2C_MODE_TX                                      ((uint32_t)0x00000002U)    /* TX mode */

#define IS_SCII2C_MODE(__MODE__)                            (((__MODE__) == SCII2C_MODE_RX) || ((__MODE__) == SCII2C_MODE_TX))

#define IS_SCII2C_INSTANCE(__INSTANCE__)                    (((__INSTANCE__) == SCI0) || ((__INSTANCE__) == SCI1) || ((__INSTANCE__) == SCI2))

/* SCI I2C  TX and RX set */
#define __DDL_SCII2C_SET_TX_MODE(__INSTANCE__) 	              SET_BIT((__INSTANCE__)->MC, SCI_MC_TXEN);
#define __DDL_SCII2C_CLEAR_TX_MODE(__INSTANCE__) 	          CLEAR_BIT((__INSTANCE__)->MC, SCI_MC_TXEN);
#define __DDL_SCII2C_SET_RX_MODE(__INSTANCE__)                SET_BIT((__INSTANCE__)->MC, SCI_MC_RXEN);
#define __DDL_SCII2C_CLEAR_RX_MODE(__INSTANCE__) 	          CLEAR_BIT((__INSTANCE__)->MC, SCI_MC_RXEN);

/* SCI I2C  interrupt enable or disable set */
#define __DDL_SCII2C_INTRENABLE(__INSTANCE__, __INTERRUPTS__)   SET_BIT((__INSTANCE__)->IE, (__INTERRUPTS__))
#define __DDL_SCII2C_INTRDISABLE(__INSTANCE__, __INTERRUPTS__)  CLEAR_BIT((__INSTANCE__)->IE, (__INTERRUPTS__))

/* SCI I2C  dma enable or disable set */
#define __DDL_SCII2C_DMA_ENABLE(__INSTANCE__)                   SET_BIT((__INSTANCE__)->MC, SCI_MC_DMAEN)
#define __DDL_SCII2C_DMA_DISABLE(__INSTANCE__)                  CLEAR_BIT((__INSTANCE__)->MC, SCI_MC_DMAEN)

/* For I2C Start & Stop & Restart Signal */
#define __DDL_SCII2C_STT_GENERATE(__INSTANCE__)                 do { while(((__INSTANCE__)->MIIC & SCI_MI2C_STP) || ((__INSTANCE__)->MIIC & SCI_MI2C_RSTT) || ((__INSTANCE__)->MIIC & SCI_MI2C_STT)) ; \
																    WRITE_REG((__INSTANCE__)->CLR, SCI_CLR_FNS); \
																    SET_BIT((__INSTANCE__)->MIIC, SCI_MI2C_STT); \
																	while(!(((__INSTANCE__)->ST) & SCI_ST_FNS)); \
																	WRITE_REG((__INSTANCE__)->CLR, SCI_CLR_FNS); \
															 }while(0);

#define __DDL_SCII2C_RSTT_GENERATE(__INSTANCE__)                do { while(((__INSTANCE__)->MIIC & SCI_MI2C_STP) || ((__INSTANCE__)->MIIC & SCI_MI2C_RSTT) || ((__INSTANCE__)->MIIC & SCI_MI2C_STT)) ; \
																    WRITE_REG((__INSTANCE__)->CLR, SCI_CLR_FNS); \
																    SET_BIT((__INSTANCE__)->MIIC, SCI_MI2C_RSTT); \
																	while(!(((__INSTANCE__)->ST) & SCI_ST_FNS)); \
																	WRITE_REG((__INSTANCE__)->CLR, SCI_CLR_FNS); \
															 }while(0);

#define __DDL_SCII2C_STP_GENERATE(__INSTANCE__)                 SET_BIT((__INSTANCE__)->MIIC, SCI_MI2C_STP)


/* SCI I2C SDA Hold */
#define SCII2C_HLDCNT_0                                        (0x00 << SCI_MI2C_HOLD_Pos)
#define SCII2C_HLDCNT_1_8                                      (0x01 << SCI_MI2C_HOLD_Pos)
#define SCII2C_HLDCNT_1_4                                      (0x02 << SCI_MI2C_HOLD_Pos)
#define SCII2C_HLDCNT_1_2                                      (0x03 << SCI_MI2C_HOLD_Pos)

/* SCI I2C sethldcnt */
#define __DDL_SCII2C_SETHLDCNT(__INSTANCE__, __HLDCNT__)        MODIFY_REG((__INSTANCE__)->MIIC, SCI_MI2C_HOLD_Msk, __HLDCNT__)

#define __DDL_SCII2C_CLKSYNC(__INSTANCE__, __CLKSYNC__)         MODIFY_REG((__INSTANCE__)->MIIC, SCI_MI2C_CLKSYNC_Msk, __CLKSYNC__)

#define __DDL_SCII2C_FASTMODE(__INSTANCE__, __FASTMODE__)       MODIFY_REG((__INSTANCE__)->MIIC, SCI_MI2C_FSTMOD_Msk, __FASTMODE__)

/* NACK Signal Generate */
#define __DDL_SCII2C_NACK_GENERATE(__INSTANCE__)                SET_BIT((__INSTANCE__)->MIIC,   SCI_MI2C_ACK)
/* ACK Signal Generate */
#define __DDL_SCII2C_ACK_GENERATE(__INSTANCE__)                 CLEAR_BIT((__INSTANCE__)->MIIC, SCI_MI2C_ACK)


/**
  * @brief  Enable SCI IIC TX or RX interrupt.
  *
  * @param  SCIx Pointer to SCI IIC instance.
  * @param  intrMask SCI IIC TX and RX mask.
  *
  * @retval None
  */
void DDL_SCIIIC_IntEnable(SCI_Type *SCIx, uint32_t intrMask);


/**
  * @brief  Disable SCI IIC TX or RX interrupt.
  *
  * @param  SCIx Pointer to SCI IIC instance.
  * @param  intrMask SCI IIC TX and RX mask.
  *
  * @retval None
  */
void DDL_SCIIIC_IntDisable(SCI_Type *SCIx, uint32_t intrMask);


/**
  * @brief  Configure the elements of structure SCII2C_Init_T to default values.
  *
  * @param  pSCII2CStruct Pointer to a SCII2C_Init_T structure that contains
  *                  the configuration information for the given SCI I2C module.
  *
  * @retval None
  */
void DDL_SCII2C_StructInit(SCII2C_Init_T *pSCII2CStruct);


/**
  * @brief  Initializes the SCI I2C by the specified parameters
  *         in the SCII2C_Init_T and initialize the associated handle.
  * @param  SCIx     Pointer to SCI IIC instance.
  * @param  pSCII2CStruct   pointer to a SCII2C_Init_T structure that contains
  *                the configuration information for the specified I2C.
  *
  * @retval None
  */
void DDL_SCII2C_Init(SCI_Type *SCIx, SCII2C_Init_T *pSCII2CStruct);


/**
  * @brief  SCI I2C as master transmits an amount of data through polling mode.
  * @param  SCIx     Pointer to SCI IIC instance.
  *         slvAddr  slave address.
  *         pData    pointer to data buffer.
  *         size     the amount of data to be sent.
  *         timeout  timeout duration.
  *
  * @retval DDL status
  */
DDL_Status_T DDL_SCII2C_Master_Transmit(SCI_Type *SCIx, uint16_t slvAddr, uint8_t *pData, uint16_t size, uint32_t timeout);


/**
  * @brief  SCI I2C as master receives an amount of data through polling mode.
  * @param  SCIx     Pointer to SCI IIC instance.
  *         slvAddr  slave address.
  *         pData    pointer to data buffer.
  *         size     the amount of data to receive.
  *         timeout  timeout duration.
  *
  * @retval DDL status
  */
DDL_Status_T DDL_SCII2C_Master_Receive(SCI_Type *SCIx, uint16_t slvAddr, uint8_t *pData, uint16_t size, uint32_t timeout);


#ifdef __cplusplus
}
#endif

#endif /* KPM32xx_DDL_SERIAL_UNIT_I2C_H */
