#include "dev_at24cxx.h"
#include <stdint.h>

/*----------------------------------------
* @函数名:dev_at24cxx_get_i2c1_time_limit
* @描述: 获取i2c超时值获取-时间大约值不一定准确
* @原理: 1、是一般i2c最迟响应时间在10ms内。
*           2、一个while(--i)语句时间大约是0.3us。
*           在使用过程中先获取此值，然后直接用while(--i),就是i*0.3 us了。
* @入参: None
* @出参: uint32_t
* @返回值: 超时值(us)
* @调用:
* @被调用:
----------------------------------------
* 作者     创建时间          操作
 樊春春   2023/11/19    Create/Modify
----------------------------------------*/
static uint32_t dev_at24cxx_get_i2c1_time_limit(void)
{
    RCC_ClocksTypeDef RCC_Clocks;
    RCC_GetClocksFreq(&RCC_Clocks);
    return RCC_Clocks.SYSCLK_Frequency / 10000; // 168000000/10000=16800 5.40ms
}

/*----------------------------------------
* @函数名: dev_at24cxx_read_one_byte
* @描述: 利用硬件i2c1读取目标寄存器数据
* @入参: 两个参数：寄存器地址，寄存器地址是否是16位
*       @arg1:目标设备地址(写地址就好了)
*       @arg2:目标8位寄存器地址
*       @arg3:寄存器地址是否是16位的
*       @arg4:读取结果指针()
* @出参: int32_t
* @返回值:  >0 成功
*         <0 失败
*           -1 i2c busy
*           -2 i2c send start fail
*           -3 i2c send address failed
*           -4 i2c send high regAdder failed
*           -5 i2c send low regAdder failed
*           -6 i2c reSend start fail
*           -7 i2c reSend address failed
*           -8 i2c no received
* @调用:
* @被调用:
----------------------------------------
* 作者     创建时间          操作
 樊春春   2023/11/19    Create/Modify
----------------------------------------*/
int32_t dev_at24cxx_read_one_byte(uint8_t devAdder, uint16_t regAdder, bool is16BitRegAdder, uint8_t *num)
{
    uint32_t timeLimit = dev_at24cxx_get_i2c1_time_limit();
    uint32_t tmp       = timeLimit;

    /*第一步：先将读指针移到指定的地址寄存器上*/
    //--判断当前i2c是否忙
    while ((--tmp) && (I2C_GetFlagStatus(I2C1_NAME, I2C_FLAG_BUSY)))
        ;
    if (tmp == 0)
        // i2c busy
        return -1;

    //--生成起始位(SB未清零-I2C_CheckEvent读了SR1，在后续发送地址时I2C_Send7bitAddress写了DR后清除SB位)
    I2C_GenerateSTART(I2C1_NAME, ENABLE); // 发送起始位后，自动转换为主设备
    tmp = timeLimit;
    while ((--tmp) && (!I2C_CheckEvent(I2C1_NAME, I2C_EVENT_MASTER_MODE_SELECT)))
        ; // EV5事件
    if (tmp == 0)
        return -2; // i2c send start fail

    //--发送7位设备地址
    I2C_Send7bitAddress(I2C1_NAME, devAdder, I2C_Direction_Transmitter); // 七位地址，非十位地址
    tmp = timeLimit;
    while ((--tmp) && (!I2C_CheckEvent(I2C1_NAME, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)))
        ;
    if (tmp == 0)
        return -3; // i2c send address failed
    // 清零事件EV6 ADDR位(先读SR1再读SR2)
    (void)(I2C1_NAME->SR1);
    (void)(I2C1_NAME->SR2); // 清除EV6事件

    //--发送要写入的目标寄存器
    if (is16BitRegAdder)
    {
        I2C_SendData(I2C1_NAME, regAdder >> 8); // 发送高8位地址
        tmp = timeLimit;
        while ((--tmp) && (!I2C_CheckEvent(I2C1_NAME, I2C_EVENT_MASTER_BYTE_TRANSMITTING)))
            ;
        if (tmp == 0)
            return -4; // i2c high regAdder failed
    }
    I2C_SendData(I2C1_NAME, regAdder % 256); // 发送低8位地址
    tmp = timeLimit;
    while ((--tmp) && (!I2C_CheckEvent(I2C1_NAME, I2C_EVENT_MASTER_BYTE_TRANSMITTING)))
        ;
    if (tmp == 0)
        return -5; // i2c send low regAdder failed

    /*第二步：开始读取*/
    //--再次生成起始位
    I2C_GenerateSTART(I2C1_NAME, ENABLE); // 发送起始位后，自动转换为主设备
    tmp = timeLimit;
    while ((--tmp) && (!I2C_CheckEvent(I2C1_NAME, I2C_EVENT_MASTER_MODE_SELECT)))
        ;
    if (tmp == 0)
        return -6; // i2c reSend start fail

    //--再次发送7位设备地址(接收/读取模式).调用I2C_CheckEvent会清除EV6事件(先读SR1再读SR2)
    I2C_Send7bitAddress(I2C1_NAME, devAdder, I2C_Direction_Receiver); // 七位地址，非十位地址。设置接收时会默认地址最后一位取反即为1
    tmp = timeLimit;
    while ((--tmp) && (!I2C_CheckEvent(I2C1_NAME, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED)))
        ; // EV6事件
    if (tmp == 0)
        return -7; // i2c reSend address failed

    //--准备接收数据
    I2C_AcknowledgeConfig(I2C1_NAME, DISABLE); // 因为只接收一个字节数据，所以不需要响应
    I2C_GenerateSTOP(I2C1_NAME, ENABLE);       // 将在接收后产生停止信号-在此书写原因在手册
    tmp = timeLimit;
    while ((--tmp) && (!I2C_CheckEvent(I2C1_NAME, I2C_EVENT_MASTER_BYTE_RECEIVED)))
        ; // EV7事件
    if (tmp == 0)
        return -8; // i2c no received

    //--接收数据
    *num = I2C_ReceiveData(I2C1_NAME); // 保存数据

    //--恢复响应
    I2C_AcknowledgeConfig(I2C1_NAME, ENABLE);

    return 1;
}

