
#include "../include/hal_lksmcu_reg.h"
#include "../include/hal_lksmcu_i2c.h"
#include "hal_lks32mc09x.h"
/**
 * @brief 复位I2C模块
 * @param i2c I2C模块编号
 */
void HAL_I2C_Reset(HAL_I2C_x i2c)
{
    HAL_REG_SYS_UNLOCK();
    HAL_REG_SET(SYS_SFT_RST, BIT0);
    HAL_REG_RESET(SYS_SFT_RST, BIT0);
    HAL_REG_SYS_LOCK();
}

/**
 * @brief 打开I2C模块
 * @param i2c I2C模块编号
 */
void HAL_I2C_Enable(HAL_I2C_x i2c)
{
    HAL_REG_SYS_UNLOCK();
    HAL_REG_SET(SYS_CLK_FEN, BIT0);
    HAL_REG_SYS_LOCK();
}

/**
 * @brief 关闭I2C模块
 * @param i2c I2C模块编号
 */
void HAL_I2C_Disable(HAL_I2C_x i2c)
{
    HAL_REG_SYS_UNLOCK();
    HAL_REG_RESET(SYS_CLK_FEN, BIT0);
    HAL_REG_SYS_LOCK();
}
/**
 * @brief 设置I2C模块波特率
 * @param i2c I2C模块编号
 * @param baud 波特率
 */
void HAL_I2C_SetBaud(HAL_I2C_x i2c, uint32_t baud)
{
    u32 BaudRate;
    BaudRate = ((u32)HAL_CLK_GetMcuFreq() + ((baud * 17) >> 1)) / (baud * 17) - 1;
    HAL_REG_SYS_UNLOCK();
    HAL_REG_WRITE(SYS_CLK_DIV0, BaudRate);
    HAL_REG_SYS_LOCK();
}

/**
 * @brief 发送数据到I2C设备
 * @param i2c I2C模块编号
 * @param addr 设备地址
 * @param data 数据缓冲区
 * @param len 数据长度
 * @return 0:成功 非0:失败
 */
uint8_t HAL_I2C_TxData(HAL_I2C_x i2c, uint8_t addr, uint8_t *data, uint32_t len)
{
    uint32_t i = 0;
    if (HAL_I2C[i2c]->MSCR & BIT3)
    {
        return 1; // 发送数据时，i2c总线忙碌
    }
    if (len == 0)
    {
        return 1; // 不支持仅发送一个地址
    }
    HAL_I2C[i2c]->SCR  = 0;
    HAL_I2C[i2c]->MSCR = 1; // 触发I2C发送数据
    while ((HAL_I2C[i2c]->MSCR & BIT2) == 0)
    {
    }
    HAL_I2C[i2c]->DATA = addr;
    while (HAL_I2C[i2c]->SCR == 0) // 等待地址发送完成
    {
    }

    if (HAL_I2C[i2c]->SCR & BIT1) // 收到nack
    {
        HAL_I2C[i2c]->SCR = 0;
        while (HAL_I2C[i2c]->MSCR & BIT3) // 等待stop信号发送完成
        {
        }
        return 1;
    }
    for (i = 0; i < len; i++)
    {
        HAL_I2C[i2c]->DATA = data[i];
        HAL_I2C[i2c]->SCR  = BIT2;              // 触发发送
        while ((HAL_I2C[i2c]->SCR & BIT0) == 0) // 等待数据发送完成
        {
        }
        if (HAL_I2C[i2c]->SCR & BIT1) // 收到nack
        {
            HAL_I2C[i2c]->SCR = 0;
            while (HAL_I2C[i2c]->MSCR & BIT3) // 等待stop信号发送完成
            {
            }
            return 1;
        }
    }
    HAL_I2C[i2c]->SCR = 0;
    while (HAL_I2C[i2c]->MSCR & BIT3) // 等待stop信号发送完成
    {
    }
    return 0;
}

/**
 * @brief 从I2C设备接收数据
 * @param i2c I2C模块编号
 * @param addr 设备地址
 * @param data 数据缓冲区
 * @param len 数据长度
 * @return 0:成功 非0:失败
 */
uint8_t HAL_I2C_RxData(HAL_I2C_x i2c, uint8_t addr, uint8_t *data, uint32_t len)
{
    uint32_t i;
    if (HAL_I2C[i2c]->MSCR & BIT3)
    {
        return 1; // 发送数据时，i2c总线忙碌
    }
    if (len == 0)
    {
        return 1; // 不支持仅发送一个地址
    }
    HAL_I2C[i2c]->SCR  = 0;
    HAL_I2C[i2c]->MSCR = 1;                  // 触发I2C发送数据
    while ((HAL_I2C[i2c]->MSCR & BIT2) == 0) // 等待start信号发送完成
    {
    }
    HAL_I2C[i2c]->DATA = addr;     // 发送地址数据
    while (HAL_I2C[i2c]->SCR == 0) // 等待地址发送完成
    {
    }
    if (HAL_I2C[i2c]->SCR & BIT1) // 收到nack
    {
        HAL_I2C[i2c]->SCR = 0;
        while (HAL_I2C[i2c]->MSCR & BIT3) // 等待stop信号发送完成
        {
        }
        return 1;
    }
    for (i = 0; i < len; i++)
    {
        HAL_I2C[i2c]->SCR = BIT4;               // 向从机发送ack响应
        while ((HAL_I2C[i2c]->SCR & BIT0) == 0) // 等待数据发送完成
        {
        }
        data[i] = HAL_I2C[i2c]->DATA;
    }
    HAL_I2C[i2c]->SCR = 0;
    while (HAL_I2C[i2c]->MSCR & BIT3) // 等待stop信号发送完成
    {
    }
    return 0;
}

/**
 * @brief 设置I2C模块的GPIO
 * @param i2c I2C模块编号
 * @param i2cgpio GPIO编号
 */
void HAL_I2C_SetGpio(HAL_I2C_x i2c, HAL_GPIO_Px i2cgpio)
{
    HAL_GPIO_SetAf(i2cgpio, 6);
    HAL_GPIO_SetMode(i2cgpio, HAL_GPIO_MODE_OUT);
}
