/*
* Copyright (c) 2023-2028, SpaceTouch Inc.
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date          Author      Notes
* 2023-07-18    zhixiongl       the first version
*/


#include <stdio.h>
#include <stdarg.h>
#include "board.h"
#include "hal_log.h"
#include "hal_i2c.h"
#include "hal_gpio.h"
#include "hal_common.h"
#include "hal_cmu.h"
#include "debug.h"

//---------------------------------------------------I2C Master---------------------start--------------
/**
* @brief        hal_i2c_start
* @details      None
* @param[in]    i2c_port
* @param[in]    addr
* @return       HAL_I2C_EOK
                -HAL_I2C_ERROR
* @note         None
*/
int32_t hal_i2c_start(i2c_port_t i2c_port, uint16_t addr)
{
    if (i2c_port == I2C_0)
    {
        //HAL_I2C_LOG("start send start\n");
        DEV_IIC0->CTL = DEV_IICn_CTL_CMD_STARTCMD
                        | DEV_IICn_CTL_TX_ACK_MASK
                        | addr;

        while ((DEV_IIC0->PD & DEV_IICn_PD_BYTE_END) == 0);

        DEV_IIC0->PD = 0x1F;
        //HAL_I2C_LOG("send start success\n");
    }
    else if (i2c_port == I2C_1)
    {
        DEV_IIC1->CTL = DEV_IICn_CTL_CMD_STARTCMD
                        | DEV_IICn_CTL_TX_ACK_MASK
                        | addr;

        while ((DEV_IIC1->PD & DEV_IICn_PD_BYTE_END) == 0);

        DEV_IIC1->PD = 0x1F;
    }
    else
    {
        return -HAL_I2C_ERROR;
    }

    return HAL_I2C_EOK;
}

/**
* @brief        hal_i2c_restart
* @details      None
* @param[in]    i2c_port
* @param[in]    addr
* @return       HAL_I2C_EOK
                -HAL_I2C_ERROR
* @note         None
*/
int32_t hal_i2c_restart(i2c_port_t i2c_port, uint16_t addr)
{
    if (i2c_port == I2C_0)
    {
        DEV_IIC0->CTL = DEV_IICn_CTL_CMD_RESTARTCMD
                        | DEV_IICn_CTL_TX_ACK_MASK
                        | addr;

        while ((DEV_IIC0->PD & DEV_IICn_PD_BYTE_END) == 0);

        DEV_IIC0->PD = 0x1F;
    }
    else if (i2c_port == I2C_1)
    {
        DEV_IIC1->CTL = DEV_IICn_CTL_CMD_RESTARTCMD
                        | DEV_IICn_CTL_TX_ACK_MASK
                        | addr;

        while ((DEV_IIC1->PD & DEV_IICn_PD_BYTE_END) == 0);

        DEV_IIC1->PD = 0x1F;
    }
    else
    {
        return -HAL_I2C_ERROR;
    }

    return HAL_I2C_EOK;
}

/**
* @brief        hal_i2c_stop
* @details      None
* @param[in]    i2c_port
* @return       HAL_I2C_EOK
                -HAL_I2C_ERROR
* @note         None
*/
int32_t hal_i2c_stop(i2c_port_t i2c_port)
{
    if (i2c_port == I2C_0)
    {
        DEV_IIC0->CTL = DEV_IICn_CTL_CMD_STOPCMD
                        | DEV_IICn_CTL_TX_ACK_MASK
                        | DEV_IICn_CTL_TX_DAT_MASK;

        while ((DEV_IIC0->PD & DEV_IICn_PD_STOP_DET) == 0);

        DEV_IIC0->PD = 0x1F;
    }
    else if (i2c_port == I2C_1)
    {
        DEV_IIC1->CTL = DEV_IICn_CTL_CMD_STOPCMD
                        | DEV_IICn_CTL_TX_ACK_MASK
                        | DEV_IICn_CTL_TX_DAT_MASK;

        while ((DEV_IIC1->PD & DEV_IICn_PD_STOP_DET) == 0);

        DEV_IIC1->PD = 0x1F;
    }
    else
    {
        return -HAL_I2C_ERROR;
    }

    return HAL_I2C_EOK;
}