/**
 * @brief: 利用硬件i2c1读取目标寄存器开始以后的两个数据
 * @args:两个参数：寄存器地址，寄存器地址是否是16位
 *       @arg1:目标设备地址(写地址就好了)
 *       @arg2:目标8位寄存器地址
 *       @arg3:寄存器地址是否是16位的
 *       @arg4:读取结果指针
 *       @arg5:是否允许跨页
 * @return:
 *         >0 成功(成功读取的字节数)
 *         <=0 失败
 *           -1 i2c busy
 *           -2 i2c send start fail
 *           -3 i2c send address failed
 *           -4 i2c send high regAdder failed
 *           -5 i2c send low regAdder failed
 *           -6 i2c reSend start fail
 *           -7 i2c reSend address failed
 *           -8 i2c no received
 */
int32_t dev_at24cxx_read_two_bytes(uint8_t devAdder, uint16_t startRegAdder, bool is16BitRegAdder, uint8_t *buf, bool isAllowOverPage)
{
    uint32_t timeLimit = dev_at24cxx_get_i2c1_time_limit();
    uint32_t tmp       = timeLimit;

#if I2C1_DEVICE_IS_EEPROM
    // 跨页问题
    uint16_t pageRemain = 0;
    uint16_t newAdder   = 0;
    if (getI2C1DeviceCurrentPageRemain(startRegAdder, &pageRemain) < 0)
    {
        return 0;
    }
    if (pageRemain < 2)
    {
        // 需要跨页
        if (dev_at24cxx_read_one_byte(devAdder, startRegAdder, true, &buf[0]) < 0) // 读取第一个数据
        {
            return 0;
        }
        if (!isAllowOverPage)
        {
            // 不允许，直接退出，返回已经读取的一个数量
            return 1; // 只存在一个数据
        }
        if (getI2C1DeviceNewPage(startRegAdder, &newAdder) < 0) // 移动到下一页
        {
            return 1; // 只存在一个数据
        }
        if (dev_at24cxx_read_one_byte(devAdder, newAdder, true, &buf[1]) < 0) // 读取第二个数据
        {
            return 0; // 只存在一个数据
        }
        return 2;
    }
#endif

    if (buf == NULL)
    {
        return 0;
    }

    /*第一步：先将读指针移到指定的地址寄存器上*/
    //--判断当前i2c是否忙
    while ((--tmp) && (I2C_GetFlagStatus(I2C1_NAME, I2C_FLAG_BUSY)))
        ;
    if (tmp == 0)
        return -1; // i2c busy

    //--生成起始位(SB未清零-I2C_CheckEvent读了SR1，在后续发送地址时I2C_Send7bitAddress写了DR后清除SB位)
    I2C_GenerateSTART(I2C1_NAME, ENABLE); // 发送起始位后，自动转换为主设备
    tmp = timeLimit;
    while ((--tmp) && (!I2C_CheckEvent(I2C1_NAME, I2C_EVENT_MASTER_MODE_SELECT)))
        ; // EV5事件
    if (tmp == 0)
        return -2; // i2c send start fail

    //--发送7位设备地址
    I2C_Send7bitAddress(I2C1_NAME, devAdder, I2C_Direction_Transmitter); // 七位地址，非十位地址
    tmp = timeLimit;
    while ((--tmp) && (!I2C_CheckEvent(I2C1_NAME, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)))
        ;
    if (tmp == 0)
        return -3; // i2c send address failed
    // 清零事件EV6 ADDR位(先读SR1再读SR2)
    (void)(I2C1_NAME->SR1);
    (void)(I2C1_NAME->SR2); // 清除EV6事件

    //--发送要写入的目标寄存器
    if (is16BitRegAdder)
    {
        I2C_SendData(I2C1_NAME, startRegAdder >> 8); // 发送高8位地址
        tmp = timeLimit;
        while ((--tmp) && (!I2C_CheckEvent(I2C1_NAME, I2C_EVENT_MASTER_BYTE_TRANSMITTING)))
            ;
        if (tmp == 0)
            return -4; // i2c high regAdder failed
    }
    I2C_SendData(I2C1_NAME, startRegAdder % 256); // 发送低8位地址
    tmp = timeLimit;
    while ((--tmp) && (!I2C_CheckEvent(I2C1_NAME, I2C_EVENT_MASTER_BYTE_TRANSMITTING)))
        ;
    if (tmp == 0)
        return -5; // i2c send low regAdder failed

    /*第二步：开始读取*/
    //--再次生成起始位
    I2C_GenerateSTART(I2C1_NAME, ENABLE); // 发送起始位后，自动转换为主设备
    tmp = timeLimit;
    while ((--tmp) && (!I2C_CheckEvent(I2C1_NAME, I2C_EVENT_MASTER_MODE_SELECT)))
        ;
    if (tmp == 0)
        return -6; // i2c reSend start fail

    //--再次发送7位设备地址(接收/读取模式).调用I2C_CheckEvent会清除EV6事件(先读SR1再读SR2)
    I2C_Send7bitAddress(I2C1_NAME, devAdder, I2C_Direction_Receiver); // 七位地址，非十位地址。设置接收时会默认地址最后一位取反即为1
    tmp = timeLimit;
    while ((--tmp) && (!I2C_CheckEvent(I2C1_NAME, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED)))
        ; // EV6事件
    if (tmp == 0)
        return -7; // i2c reSend address failed

    //--准备接收数据
    I2C_NACKPositionConfig(I2C1_NAME, I2C_NACKPosition_Next); // POS位置位，在接收的下一个字节产生NACK
    tmp = timeLimit;
    while ((--tmp) && (!I2C_GetFlagStatus(I2C1_NAME, I2C_FLAG_BTF)))
        ; // 等待BTF置位
    if (tmp == 0)
        return -8; // i2c no received

    //--发送结束信号
    I2C_GenerateSTOP(I2C1_NAME, ENABLE);

    //--接收两个字节数据.读取第一个数据后第二个数据将会从移位寄存器转到DR中
    buf[0] = (uint8_t)I2C_ReceiveData(I2C1_NAME); // 保存第一个字节
    tmp    = timeLimit;                           // 给移位寄存器转到DR中时间，相当于nop
    buf[1] = (uint8_t)I2C_ReceiveData(I2C1_NAME); // 保存第二个字节

    return 2; // 成功读取两个字节
}

