#include "i2c_slave.h"
#if APP_I2C_SLAVE_ENABLE
#define I2C_SPEEDCLOCK 100000 /* Communication speed : 100K */
#define I2C_WR 1              // 写控制bit
#define I2C_RD 2              // 读控制bit
#define RX_MAX_LEN 50
static uint8_t I2C_SRAM[RX_MAX_LEN] = {0};
/********************************************************
**	函数名	void I2C_Init(void)
**	描述	：初始化I2C
**	传入	：
**	返回	：
*********************************************************/
void I2C_Init(void)
{
    /* Enable I2C1 peripheral clock */
    LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_I2C1);
#if (I2C_SLAVE_SCL == 23 || I2C_SLAVE_SCL == 24)
    GPIO_Init(I2C_SLAVE_SCL, PULL_UP | OPENDRAIN | ALTERNATE | GPIO_I2C_AF3); // SCL
#else
    GPIO_Init(I2C_SLAVE_SCL, PULL_UP | OPENDRAIN | ALTERNATE | GPIO_I2C_AF4); // SCL
#endif
    GPIO_Init(I2C_SLAVE_SDA, PULL_UP | OPENDRAIN | ALTERNATE | GPIO_I2C_AF4); // SDA
    /* Enable I2C Peripheral interruption request */
    NVIC_SetPriority(I2C1_IRQn, 0);
    NVIC_EnableIRQ(I2C1_IRQn);
    /* Reset I2C peripheral */
    LL_APB1_GRP1_ForceReset(LL_APB1_GRP1_PERIPH_I2C1);
    LL_APB1_GRP1_ReleaseReset(LL_APB1_GRP1_PERIPH_I2C1);
    /* I2C initialization */
    LL_I2C_InitTypeDef I2C_InitStruct;
    I2C_InitStruct.ClockSpeed = I2C_SPEEDCLOCK;
    I2C_InitStruct.DutyCycle = LL_I2C_DUTYCYCLE_16_9;
    I2C_InitStruct.DataHoldTimeSel = LL_I2C_DATA_HOLD_TIME_HARDWARE;
    I2C_InitStruct.OwnAddress1 = I2C_SLAVE_ADDRESS;
    I2C_InitStruct.TypeAcknowledge = LL_I2C_NACK;
    LL_I2C_Init(I2C1, &I2C_InitStruct);
    /*	使能接收	*/
    /* Clear POS bit */
    LL_I2C_DisableBitPOS(I2C1);
    /* Enable acknowledge */
    LL_I2C_AcknowledgeNextData(I2C1, LL_I2C_ACK);
    /* Enable interrupt */
    LL_I2C_EnableIT_EVT(I2C1);
    LL_I2C_EnableIT_BUF(I2C1);
    LL_I2C_EnableIT_ERR(I2C1);
}
/**
 * @brief This function handles I2C interrupt.
 */
void I2C1_IRQHandler(void)
{
    static uint8_t DIR;
    static uint8_t addr;
    static uint8_t state;
	uint8_t reset_i2c = 0;
    /* Set ADDR flag */
    if (LL_I2C_IsActiveFlag_ADDR(I2C1))
    {
        LL_I2C_ClearFlag_ADDR(I2C1);
        if (I2C1->SR2 & (1 << 2))
            DIR = I2C_RD;
        else
            DIR = I2C_WR;
        state = 0;
    }
    /* Set STOP flag */
    else if (LL_I2C_IsActiveFlag_STOP(I2C1))
    {
        LL_I2C_ClearFlag_STOP(I2C1);
		if (DIR != 0)
        {
			reset_i2c = 1;
        }
        DIR = 0;
    }
    /* Slave Receive */
    else if (DIR == I2C_WR) // 写入数据
    {
        if (state == 0) // 获取寄存器地址
        {
            state = 1;
            /* Set RXNE flag, BTF flag is not set */
            if ((LL_I2C_IsActiveFlag_RXNE(I2C1) == 1) && (LL_I2C_IsActiveFlag_BTF(I2C1) == 0))
            {
                addr = LL_I2C_ReceiveData8(I2C1);
            }
            /* Set BTF flag */
            else if ((LL_I2C_IsActiveFlag_BTF(I2C1) == 1))
            {
                addr = LL_I2C_ReceiveData8(I2C1);
            }
        }
        else // 获取数据
        {
            /* Set RXNE flag, BTF flag is not set */
            if ((LL_I2C_IsActiveFlag_RXNE(I2C1) == 1) && (LL_I2C_IsActiveFlag_BTF(I2C1) == 0))
            {
                I2C_SRAM[addr++] = LL_I2C_ReceiveData8(I2C1);
            }
            /* Set BTF flag */
            else if ((LL_I2C_IsActiveFlag_BTF(I2C1) == 1))
            {
                I2C_SRAM[addr++] = LL_I2C_ReceiveData8(I2C1);
            }
        }
    }
    else if (DIR == I2C_RD) // 读出数据
    {
        /* Check if TxE bit is set and BTF bit is clear */
        if ((LL_I2C_IsActiveFlag_TXE(I2C1) == 1) && (LL_I2C_IsActiveFlag_BTF(I2C1) == 0))
        {
            LL_I2C_TransmitData8(I2C1, I2C_SRAM[addr++]);
        }
        /* Check if BTF bit is set */
        else if ((LL_I2C_IsActiveFlag_BTF(I2C1) == 1))
        {
            LL_I2C_TransmitData8(I2C1, I2C_SRAM[addr++]);
        }
    }
    if ((LL_I2C_IsActiveFlag_AF(I2C1) == 1))
    {
        LL_I2C_ClearFlag_AF(I2C1);
		reset_i2c = 1;
    }
    if ((LL_I2C_IsActiveFlag_BERR(I2C1) == 1))
    {
        LL_I2C_ClearFlag_BERR(I2C1);
		reset_i2c = 1;
    }
    if ((LL_I2C_IsActiveFlag_ARLO(I2C1) == 1))
    {
        LL_I2C_ClearFlag_ARLO(I2C1);
		reset_i2c = 1;
    }
    if ((LL_I2C_IsActiveFlag_OVR(I2C1) == 1))
    {
        LL_I2C_ClearFlag_OVR(I2C1);
		reset_i2c = 1;
    }
	if(reset_i2c == 1)
	{
		LL_I2C_Disable(I2C1);
		LL_I2C_Enable(I2C1);
		LL_I2C_AcknowledgeNextData(I2C1, LL_I2C_ACK);
	}
}
#endif