/**
* @brief        hal_i2c_send_byte
* @details      None
* @param[in]    i2c_port
* @param[in]    data
* @return       HAL_I2C_EOK
                -HAL_I2C_ERROR
* @note         None
*/
int32_t hal_i2c_send_byte(i2c_port_t i2c_port, uint8_t data)
{
    if (i2c_port == I2C_0)
    {
        DEV_IIC0->CTL = DEV_IICn_CTL_CMD_RELEASEBUS
                        | DEV_IICn_CTL_TX_ACK_ACK
                        | data;

        while ((DEV_IIC0->PD & DEV_IICn_PD_BYTE_END) == 0);

        DEV_IIC0->PD = 0x1F;
    }
    else if (i2c_port == I2C_1)
    {
        DEV_IIC1->CTL = DEV_IICn_CTL_CMD_RELEASEBUS
                        | DEV_IICn_CTL_TX_ACK_ACK
                        | data;

        while ((DEV_IIC1->PD & DEV_IICn_PD_BYTE_END) == 0);

        DEV_IIC1->PD = 0x1F;
    }
    else
    {
        return -HAL_I2C_ERROR;
    }

    return HAL_I2C_EOK;
}

/**
* @brief        hal_i2c_send_bytes
* @details      None
* @param[in]    i2c_port
* @param[in]    buf
* @param[in]    len
* @return       HAL_I2C_EOK
                -HAL_I2C_ERROR
* @note         None
*/
int32_t hal_i2c_send_bytes(i2c_port_t i2c_port, uint8_t *buf, uint16_t len)
{
    while (len > 0)
    {
        if (hal_i2c_send_byte(i2c_port, *buf) != HAL_I2C_EOK)
        {
            HAL_I2C_LOG("send data Fail\n");
            return -HAL_I2C_ERROR;
        }

        len --;
        buf ++;
    }

    HAL_I2C_LOG("send data Success\n");
    return HAL_I2C_EOK;
}

/**
* @brief        hal_i2c_recv_bytes
* @details      None
* @param[in]    i2c_port
* @param[in]    buf
* @param[in]    len
* @return       HAL_I2C_EOK
                -HAL_I2C_ERROR
* @note         None
*/
int32_t hal_i2c_recv_bytes(i2c_port_t i2c_port, uint8_t *buf, uint16_t len)
{
    uint8_t val;

    while (len > 0)
    {
        if (i2c_port == I2C_0)
        {
            if (len > 1)
            {
                DEV_IIC0->CTL = DEV_IICn_CTL_CMD_RELEASEBUS
                                | DEV_IICn_CTL_TX_ACK_ACK
                                | DEV_IICn_CTL_TX_DAT_MASK;
            }
            else
            {
                //���һ��
                DEV_IIC0->CTL = DEV_IICn_CTL_CMD_RELEASEBUS
                                | DEV_IICn_CTL_TX_ACK_NACK
                                | DEV_IICn_CTL_TX_DAT_MASK;
            }

            while ((DEV_IIC0->PD & DEV_IICn_PD_BYTE_END) == 0);

            val = DEV_IIC0->RX_DAT & DEV_IICn_RX_DAT_MASK;
            DEV_IIC0->PD = 0x1F;
        }
        else if (i2c_port == I2C_1)
        {
            if (len > 1)
            {
                DEV_IIC1->CTL = DEV_IICn_CTL_CMD_RELEASEBUS
                                | DEV_IICn_CTL_TX_ACK_ACK
                                | DEV_IICn_CTL_TX_DAT_MASK;
            }
            else
            {
                //���һ��
                DEV_IIC1->CTL = DEV_IICn_CTL_CMD_RELEASEBUS
                                | DEV_IICn_CTL_TX_ACK_NACK
                                | DEV_IICn_CTL_TX_DAT_MASK;
            }

            while ((DEV_IIC1->PD & DEV_IICn_PD_BYTE_END) == 0);

            val = DEV_IIC1->RX_DAT & DEV_IICn_RX_DAT_MASK;
            DEV_IIC1->PD = 0x1F;
        }
        else
        {
            return -HAL_I2C_ERROR;
        }

        *buf = val;
        buf++;
        len --;
    }

    return HAL_I2C_EOK;
}