/**
 * @brief: 利用硬件i2c1读取从目标寄存器开始的bufsize个数据
 * @args:四个参数：寄存器起始地址，寄存器地址是否是16位，保存数据的buf，保存数据数量
 *       @arg1:目标设备地址(写地址就好了)
 *       @arg2:目标8位寄存器地址
 *       @arg3:寄存器地址是否是16位的
 *       @arg4:读取结果指针
 *       @arg5:要读取的大小，调用此函数最小读取为3个字节
 * @return:
 *         >0 成功 表示已经接收的字节数量
 *         <0 失败
 *           -1 i2c busy
 *           -2 i2c send start fail
 *           -3 i2c send address failed
 *           -4 i2c send high regAdder failed
 *           -5 i2c send low regAdder failed
 *           -6 i2c reSend start fail
 *           -7 i2c reSend address failed
 */
// static
int32_t dev_at24cxx_read_more_bytes(uint8_t devAdder, uint16_t startRegAdder, bool is16BitRegAdder, uint8_t *buf, uint8_t bufSize)
{
    uint32_t timeLimit = dev_at24cxx_get_i2c1_time_limit();
    uint32_t tmp       = timeLimit;
    uint32_t index     = 0;

    if (bufSize < 3)
    {
        return 0;
    }

    /*第一步：先将读指针移到指定的地址寄存器上*/
    //--判断当前i2c是否忙
    while ((--tmp) && (I2C_GetFlagStatus(I2C1_NAME, I2C_FLAG_BUSY)))
        ;
    if (tmp == 0)
        return -1; // i2c busy

    //--生成起始位(SB未清零-I2C_CheckEvent读了SR1，在后续发送地址时I2C_Send7bitAddress写了DR后清除SB位)
    I2C_GenerateSTART(I2C1_NAME, ENABLE); // 发送起始位后，自动转换为主设备
    tmp = timeLimit;
    while ((--tmp) && (!I2C_CheckEvent(I2C1_NAME, I2C_EVENT_MASTER_MODE_SELECT)))
        ; // EV5事件
    if (tmp == 0)
        return -2; // i2c send start fail

    //--发送7位设备地址
    I2C_Send7bitAddress(I2C1_NAME, devAdder, I2C_Direction_Transmitter); // 七位地址，非十位地址
    tmp = timeLimit;
    while ((--tmp) && (!I2C_CheckEvent(I2C1_NAME, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)))
        ;
    if (tmp == 0)
        return -3; // i2c send address failed
    // 清零事件EV6 ADDR位(先读SR1再读SR2)
    (void)(I2C1_NAME->SR1);
    (void)(I2C1_NAME->SR2); // 清除EV6事件

    //--发送要写入的目标寄存器
    if (is16BitRegAdder)
    {
        I2C_SendData(I2C1_NAME, startRegAdder >> 8); // 发送高8位地址
        tmp = timeLimit;
        while ((--tmp) && (!I2C_CheckEvent(I2C1_NAME, I2C_EVENT_MASTER_BYTE_TRANSMITTING)))
            ;
        if (tmp == 0)
            return -4; // i2c high regAdder failed
    }
    I2C_SendData(I2C1_NAME, startRegAdder % 256); // 发送低8位地址
    tmp = timeLimit;
    while ((--tmp) && (!I2C_CheckEvent(I2C1_NAME, I2C_EVENT_MASTER_BYTE_TRANSMITTING)))
        ;
    if (tmp == 0)
        return -5; // i2c send low regAdder failed

    /*第二步：开始读取*/
    //--再次生成起始位
    I2C_GenerateSTART(I2C1_NAME, ENABLE); // 发送起始位后，自动转换为主设备
    tmp = timeLimit;
    while ((--tmp) && (!I2C_CheckEvent(I2C1_NAME, I2C_EVENT_MASTER_MODE_SELECT)))
        ;
    if (tmp == 0)
        return -6; // i2c reSend start fail

    //--再次发送7位设备地址(接收/读取模式).调用I2C_CheckEvent会清除EV6事件(先读SR1再读SR2)
    I2C_Send7bitAddress(I2C1_NAME, devAdder, I2C_Direction_Receiver); // 七位地址，非十位地址。设置接收时会默认地址最后一位取反即为1
    tmp = timeLimit;
    while ((--tmp) && (!I2C_CheckEvent(I2C1_NAME, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED)))
        ; // EV6事件
    if (tmp == 0)
        return -7; // i2c reSend address failed

    //--开始接收数据
    while (index < bufSize)
    {
        if (index == bufSize - 3)
        {
            // 已经是倒数第三个了
            tmp = timeLimit;
            while ((--tmp) && (!I2C_GetFlagStatus(I2C1_NAME, I2C_FLAG_BTF)))
                ; // step1等待BTF置位(读DR复位)
            if (tmp == 0)
                return index;                          // 返回已经接收的字节数
            I2C_AcknowledgeConfig(I2C1_NAME, DISABLE); // step2复位ACK
            buf[index] = I2C_ReceiveData(I2C1_NAME);   // step3读取n-2数据
            index++;
            tmp = timeLimit;
            while ((--tmp) && (!I2C_GetFlagStatus(I2C1_NAME, I2C_FLAG_BTF)))
                ; // step4再次等待BTF置位(读DR复位)
            if (tmp == 0)
                return index;                          // 返回已经接收的字节数
            I2C_GenerateSTOP(I2C1_NAME, ENABLE);       // step5生成停止位
            buf[index++] = I2C_ReceiveData(I2C1_NAME); // step6读取第n-1数据
            tmp          = timeLimit;                  // 此操作就是为了等待移位寄存器中的数据移入DR，相当于一个nop
            buf[index++] = I2C_ReceiveData(I2C1_NAME); // step7读取第n数据

            // 接收完成
            I2C_AcknowledgeConfig(I2C1_NAME, ENABLE); // 恢复响应
            return index;                             // 返回已经接收数量
        }
        tmp = timeLimit;
        while ((--tmp) && (!I2C_CheckEvent(I2C1_NAME, I2C_EVENT_MASTER_BYTE_RECEIVED)))
            ; // EV7事件
        if (tmp == 0)
            return index; // 返回已经接收的字节数
        buf[index] = I2C_ReceiveData(I2C1_NAME);
        index++; // 接收下一字节
    }
    return 0;
}