/**
* @brief        hal_i2c_send_address
* @details      None
* @param[in]    i2c_port
* @param[in]    addr
* @param[in]    flags
                    HAL_I2C_ADDR_10BIT
                    HAL_I2C_WR
                    HAL_I2C_RD
* @return       HAL_I2C_EOK
                -HAL_I2C_ERROR
* @note         None
*/
int32_t hal_i2c_send_address(i2c_port_t i2c_port, uint16_t addr, uint16_t flags)
{
    uint8_t addr1, addr2;
    uint32_t reg_value;
    reg_value = 0;

    if (flags & HAL_I2C_ADDR_10BIT)
    {
        addr1 = 0xf0 | ((addr >> 7) & 0x06);

        if (flags & HAL_I2C_RD)
        {
            addr1 |= 1;
        }

        addr2 = addr & 0xff;
        HAL_I2C_LOG("addr1: %d, addr2: %d\n", addr1, addr2);

        if (i2c_port == I2C_0)
        {
            reg_value = DEV_IIC0->STA;
        }
        else if (i2c_port == I2C_1)
        {
            reg_value = DEV_IIC1->STA;
        }

        if ((reg_value & DEV_IICn_STA_BUSY_BUSY) != 0)
        {
            HAL_I2C_LOG("send restart\n");

            if (hal_i2c_restart(i2c_port, addr1) != HAL_I2C_EOK)
            {
                HAL_I2C_LOG("send addr Fail\n");
                return -HAL_I2C_ERROR;
            }
        }
        else
        {
            HAL_I2C_LOG("send start\n");

            if (hal_i2c_start(i2c_port, addr1) != HAL_I2C_EOK)
            {
                HAL_I2C_LOG("send addr Fail\n");
                return -HAL_I2C_ERROR;
            }
        }

        if (hal_i2c_send_byte(i2c_port, addr2) != HAL_I2C_EOK)
        {
            HAL_I2C_LOG("send addr2 Fail\n");
            return -HAL_I2C_ERROR;
        }
    }
    else
    {
        /* 7-bit addr */
        addr1 = addr << 1;

        if (flags & HAL_I2C_RD)
        {
            addr1 |= 1;
        }

        if (i2c_port == I2C_0)
        {
            reg_value = DEV_IIC0->STA;
        }
        else if (i2c_port == I2C_1)
        {
            reg_value = DEV_IIC1->STA;
        }

        if ((reg_value & DEV_IICn_STA_BUSY_BUSY) != 0)
        {
            HAL_I2C_LOG("send restart\n");

            if (hal_i2c_restart(i2c_port, addr1) != HAL_I2C_EOK)
            {
                HAL_I2C_LOG("send addr Fail\n");
                return -HAL_I2C_ERROR;
            }
        }
        else
        {
            HAL_I2C_LOG("send start\n");

            if (hal_i2c_start(i2c_port, addr1) != HAL_I2C_EOK)
            {
                HAL_I2C_LOG("send addr Fail\n");
                return -HAL_I2C_ERROR;
            }
        }
    }

    HAL_I2C_LOG("send addr Success\n");
    return HAL_I2C_EOK;
}

/**
* @brief        hal_i2c_master_xfer
* @details      According to the target read and write timing, use this function
* @param[in]    i2c_port
* @param[in]    addr
* @param[in]    buf
* @param[in]    len
* @param[in]    flags
                    HAL_I2C_ADDR_10BIT
                    HAL_I2C_NO_START
                    HAL_I2C_NO_STOP
                    HAL_I2C_WR
                    HAL_I2C_RD
* @return       HAL_I2C_EOK
                -HAL_I2C_ERROR
* @note         None
*/
int32_t hal_i2c_master_xfer(i2c_port_t i2c_port, uint16_t addr, uint8_t *buf, uint16_t len, uint16_t flags)
{
    int32_t ret;

    if (!(flags & HAL_I2C_NO_START))
    {
        ret = hal_i2c_send_address(i2c_port, addr, flags);

        if (ret != HAL_I2C_EOK)
        {
            if (!(flags & HAL_I2C_NO_STOP))
            {
                HAL_I2C_LOG("send stop\n");
                hal_i2c_stop(i2c_port);
            }

            return ret;
        }
    }

    if (flags & HAL_I2C_RD)
    {
        ret = hal_i2c_recv_bytes(i2c_port, buf, len);

        if (ret != HAL_I2C_EOK)
        {
            HAL_I2C_LOG("receive NACK from device addr Fail\n");

            if (!(flags & HAL_I2C_NO_STOP))
            {
                HAL_I2C_LOG("send stop\n");
                hal_i2c_stop(i2c_port);
            }

            return ret;
        }
    }
    else
    {
        //RT_I2C_WR
        ret = hal_i2c_send_bytes(i2c_port, buf, len);

        if (ret != HAL_I2C_EOK)
        {
            HAL_I2C_LOG("receive NACK from device addr Fail\n");

            if (!(flags & HAL_I2C_NO_STOP))
            {
                HAL_I2C_LOG("send stop\n");
                hal_i2c_stop(i2c_port);
            }

            return ret;
        }
    }

    if (!(flags & HAL_I2C_NO_STOP))
    {
        HAL_I2C_LOG("send stop\n");
        hal_i2c_stop(i2c_port);
    }

    return ret;
}

/**
* @brief        hal_i2c_init
* @details      None
* @param[in]    i2c_port
* @return       HAL_I2C_EOK
                -HAL_I2C_ERROR
* @note         None
*/
int32_t hal_i2c_init(i2c_port_t i2c_port)
{
    if (i2c_port == I2C_0)
    {
        cmu_i2c_set_clk(I2C_0, CMU_Clock_OSC_XTAL);
        DEV_IIC0->CFG = DEV_IICn_CFG_IIC_EN_ENABLE
                        | DEV_IICn_CFG_DIV_COE(24000000, 100000)  //100K
                        | DEV_IICn_CFG_SLV_ADDR_MASK
                        | DEV_IICn_CFG_MODE_MASTER;
#ifdef HAL_I2C0_SCL_PIN
        hal_gpio_pinmux_set_function(HAL_I2C0_SCL_PIN, GPIO_MUXSEL_FUNCTION4);
        hal_gpio_set_pull(HAL_I2C0_SCL_PIN, GPIO_PULL_UP);
#endif
#ifdef HAL_I2C0_SDA_PIN
        hal_gpio_pinmux_set_function(HAL_I2C0_SDA_PIN, GPIO_MUXSEL_FUNCTION4);
        hal_gpio_set_pull(HAL_I2C0_SDA_PIN, GPIO_PULL_UP);
#endif
    }

    if (i2c_port == I2C_1)
    {
        cmu_i2c_set_clk(I2C_1, CMU_Clock_OSC_XTAL);
        DEV_IIC1->CFG = DEV_IICn_CFG_IIC_EN_ENABLE
                        | DEV_IICn_CFG_DIV_COE(24000000, 100000)  //100K
                        | DEV_IICn_CFG_SLV_ADDR_MASK
                        | DEV_IICn_CFG_MODE_MASTER;
#ifdef HAL_I2C1_SCL_PIN

        if (HAL_I2C1_SCL_PIN == GPIO38)
        {
            hal_gpio_pinmux_set_function(HAL_I2C1_SCL_PIN, GPIO_MUXSEL_FUNCTION5);
        }
        else if (HAL_I2C1_SCL_PIN == GPIO39)
        {
            hal_gpio_pinmux_set_function(HAL_I2C1_SCL_PIN, GPIO_MUXSEL_FUNCTION6);
        }
        else
        {
            hal_gpio_pinmux_set_function(HAL_I2C1_SCL_PIN, GPIO_MUXSEL_FUNCTION4);
        }

        hal_gpio_set_pull(HAL_I2C1_SCL_PIN, GPIO_PULL_UP);
#endif
#ifdef HAL_I2C1_SDA_PIN

        if (HAL_I2C1_SDA_PIN == GPIO38)
        {
            hal_gpio_pinmux_set_function(HAL_I2C1_SDA_PIN, GPIO_MUXSEL_FUNCTION6);
        }
        else if (HAL_I2C1_SDA_PIN == GPIO39)
        {
            hal_gpio_pinmux_set_function(HAL_I2C1_SDA_PIN, GPIO_MUXSEL_FUNCTION5);
        }
        else
        {
            hal_gpio_pinmux_set_function(HAL_I2C1_SDA_PIN, GPIO_MUXSEL_FUNCTION4);
        }

        hal_gpio_set_pull(HAL_I2C1_SDA_PIN, GPIO_PULL_UP);
#endif
    }

    return HAL_I2C_EOK;
}