/**
 * @brief: 利用硬件i2c1向目标寄存器写入一个数据
 * @args:三个参数：寄存器地址，寄存器地址是否是16位，需要写入的数据
 *       @arg1:目标设备地址(写地址就好了)
 *       @arg2:目标寄存器地址
 *       @arg3:寄存器地址是否是16位的
 *       @arg4:一个字节数据
 * @return:
 *         >0 成功
 *         <0 失败
 *           -1 i2c busy
 *           -2 i2c send start fail
 *           -3 i2c send address failed
 *           -4 i2c high regAdder failed
 *           -5 i2c send low regAdder failed
 *           -6 i2c send data failed
 */
int32_t dev_at24cxx_write_one_byte(uint8_t devAdder, uint16_t regAdder, bool is16BitRegAdder, uint8_t num)
{
    uint32_t timeLimit = dev_at24cxx_get_i2c1_time_limit();
    uint32_t tmp       = timeLimit;

    //--判断当前i2c是否忙
    while ((--tmp) && (I2C_GetFlagStatus(I2C1_NAME, I2C_FLAG_BUSY)))
        ;
    if (tmp == 0)
        return -1; // i2c busy

    //--生成起始位(SB未清零-I2C_CheckEvent读了SR1，在后续发送地址时I2C_Send7bitAddress写了DR后清除SB位)
    I2C_GenerateSTART(I2C1_NAME, ENABLE); // 发送起始位后，自动转换为主设备
    tmp = timeLimit;
    while ((--tmp) && (!I2C_CheckEvent(I2C1_NAME, I2C_EVENT_MASTER_MODE_SELECT)))
        ; // EV5事件
    if (tmp == 0)
        return -2; // i2c send start fail

    //--发送7位设备地址.调用I2C_CheckEvent会清除EV6事件(先读SR1再读SR2)
    I2C_Send7bitAddress(I2C1_NAME, devAdder, I2C_Direction_Transmitter); // 七位地址，非十位地址
    tmp = timeLimit;
    while ((--tmp) && (!I2C_CheckEvent(I2C1_NAME, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)))
        ; // EV6事件
    if (tmp == 0)
        return -3; // i2c send address failed

    //--发送要写入的目标寄存器
    if (is16BitRegAdder)
    {
        I2C_SendData(I2C1_NAME, regAdder >> 8); // 发送高8位地址
        tmp = timeLimit;
        while ((--tmp) && (!I2C_CheckEvent(I2C1_NAME, I2C_EVENT_MASTER_BYTE_TRANSMITTING)))
            ; // EV8事件-写DR清除
        if (tmp == 0)
            return -4; // i2c high regAdder failed
    }
    I2C_SendData(I2C1_NAME, regAdder % 256); // 发送低8位地址
    tmp = timeLimit;
    while ((--tmp) && (!I2C_CheckEvent(I2C1_NAME, I2C_EVENT_MASTER_BYTE_TRANSMITTING)))
        ; // EV8事件-写DR清除
    if (tmp == 0)
        return -5; // i2c send low regAdder failed

    //--发送数据
    I2C_SendData(I2C1_NAME, num);
    tmp = timeLimit;
    while ((--tmp) && (!I2C_CheckEvent(I2C1_NAME, I2C_EVENT_MASTER_BYTE_TRANSMITTED)))
        ; // EV8_2事件
    if (tmp == 0)
        return -6; // i2c send data failed

    //--发送结束信号
    I2C_GenerateSTOP(I2C1_NAME, ENABLE);

    return 1;
}