//---------------------------------------------------I2C Master---------------------end--------------
//---------------------------------------------------I2C Slave---------------------start--------------
/*
I2C Slave application instruction:(take i2c0 as an example)
Step 1: configure i2c0 in board.h, such as:interface enabling,msg length,pin IO
#define BSP_USING_I2C0_SLAVE
#define I2C0_SLAVE_MSG_LEN 5
#define HAL_I2C0_SLAVE_SCL_PIN    GPIO6
#define HAL_I2C0_SLAVE_SDA_PIN    GPIO7

Step 2: Initialize i2c0 and configure the address
hal_i2c_slave_init(I2C_0,0x5A);

Step 3: Send and receive data
��receive data
if(i2c0_slave_msg_rx.busy == 0)
{
    if(i2c0_slave_msg_rx.len > 0)
    {
        for (i = 0; i < i2c0_slave_msg_rx.len; i++)
        {
            rt_kprintf("%x ", i2c0_slave_msg_rx.buf[i]);
        }
        i2c0_slave_msg_rx.len = 0;
    }
}
��send data
if(i2c0_slave_msg_rx.busy == 0)
{
    uint8_t send_data[] = {0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29};

    i2c0_slave_msg_tx.len = sizeof(send_data);
    memcpy(i2c0_slave_msg_tx.buf, send_data, sizeof(send_data));
}
*/

#ifdef BSP_USING_I2C0_SLAVE
    i2c0_slave_msg_t i2c0_slave_msg_tx;
    i2c0_slave_msg_t i2c0_slave_msg_rx;
#endif

#ifdef BSP_USING_I2C1_SLAVE
    i2c1_slave_msg_t i2c1_slave_msg_tx;
    i2c1_slave_msg_t i2c1_slave_msg_rx;
#endif

/**
* @brief        hal_i2c_slave_init
* @details      None
* @param[in]    i2c_port
* @param[in]    device_addr
* @return       HAL_I2C_EOK
                -HAL_I2C_ERROR
* @note         None
*/

// #define BSP_USING_I2C0_SLAVE
// #define HAL_I2C0_SLAVE_SCL_PIN    GPIO6
// #define HAL_I2C0_SLAVE_SDA_PIN    GPIO7



void (* hal_iic_callback)(uint8_t *buff, uint32_t length, i2c_event_t event);

void iic_set_callback(void (* pcall_back)(uint8_t *buff, uint32_t length, i2c_event_t event))
{
    if (pcall_back != NULL)
    {
        hal_iic_callback = pcall_back;
    }
}