/***@brief : 利用硬件i2c1向目标起始寄存器连续写入多个数据
                *@args : 5个参数：开始寄存器地址，寄存器地址是否是16位，需要写入的数据数组，数据数组大小，是否允许跨页(如果不是eerpom不用管) *
        @arg1 : 目标设备地址(写地址就好了) * @arg2 : 目标寄存器地址 *@arg3 : 寄存器地址是否是16位的 *@arg4 : 一个要写入数据的数组 *@arg5 : 写入数据长度 *@ return : * >
    0 成功发送的字节数
        * <= 0 失败
                 * 0 buf大小为0
                 * -1 i2c busy
                 * -2 i2c send start fail
                 * -3 i2c send address failed
                 * -4 i2c high regAdder failed
                 * -5 i2c send low regAdder failed */
// static
int32_t dev_at24cxx_write_more_bytes(uint8_t devAdder, uint16_t startRegAdder, bool is16BitRegAdder, uint8_t *buf, uint8_t bufSize)
{
    uint32_t timeLimit = dev_at24cxx_get_i2c1_time_limit();
    uint32_t tmp       = timeLimit;
    uint32_t index     = 0;

    if (bufSize <= 0)
    {
        return 0;
    }

    //--判断当前i2c是否忙
    while ((--tmp) && (I2C_GetFlagStatus(I2C1_NAME, I2C_FLAG_BUSY)))
        ;
    if (tmp == 0)
        return -1; // i2c busy

    //--生成起始位(SB未清零-I2C_CheckEvent读了SR1，在后续发送地址时I2C_Send7bitAddress写了DR后清除SB位)
    I2C_GenerateSTART(I2C1_NAME, ENABLE); // 发送起始位后，自动转换为主设备
    tmp = timeLimit;
    while ((--tmp) && (!I2C_CheckEvent(I2C1_NAME, I2C_EVENT_MASTER_MODE_SELECT)))
        ; // EV5事件
    if (tmp == 0)
        return -2; // i2c send start fail

    //--发送7位设备地址.调用I2C_CheckEvent会清除EV6事件(先读SR1再读SR2)
    I2C_Send7bitAddress(I2C1_NAME, devAdder, I2C_Direction_Transmitter); // 七位地址，非十位地址
    tmp = timeLimit;
    while ((--tmp) && (!I2C_CheckEvent(I2C1_NAME, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)))
        ; // EV6事件
    if (tmp == 0)
        return -3; // i2c send address failed

    //--发送要写入的目标寄存器
    if (is16BitRegAdder)
    {
        I2C_SendData(I2C1_NAME, startRegAdder >> 8); // 发送高8位地址
        tmp = timeLimit;
        while ((--tmp) && (!I2C_CheckEvent(I2C1_NAME, I2C_EVENT_MASTER_BYTE_TRANSMITTING)))
            ; // EV8事件-写DR清除
        if (tmp == 0)
            return -4; // i2c high regAdder failed
    }
    I2C_SendData(I2C1_NAME, startRegAdder % 256); // 发送低8位地址
    tmp = timeLimit;
    while ((--tmp) && (!I2C_CheckEvent(I2C1_NAME, I2C_EVENT_MASTER_BYTE_TRANSMITTING)))
        ; // EV8事件-写DR清除
    if (tmp == 0)
        return -5; // i2c send low regAdder failed

    //--发送数据
    while (index < bufSize)
    {
        if (index == (bufSize - 1))
        {
            // 已经是最后一个字节了，在写入DR后发送停止位了
            I2C_SendData(I2C1_NAME, buf[index]);
            tmp = timeLimit;
            while ((--tmp) && (!I2C_CheckEvent(I2C1_NAME, I2C_EVENT_MASTER_BYTE_TRANSMITTED)))
                ; // EV8_2事件
            I2C_GenerateSTOP(I2C1_NAME, ENABLE);
            if (tmp == 0)
                return index; // 返回已发送的字节数量
        }
        else
        {
            I2C_SendData(I2C1_NAME, buf[index]);
            tmp = timeLimit;
            while ((--tmp) && (!I2C_CheckEvent(I2C1_NAME, I2C_EVENT_MASTER_BYTE_TRANSMITTING)))
                ; // EV8事件
            if (tmp == 0)
                return index; // 返回已发送的字节数量
        }
        index++;
    }
    return index;
}

int32_t dev_at24cxx_read_bytes(uint8_t addr, uint8_t *buf, uint8_t size)
{
    if (1 == size)
    {
        return dev_at24cxx_read_one_byte(I2C1_ADDRESS, addr, 1, buf);
    }
    else if (2 == size)
    {
        return dev_at24cxx_read_two_bytes(I2C1_ADDRESS, addr, 1, buf, 1);
    }
    else
    {
        return dev_at24cxx_read_more_bytes(I2C1_ADDRESS, addr, 1, buf, size);
    }
}

int32_t dev_at24cxx_write_bytes(uint8_t addr, uint8_t *buf, uint8_t size)
{
    if (1 == size)
    {
        return dev_at24cxx_write_one_byte(I2C1_ADDRESS, addr, 1, *buf);
    }
    else
    {
        return dev_at24cxx_write_more_bytes(I2C1_ADDRESS, addr, 1, buf, size);
    }
}