int32_t hal_i2c_slave_init(i2c_port_t i2c_port, uint8_t device_addr)
{
#ifdef BSP_USING_I2C0_SLAVE
#ifdef HAL_I2C0_SLAVE_SCL_PIN
    hal_gpio_pinmux_set_function(HAL_I2C0_SLAVE_SCL_PIN, GPIO_MUXSEL_FUNCTION4);
    hal_gpio_set_pull(HAL_I2C0_SLAVE_SCL_PIN, GPIO_PULL_UP);
#endif
#ifdef HAL_I2C0_SLAVE_SDA_PIN
    hal_gpio_pinmux_set_function(HAL_I2C0_SLAVE_SDA_PIN, GPIO_MUXSEL_FUNCTION4);
    hal_gpio_set_pull(HAL_I2C0_SLAVE_SDA_PIN, GPIO_PULL_UP);
#endif
    hal_iic_callback = NULL;

    if (i2c_port == I2C_0)
    {
        i2c0_slave_msg_tx.busy = 0;
        i2c0_slave_msg_tx.len = 0;
        i2c0_slave_msg_rx.busy = 0;
        i2c0_slave_msg_rx.len = 0;
        cmu_i2c_set_clk(I2C_0, CMU_Clock_OSC_XTAL);
        DEV_IIC0->CFG = DEV_IICn_CFG_IIC_EN_ENABLE
                        | DEV_IICn_CFG_DIV_COE(24000000, 100000)  //100K
                        | (device_addr << 1)
                        | DEV_IICn_CFG_MODE_SLAVE;
        DEV_IIC0->IE = DEV_IICn_IE_BUS_ERR
                       | DEV_IICn_IE_START_DET
                       | DEV_IICn_IE_NACK_DET
                       | DEV_IICn_IE_BYTE_END
                       | DEV_IICn_IE_STOP_DET;
        DEV_IIC0->PD = 0xff;
        HAL_INTERRUPT_ENABLE(IRQ_SOURCE_I2C0);
    }

#endif
#ifdef BSP_USING_I2C1_SLAVE

    if (i2c_port == I2C_1)
    {
        i2c1_slave_msg_tx.busy = 0;
        i2c1_slave_msg_tx.len = 0;
        i2c1_slave_msg_rx.busy = 0;
        i2c1_slave_msg_rx.len = 0;
        cmu_i2c_set_clk(I2C_1, CMU_Clock_OSC_XTAL);
        DEV_IIC1->CFG = DEV_IICn_CFG_IIC_EN_ENABLE
                        | DEV_IICn_CFG_DIV_COE(24000000, 100000)  //100K
                        | (device_addr << 1)
                        | DEV_IICn_CFG_MODE_SLAVE;
#ifdef HAL_I2C1_SLAVE_SCL_PIN

        if (HAL_I2C1_SLAVE_SCL_PIN == GPIO38)
        {
            hal_gpio_pinmux_set_function(HAL_I2C1_SLAVE_SCL_PIN, GPIO_MUXSEL_FUNCTION5);
        }
        else if (HAL_I2C1_SLAVE_SCL_PIN == GPIO39)
        {
            hal_gpio_pinmux_set_function(HAL_I2C1_SLAVE_SCL_PIN, GPIO_MUXSEL_FUNCTION6);
        }
        else
        {
            hal_gpio_pinmux_set_function(HAL_I2C1_SLAVE_SCL_PIN, GPIO_MUXSEL_FUNCTION4);
        }

        hal_gpio_set_pull(HAL_I2C1_SLAVE_SCL_PIN, GPIO_PULL_UP);
#endif
#ifdef HAL_I2C1_SLAVE_SDA_PIN

        if (HAL_I2C1_SLAVE_SDA_PIN == GPIO38)
        {
            hal_gpio_pinmux_set_function(HAL_I2C1_SLAVE_SDA_PIN, GPIO_MUXSEL_FUNCTION6);
        }
        else if (HAL_I2C1_SLAVE_SDA_PIN == GPIO39)
        {
            hal_gpio_pinmux_set_function(HAL_I2C1_SLAVE_SDA_PIN, GPIO_MUXSEL_FUNCTION5);
        }
        else
        {
            hal_gpio_pinmux_set_function(HAL_I2C1_SLAVE_SDA_PIN, GPIO_MUXSEL_FUNCTION4);
        }

        hal_gpio_set_pull(HAL_I2C1_SLAVE_SDA_PIN, GPIO_PULL_UP);
#endif
        DEV_IIC1->IE = DEV_IICn_IE_BUS_ERR
                       | DEV_IICn_IE_START_DET
                       | DEV_IICn_IE_NACK_DET
                       | DEV_IICn_IE_BYTE_END
                       | DEV_IICn_IE_STOP_DET;
        HAL_INTERRUPT_ENABLE(IRQ_SOURCE_I2C1);
    }

#endif
    return HAL_I2C_EOK;
}

/**
* @brief        i2c0_irq_handler
* @details      None
* @param[in]    NULL
* @return         NULL
* @note         None
*/
volatile static uint8_t iic_buff[10] = {0};
volatile static uint8_t rx_cnt = 0;
volatile static uint8_t flag_write_read = 0;
void i2c0_irq_handler()
{
#ifdef BSP_USING_I2C0_SLAVE
    static uint8_t i2c0_irq_num_test = 0;

    if (DEV_IIC0->PD & DEV_IICn_PD_BUS_ERR)
    {
        //debug("err1\r\n");
        DEV_IIC0->PD = DEV_IICn_PD_BUS_ERR;
        brom_memset(iic_buff, 0, 10);
        rx_cnt = 0;
    }

    if (DEV_IIC0->PD & DEV_IICn_PD_NACK_DET)
    {
        //debug("err2\r\n");
        DEV_IIC0->PD = DEV_IICn_PD_NACK_DET;
    }

    if (DEV_IIC0->PD & DEV_IICn_PD_START_DET) //起始信号
    {
        DEV_IIC0->PD = DEV_IICn_PD_START_DET;

        if (DEV_IIC0->PD & DEV_IICn_PD_BYTE_END) //一个字节结束
        {
            DEV_IIC0->PD = DEV_IICn_PD_BYTE_END;

            if (DEV_IIC0->STA & DEV_IICn_STA_RW_FLAG_SWR_MRD)//主机读命令
            {
                //debug("1\r\n");
                flag_write_read = 1;
                hal_iic_callback(iic_buff, 0, I2C_READ); //主机向从机写读命令
                DEV_IIC0->CTL = DEV_IICn_CTL_CMD_RELEASEBUS
                                | DEV_IICn_CTL_TX_ACK_ACK
                                | iic_buff[0];
            }
            else //主机写命令
            {
                DEV_IIC0->CTL = DEV_IICn_CTL_CMD_RELEASEBUS
                                | DEV_IICn_CTL_TX_ACK_ACK
                                | DEV_IICn_CTL_TX_DAT_MASK;
                brom_memset(iic_buff, 0, 10); //接受到设备地址，清除数据buff
                rx_cnt = 0;
                //debug("2,%x\r\n", DEV_IIC0->RX_DAT); //设备地址
            }
        }
        else
        {
            brom_memset(iic_buff, 0, 10);
            rx_cnt = 0;
        }
    }

    if (DEV_IIC0->PD & DEV_IICn_PD_BYTE_END) //一个byte 结束
    {
        DEV_IIC0->PD = DEV_IICn_PD_BYTE_END;

        if (DEV_IIC0->STA & DEV_IICn_STA_RW_FLAG_SWR_MRD) //主机读命令
        {
            //debug("3\r\n");
            DEV_IIC0->CTL = DEV_IICn_CTL_CMD_RELEASEBUS
                            | DEV_IICn_CTL_TX_ACK_ACK
                            | 0x55;//发出data
        }
        else//主机写命令
        {
            DEV_IIC0->CTL = DEV_IICn_CTL_CMD_RELEASEBUS
                            | DEV_IICn_CTL_TX_ACK_ACK
                            | DEV_IICn_CTL_TX_DAT_MASK;
            iic_buff[rx_cnt] = DEV_IIC0->RX_DAT;
            //debug("4:%x\r\n", iic_buff[rx_cnt]);
            rx_cnt ++;
        }
    }

    if (DEV_IIC0->PD & DEV_IICn_PD_STOP_DET) //iic 停止bit中断
    {
        DEV_IIC0->PD = DEV_IICn_PD_STOP_DET;

        if (!flag_write_read)
        {
            hal_iic_callback(iic_buff, rx_cnt, I2C_WRITE); //写数据完成的回调函数
        }

        brom_memset(iic_buff, 0, 10);
        rx_cnt = 0;
        flag_write_read = 0;
        //debug("5\r\n");
    }

#endif
}

/**
* @brief        i2c1_irq_handler
* @details      None
* @param[in]    NULL
* @return         NULL
* @note         None
*/

void i2c1_irq_handler()
{
#ifdef BSP_USING_I2C1_SLAVE
    static uint8_t i2c1_irq_num_test = 0;
    i2c1_irq_num_test++;
    HAL_I2C_LOG("i2c1_irq_num_test:%d,i2c1_irq_handler\n", i2c1_irq_num_test);

    if (DEV_IIC1->PD & DEV_IICn_PD_BUS_ERR)
    {
        HAL_I2C_LOG("i2c1_irq_num_test:%d,DEV_IICn_PD_BUS_ERR\n", i2c1_irq_num_test);
        DEV_IIC1->PD = DEV_IICn_PD_BUS_ERR;
    }

    if (DEV_IIC1->PD & DEV_IICn_PD_NACK_DET)
    {
        HAL_I2C_LOG("i2c1_irq_num_test:%d,DEV_IICn_PD_NACK_DET\n", i2c1_irq_num_test);
        DEV_IIC1->PD = DEV_IICn_PD_NACK_DET;
    }

    if (DEV_IIC1->PD & DEV_IICn_PD_START_DET)
    {
        HAL_I2C_LOG("i2c1_irq_num_test:%d,DEV_IICn_PD_START_DET\n", i2c1_irq_num_test);
        DEV_IIC1->PD = DEV_IICn_PD_START_DET;

        if (DEV_IIC1->PD & DEV_IICn_PD_BYTE_END)
        {
            HAL_I2C_LOG("i2c1_irq_num_test:%d,DEV_IICn_PD_BYTE_END\n", i2c1_irq_num_test);
            DEV_IIC1->PD = DEV_IICn_PD_BYTE_END;

            //读写标志
            if (DEV_IIC1->STA & DEV_IICn_STA_RW_FLAG_SWR_MRD)
            {
                //IIC_slave Write
                i2c1_slave_msg_tx.busy = 1;
                i2c1_slave_msg_tx.cur_cnt = 0;

                if (i2c1_slave_msg_tx.len == 0)
                {
                    //no send task, send data 0x00
                    DEV_IIC1->CTL = DEV_IICn_CTL_CMD_RELEASEBUS
                                    | DEV_IICn_CTL_TX_ACK_ACK
                                    | 0x00;
                }
                else
                {
                    //send the first byte of data
                    DEV_IIC1->CTL = DEV_IICn_CTL_CMD_RELEASEBUS
                                    | DEV_IICn_CTL_TX_ACK_ACK
                                    | i2c1_slave_msg_tx.buf[i2c1_slave_msg_tx.cur_cnt];
                    i2c1_slave_msg_tx.cur_cnt++;
                }
            }
            else
            {
                //IIC_slave Read
                i2c1_slave_msg_rx.busy = 1;
                i2c1_slave_msg_rx.cur_cnt = 0;
                DEV_IIC1->CTL = DEV_IICn_CTL_CMD_RELEASEBUS
                                | DEV_IICn_CTL_TX_ACK_ACK
                                | DEV_IICn_CTL_TX_DAT_MASK;
                //address is received as data, not assigned to the buf
            }
        }
    }

    if (DEV_IIC1->PD & DEV_IICn_PD_BYTE_END)
    {
        HAL_I2C_LOG("i2c1_irq_num_test:%d,DEV_IICn_PD_BYTE_END\n", i2c1_irq_num_test);
        DEV_IIC1->PD = DEV_IICn_PD_BYTE_END;

        if (DEV_IIC1->STA & DEV_IICn_STA_RW_FLAG_SWR_MRD)
        {
            //IIC_slave Write
            if ((i2c1_slave_msg_tx.cur_cnt + 1) > i2c1_slave_msg_tx.len || (i2c1_slave_msg_tx.cur_cnt + 1) > I2C1_SLAVE_MSG_LEN)
            {
                //no send task or beyond the buf length, send data 0x00
                DEV_IIC1->CTL = DEV_IICn_CTL_CMD_RELEASEBUS
                                | DEV_IICn_CTL_TX_ACK_ACK
                                | 0x00;
            }
            else
            {
                DEV_IIC1->CTL = DEV_IICn_CTL_CMD_RELEASEBUS
                                | DEV_IICn_CTL_TX_ACK_ACK
                                | i2c1_slave_msg_tx.buf[i2c1_slave_msg_tx.cur_cnt];
                i2c1_slave_msg_tx.cur_cnt++;
            }
        }
        else
        {
            //IIC_slave Read
            DEV_IIC1->CTL = DEV_IICn_CTL_CMD_RELEASEBUS
                            | DEV_IICn_CTL_TX_ACK_ACK
                            | DEV_IICn_CTL_TX_DAT_MASK;

            if ((i2c1_slave_msg_rx.cur_cnt + 1) <= I2C1_SLAVE_MSG_LEN)
            {
                i2c1_slave_msg_rx.buf[i2c1_slave_msg_rx.cur_cnt] = DEV_IIC1->RX_DAT & DEV_IICn_RX_DAT_MASK;
                i2c1_slave_msg_rx.cur_cnt++;
            }
        }
    }

    if (DEV_IIC1->PD & DEV_IICn_PD_STOP_DET)
    {
        HAL_I2C_LOG("i2c1_irq_num_test:%d,DEV_IICn_PD_STOP_DET\n", i2c1_irq_num_test);
        DEV_IIC1->PD = DEV_IICn_PD_STOP_DET;

        if (i2c1_slave_msg_tx.busy == 1)
        {
            i2c1_slave_msg_tx.busy = 0;
            i2c1_slave_msg_tx.len = 0;
        }

        if (i2c1_slave_msg_rx.busy == 1)
        {
            i2c1_slave_msg_rx.busy = 0;
            i2c1_slave_msg_rx.len = i2c1_slave_msg_rx.cur_cnt;
        }
    }

#endif
}
//---------------------------------------------------I2C Slave---------------------end--------------


