/*********************************************************************************************************************
* TC264 Opensourec Library TC264 Դ⣩һڹٷ SDK ӿڵĵԴ
* Copyright (c) 2022 SEEKFREE ɿƼ
*
* ļ TC264 Դһ
*
* TC264 Դ 
* Ըᷢ GPLGNU General Public License GNUͨù֤
*  GPL ĵ3棨 GPL3.0ѡģκκİ汾·/޸
*
* Դķϣܷãδκεı֤
* ûԻʺض;ı֤
* ϸμ GPL
*
* ӦյԴͬʱյһ GPL ĸ
* ûУ<https://www.gnu.org/licenses/>
*
* ע
* Դʹ GPL3.0 Դ֤Э Ϊİ汾
* Ӣİ libraries/doc ļµ GPL3_permission_statement.txt ļ
* ֤ libraries ļ ļµ LICENSE ļ
* ӭλʹò ޸ʱ뱣ɿƼİȨ
*
* ļ          zf_driver_soft_iic
* ˾          ɶɿƼ޹˾
* 汾Ϣ          鿴 libraries/doc ļ version ļ 汾˵
*           ADS v1.9.4
* ƽ̨          TC264D
*           https://seekfree.taobao.com/
*
* ޸ļ¼
*                               ע
* 2022-09-15       pudding            first version
* 2022-07-06       pudding            ޸ soft_iic transfer ȡΪ 0 ʱ restart źŵ bug
********************************************************************************************************************/

#include "zf_common_debug.h"
#include "zf_driver_delay.h"
#include "zf_driver_soft_iic.h"

#define soft_iic_gpio_high_scl()  ((Ifx_P *)soft_iic_obj->iic_scl)->OMR.U = 1 << ((soft_iic_obj->scl_pin)&0x1f)
#define soft_iic_gpio_high_sda()  ((Ifx_P *)soft_iic_obj->iic_sda)->OMR.U = 1 << ((soft_iic_obj->sda_pin)&0x1f)
#define soft_iic_gpio_low_scl()   ((Ifx_P *)soft_iic_obj->iic_scl)->OMR.U = 65536 << ((soft_iic_obj->scl_pin)&0x1f)
#define soft_iic_gpio_low_sda()   ((Ifx_P *)soft_iic_obj->iic_sda)->OMR.U = 65536 << ((soft_iic_obj->sda_pin)&0x1f)

//-------------------------------------------------------------------------------------------------------------------
//       IIC ʱ
// ˵     delay           ʱ
// ز     void
// ʹʾ     soft_iic_delay(1);
// עϢ     ڲ
//-------------------------------------------------------------------------------------------------------------------
#define soft_iic_delay(x)  for(uint32 i = x; i--; )

//-------------------------------------------------------------------------------------------------------------------
//       IIC GPIO
// ˵     x           ź
// ز     void
// ʹʾ     soft_iic_soft_iic_gpio_high_scl();
// עϢ     ڲ
//-------------------------------------------------------------------------------------------------------------------
#define soft_iic_gpio_high(x)  soft_iic_obj->iic_scl->OMR.U = 1 << ((x)&0x1f)


//-------------------------------------------------------------------------------------------------------------------
//       IIC START ź
// ˵     *soft_iic_obj    IIC ָϢ Բ zf_driver_soft_iic.h ĸʽ
// ز     void
// ʹʾ     soft_iic_start(soft_iic_obj);
// עϢ     ڲ
//-------------------------------------------------------------------------------------------------------------------
static void soft_iic_start (soft_iic_info_struct *soft_iic_obj)
{
    soft_iic_gpio_high_scl();                                           // SCL ߵƽ
    soft_iic_gpio_high_sda();                                           // SDA ߵƽ

    soft_iic_delay(soft_iic_obj->delay);
    soft_iic_gpio_low_sda();                                            // SDA 
    soft_iic_delay(soft_iic_obj->delay);
    soft_iic_gpio_low_scl();                                            // SCL 
}

//-------------------------------------------------------------------------------------------------------------------
//       IIC STOP ź
// ˵     *soft_iic_obj    IIC ָϢ Բ zf_driver_soft_iic.h ĸʽ
// ز     void
// ʹʾ     soft_iic_stop(soft_iic_obj);
// עϢ     ڲ
//-------------------------------------------------------------------------------------------------------------------
static void soft_iic_stop (soft_iic_info_struct *soft_iic_obj)
{
    soft_iic_gpio_low_sda();                                            // SDA ͵ƽ
    soft_iic_gpio_low_scl();                                            // SCL ͵ƽ

    soft_iic_delay(soft_iic_obj->delay);
    soft_iic_gpio_high_scl();                                           // SCL 
    soft_iic_delay(soft_iic_obj->delay);
    soft_iic_gpio_high_sda();                                           // SDA 
    soft_iic_delay(soft_iic_obj->delay);
}

//-------------------------------------------------------------------------------------------------------------------
//       IIC  ACK/NAKC ź ڲ
// ˵     *soft_iic_obj    IIC ָϢ Բ zf_driver_soft_iic.h ĸʽ
// ˵     ack             ACK ƽ
// ز     void
// ʹʾ     soft_iic_send_ack(soft_iic_obj, 1);
// עϢ     ڲ
//-------------------------------------------------------------------------------------------------------------------
static void soft_iic_send_ack (soft_iic_info_struct *soft_iic_obj, uint8 ack)
{
    soft_iic_gpio_low_scl();                                            // SCL ͵ƽ

    if(ack)
    {
        soft_iic_gpio_high_sda();                                       // SDA 
    }
    else
    {
        soft_iic_gpio_low_sda();                                        // SDA 
    }

    soft_iic_delay(soft_iic_obj->delay);
    soft_iic_gpio_high_scl();                                           // SCL 
    soft_iic_delay(soft_iic_obj->delay);
    soft_iic_gpio_low_scl();                                            // SCL 
    soft_iic_gpio_high_sda();                                           // SDA 
}

//-------------------------------------------------------------------------------------------------------------------
//       IIC ȡ ACK/NAKC ź
// ˵     *soft_iic_obj    IIC ָϢ Բ zf_driver_soft_iic.h ĸʽ
// ز     uint8           ACK ״̬
// ʹʾ     soft_iic_wait_ack(soft_iic_obj);
// עϢ     ڲ
//-------------------------------------------------------------------------------------------------------------------
static uint8 soft_iic_wait_ack (soft_iic_info_struct *soft_iic_obj)
{
    uint8 temp = 0;
    soft_iic_gpio_low_scl();                                            // SCL ͵ƽ
    soft_iic_gpio_high_sda();                                           // SDA ߵƽ ͷ SDA
#if SOFT_IIC_SDA_IO_SWITCH
    gpio_set_dir(soft_iic_obj->sda_pin, GPI, GPI_FLOATING_IN);
#endif
    soft_iic_delay(soft_iic_obj->delay);

    soft_iic_gpio_high_scl();                                           // SCL ߵƽ
    soft_iic_delay(soft_iic_obj->delay);

    if(gpio_get_level(soft_iic_obj->sda_pin))
    {
        temp = 1;
    }
    soft_iic_gpio_low_scl();                                            // SCL ͵ƽ
#if SOFT_IIC_SDA_IO_SWITCH
    gpio_set_dir(soft_iic_obj->sda_pin, GPO, GPO_OPEN_DTAIN);
#endif
    soft_iic_delay(soft_iic_obj->delay);

    return temp;
}

//-------------------------------------------------------------------------------------------------------------------
//       IIC  8bit 
// ˵     *soft_iic_obj    IIC ָϢ Բ zf_driver_soft_iic.h ĸʽ
// ˵     data            
// ز     uint8           ACK ״̬
// עϢ     ڲ
//-------------------------------------------------------------------------------------------------------------------
static uint8 soft_iic_send_data (soft_iic_info_struct *soft_iic_obj, const uint8 data)
{
    uint8 temp = 0x80;
    while(temp)
    {
        gpio_set_level(soft_iic_obj->sda_pin, data & temp);
        temp >>= 1;

        soft_iic_delay(soft_iic_obj->delay);
        soft_iic_gpio_high_scl();                                       // SCL 
        soft_iic_delay(soft_iic_obj->delay);
        soft_iic_gpio_low_scl();                                        // SCL 
    }
    return ((soft_iic_wait_ack(soft_iic_obj) == 1) ? 0 : 1 );
}

//-------------------------------------------------------------------------------------------------------------------
//       IIC ȡ 8bit 
// ˵     *soft_iic_obj    IIC ָϢ Բ zf_driver_soft_iic.h ĸʽ
// ˵     ack             ACK  NACK
// ز     uint8           
// עϢ     ڲ
//-------------------------------------------------------------------------------------------------------------------
static uint8 soft_iic_read_data (soft_iic_info_struct *soft_iic_obj, uint8 ack)
{
    uint8 data = 0x00;
    uint8 temp = 8;
    soft_iic_gpio_low_scl();                                            // SCL ͵ƽ
    soft_iic_delay(soft_iic_obj->delay);
    soft_iic_gpio_high_sda();                                           // SDA ߵƽ ͷ SDA
#if SOFT_IIC_SDA_IO_SWITCH
    gpio_set_dir(soft_iic_obj->sda_pin, GPI, GPI_FLOATING_IN);
#endif

    while(temp --)
    {
        soft_iic_gpio_low_scl();                                        // SCL 
        soft_iic_delay(soft_iic_obj->delay);
        soft_iic_gpio_high_scl();                                       // SCL 
        soft_iic_delay(soft_iic_obj->delay);
        data = ((data << 1) | gpio_get_level(soft_iic_obj->sda_pin));
    }
    soft_iic_gpio_low_scl();                                            // SCL ͵ƽ
#if SOFT_IIC_SDA_IO_SWITCH
    gpio_set_dir(soft_iic_obj->sda_pin, GPO, GPO_OPEN_DTAIN);
#endif
    soft_iic_delay(soft_iic_obj->delay);
    soft_iic_send_ack(soft_iic_obj, ack);
    return data;
}

//-------------------------------------------------------------------------------------------------------------------
//       IIC ӿд 8bit 
// ˵     *soft_iic_obj    IIC ָϢ Բ zf_driver_soft_iic.h ĸʽ
// ˵     data            Ҫд
// ز     void
// ʹʾ     soft_iic_write_8bit_register(soft_iic_obj, 0x01);
// עϢ
//-------------------------------------------------------------------------------------------------------------------
void soft_iic_write_8bit (soft_iic_info_struct *soft_iic_obj, const uint8 data)
{
    soft_iic_start(soft_iic_obj);
    soft_iic_send_data(soft_iic_obj, soft_iic_obj->addr << 1);
    soft_iic_send_data(soft_iic_obj, data);
    soft_iic_stop(soft_iic_obj);
}

//-------------------------------------------------------------------------------------------------------------------
//       IIC ӿд 8bit 
// ˵     *soft_iic_obj    IIC ָϢ Բ zf_driver_soft_iic.h ĸʽ
// ˵     *data           ݴŻ
// ˵     len             
// ز     void
// ʹʾ     soft_iic_write_8bit_array(soft_iic_obj, data, 6);
// עϢ
//-------------------------------------------------------------------------------------------------------------------
void soft_iic_write_8bit_array (soft_iic_info_struct *soft_iic_obj, const uint8 *data, uint32 len)
{
    soft_iic_start(soft_iic_obj);
    soft_iic_send_data(soft_iic_obj, soft_iic_obj->addr << 1);
    while(len --)
    {
        soft_iic_send_data(soft_iic_obj, *data ++);
    }
    soft_iic_stop(soft_iic_obj);
}

//-------------------------------------------------------------------------------------------------------------------
//       IIC ӿд 16bit 
// ˵     *soft_iic_obj    IIC ָϢ Բ zf_driver_soft_iic.h ĸʽ
// ˵     data            Ҫд
// ز     void
// ʹʾ     soft_iic_write_16bit(soft_iic_obj, 0x0101);
// עϢ
//-------------------------------------------------------------------------------------------------------------------
void soft_iic_write_16bit (soft_iic_info_struct *soft_iic_obj, const uint16 data)
{
    soft_iic_start(soft_iic_obj);
    soft_iic_send_data(soft_iic_obj, soft_iic_obj->addr << 1);
    soft_iic_send_data(soft_iic_obj, (uint8)((data & 0xFF00) >> 8));
    soft_iic_send_data(soft_iic_obj, (uint8)(data & 0x00FF));
    soft_iic_stop(soft_iic_obj);
}

//-------------------------------------------------------------------------------------------------------------------
//       IIC ӿд 16bit 
// ˵     *soft_iic_obj    IIC ָϢ Բ zf_driver_soft_iic.h ĸʽ
// ˵     *data           ݴŻ
// ˵     len             
// ز     void
// ʹʾ     soft_iic_write_16bit_array(soft_iic_obj, data, 6);
// עϢ
//-------------------------------------------------------------------------------------------------------------------
void soft_iic_write_16bit_array (soft_iic_info_struct *soft_iic_obj, const uint16 *data, uint32 len)
{
    soft_iic_start(soft_iic_obj);
    soft_iic_send_data(soft_iic_obj, soft_iic_obj->addr << 1);
    while(len --)
    {
        soft_iic_send_data(soft_iic_obj, (uint8)((*data & 0xFF00) >> 8));
        soft_iic_send_data(soft_iic_obj, (uint8)(*data ++ & 0x00FF));
    }
    soft_iic_stop(soft_iic_obj);
}

//-------------------------------------------------------------------------------------------------------------------
//       IIC ӿ򴫸Ĵд 8bit 
// ˵     *soft_iic_obj    IIC ָϢ Բ zf_driver_soft_iic.h ĸʽ
// ˵     register_name   ļĴַ
// ˵     data            Ҫд
// ز     void
// ʹʾ     soft_iic_write_8bit_register(soft_iic_obj, 0x01, 0x01);
// עϢ
//-------------------------------------------------------------------------------------------------------------------
void soft_iic_write_8bit_register (soft_iic_info_struct *soft_iic_obj, const uint8 register_name, const uint8 data)
{
    soft_iic_start(soft_iic_obj);
    soft_iic_send_data(soft_iic_obj, soft_iic_obj->addr << 1);
    soft_iic_send_data(soft_iic_obj, register_name);
    soft_iic_send_data(soft_iic_obj, data);
    soft_iic_stop(soft_iic_obj);
}

//-------------------------------------------------------------------------------------------------------------------
//       IIC ӿ򴫸Ĵд 8bit 
// ˵     *soft_iic_obj    IIC ָϢ Բ zf_driver_soft_iic.h ĸʽ
// ˵     register_name   ļĴַ
// ˵     *data           ݴŻ
// ˵     len             
// ز     void
// ʹʾ     soft_iic_write_8bit_registers(soft_iic_obj, 0x01, data, 6);
// עϢ
//-------------------------------------------------------------------------------------------------------------------
void soft_iic_write_8bit_registers (soft_iic_info_struct *soft_iic_obj, const uint8 register_name, const uint8 *data, uint32 len)
{
    soft_iic_start(soft_iic_obj);
    soft_iic_send_data(soft_iic_obj, soft_iic_obj->addr << 1);
    soft_iic_send_data(soft_iic_obj, register_name);
    while(len --)
    {
        soft_iic_send_data(soft_iic_obj, *data ++);
    }
    soft_iic_stop(soft_iic_obj);
}

//-------------------------------------------------------------------------------------------------------------------
//       IIC ӿ򴫸Ĵд 16bit 
// ˵     *soft_iic_obj    IIC ָϢ Բ zf_driver_soft_iic.h ĸʽ
// ˵     register_name   ļĴַ
// ˵     data            Ҫд
// ز     void
// ʹʾ     soft_iic_write_16bit_register(soft_iic_obj, 0x0101, 0x0101);
// עϢ
//-------------------------------------------------------------------------------------------------------------------
void soft_iic_write_16bit_register (soft_iic_info_struct *soft_iic_obj, const uint16 register_name, const uint16 data)
{
    soft_iic_start(soft_iic_obj);
    soft_iic_send_data(soft_iic_obj, soft_iic_obj->addr << 1);
    soft_iic_send_data(soft_iic_obj, (uint8)((register_name & 0xFF00) >> 8));
    soft_iic_send_data(soft_iic_obj, (uint8)(register_name & 0x00FF));
    soft_iic_send_data(soft_iic_obj, (uint8)((data & 0xFF00) >> 8));
    soft_iic_send_data(soft_iic_obj, (uint8)(data & 0x00FF));
    soft_iic_stop(soft_iic_obj);
}

//-------------------------------------------------------------------------------------------------------------------
//       IIC ӿ򴫸Ĵд 16bit 
// ˵     *soft_iic_obj    IIC ָϢ Բ zf_driver_soft_iic.h ĸʽ
// ˵     register_name   ļĴַ
// ˵     *data           ݴŻ
// ˵     len             
// ز     void
// ʹʾ     soft_iic_write_16bit_registers(soft_iic_obj, 0x0101, data, 6);
// עϢ
//-------------------------------------------------------------------------------------------------------------------
void soft_iic_write_16bit_registers (soft_iic_info_struct *soft_iic_obj, const uint16 register_name, const uint16 *data, uint32 len)
{
    soft_iic_start(soft_iic_obj);
    soft_iic_send_data(soft_iic_obj, soft_iic_obj->addr << 1);
    soft_iic_send_data(soft_iic_obj, (uint8)((register_name & 0xFF00) >> 8));
    soft_iic_send_data(soft_iic_obj, (uint8)(register_name & 0x00FF));
    while(len--)
    {
        soft_iic_send_data(soft_iic_obj, (uint8)((*data & 0xFF00) >> 8));
        soft_iic_send_data(soft_iic_obj, (uint8)(*data ++ & 0x00FF));
    }
    soft_iic_stop(soft_iic_obj);
}

//-------------------------------------------------------------------------------------------------------------------
//       IIC ӿڶȡ 8bit 
// ˵     *soft_iic_obj    IIC ָϢ Բ zf_driver_soft_iic.h ĸʽ
// ز     uint8           ضȡ 8bit 
// ʹʾ     soft_iic_read_8bit(soft_iic_obj);
// עϢ
//-------------------------------------------------------------------------------------------------------------------
uint8 soft_iic_read_8bit (soft_iic_info_struct *soft_iic_obj)
{
    uint8 temp = 0;
    soft_iic_start(soft_iic_obj);
    soft_iic_send_data(soft_iic_obj, soft_iic_obj->addr << 1 | 0x01);
    temp = soft_iic_read_data(soft_iic_obj, 1);
    soft_iic_stop(soft_iic_obj);
    return temp;
}

//-------------------------------------------------------------------------------------------------------------------
//       IIC ӿڴӴĴȡ 8bit 
// ˵     *soft_iic_obj    IIC ָϢ Բ zf_driver_soft_iic.h ĸʽ
// ˵     register_name   ļĴַ
// ˵     *data           ҪȡݵĻָ
// ˵     len             Ҫȡݳ
// ز     void
// ʹʾ     soft_iic_read_8bit_array(soft_iic_obj, data, 8);
// עϢ
//-------------------------------------------------------------------------------------------------------------------
void soft_iic_read_8bit_array (soft_iic_info_struct *soft_iic_obj, uint8 *data, uint32 len)
{
    soft_iic_start(soft_iic_obj);
    soft_iic_send_data(soft_iic_obj, soft_iic_obj->addr << 1 | 0x01);
    while(len --)
    {
        *data ++ = soft_iic_read_data(soft_iic_obj, len == 0);
    }
    soft_iic_stop(soft_iic_obj);
}

//-------------------------------------------------------------------------------------------------------------------
//       IIC ӿڶȡ 16bit 
// ˵     *soft_iic_obj    IIC ָϢ Բ zf_driver_soft_iic.h ĸʽ
// ˵     register_name   ļĴַ
// ز     uint16          ضȡ 16bit 
// ʹʾ     soft_iic_read_16bit(soft_iic_obj);
// עϢ
//-------------------------------------------------------------------------------------------------------------------
uint16 soft_iic_read_16bit (soft_iic_info_struct *soft_iic_obj)
{
    uint16 temp = 0;
    soft_iic_start(soft_iic_obj);
    soft_iic_send_data(soft_iic_obj, soft_iic_obj->addr << 1 | 0x01);
    temp = soft_iic_read_data(soft_iic_obj, 0);
    temp = ((temp << 8)| soft_iic_read_data(soft_iic_obj, 1));
    soft_iic_stop(soft_iic_obj);
    return temp;
}

//-------------------------------------------------------------------------------------------------------------------
//       IIC ӿڶȡ 16bit 
// ˵     *soft_iic_obj    IIC ָϢ Բ zf_driver_soft_iic.h ĸʽ
// ˵     *data           ҪȡݵĻָ
// ˵     len             Ҫȡݳ
// ز     void
// ʹʾ     soft_iic_read_16bit_array(soft_iic_obj, data, 8);
// עϢ
//-------------------------------------------------------------------------------------------------------------------
void soft_iic_read_16bit_array (soft_iic_info_struct *soft_iic_obj, uint16 *data, uint32 len)
{
    soft_iic_start(soft_iic_obj);
    soft_iic_send_data(soft_iic_obj, soft_iic_obj->addr << 1 | 0x01);
    while(len --)
    {
        *data = soft_iic_read_data(soft_iic_obj, 0);
        *data = ((*data << 8)| soft_iic_read_data(soft_iic_obj, len == 0));
        data ++;
    }
    soft_iic_stop(soft_iic_obj);
}

//-------------------------------------------------------------------------------------------------------------------
//       IIC ӿڴӴĴȡ 8bit 
// ˵     *soft_iic_obj    IIC ָϢ Բ zf_driver_soft_iic.h ĸʽ
// ˵     register_name   ļĴַ
// ز     uint8           ضȡ 8bit 
// ʹʾ     soft_iic_read_8bit_register(soft_iic_obj, 0x01);
// עϢ
//-------------------------------------------------------------------------------------------------------------------
uint8 soft_iic_read_8bit_register (soft_iic_info_struct *soft_iic_obj, const uint8 register_name)
{
    uint8 temp = 0;
    soft_iic_start(soft_iic_obj);
    soft_iic_send_data(soft_iic_obj, soft_iic_obj->addr << 1);
    soft_iic_send_data(soft_iic_obj, register_name);
    soft_iic_start(soft_iic_obj);
    soft_iic_send_data(soft_iic_obj, soft_iic_obj->addr << 1 | 0x01);
    temp = soft_iic_read_data(soft_iic_obj, 1);
    soft_iic_stop(soft_iic_obj);
    return temp;
}

//-------------------------------------------------------------------------------------------------------------------
//       IIC ӿڴӴĴȡ 8bit 
// ˵     *soft_iic_obj    IIC ָϢ Բ zf_driver_soft_iic.h ĸʽ
// ˵     register_name   ļĴַ
// ˵     *data           ҪȡݵĻָ
// ˵     len             Ҫȡݳ
// ز     void
// ʹʾ     soft_iic_read_8bit_registers(soft_iic_obj, 0x01, data, 8);
// עϢ
//-------------------------------------------------------------------------------------------------------------------
void soft_iic_read_8bit_registers (soft_iic_info_struct *soft_iic_obj, const uint8 register_name, uint8 *data, uint32 len)
{
    soft_iic_start(soft_iic_obj);
    soft_iic_send_data(soft_iic_obj, soft_iic_obj->addr << 1);
    soft_iic_send_data(soft_iic_obj, register_name);
    soft_iic_start(soft_iic_obj);
    soft_iic_send_data(soft_iic_obj, soft_iic_obj->addr << 1 | 0x01);
    while(len --)
    {
        *data ++ = soft_iic_read_data(soft_iic_obj, len == 0);
    }
    soft_iic_stop(soft_iic_obj);
}

//-------------------------------------------------------------------------------------------------------------------
//       IIC ӿڴӴĴȡ 16bit 
// ˵     *soft_iic_obj    IIC ָϢ Բ zf_driver_soft_iic.h ĸʽ
// ˵     register_name   ļĴַ
// ز     uint16          ضȡ 16bit 
// ʹʾ     soft_iic_read_16bit_register(soft_iic_obj, 0x0101);
// עϢ
//-------------------------------------------------------------------------------------------------------------------
uint16 soft_iic_read_16bit_register (soft_iic_info_struct *soft_iic_obj, const uint16 register_name)
{
    uint16 temp = 0;
    soft_iic_start(soft_iic_obj);
    soft_iic_send_data(soft_iic_obj, soft_iic_obj->addr << 1);
    soft_iic_send_data(soft_iic_obj, (uint8)((register_name & 0xFF00) >> 8));
    soft_iic_send_data(soft_iic_obj, (uint8)(register_name & 0x00FF));
    soft_iic_start(soft_iic_obj);
    soft_iic_send_data(soft_iic_obj, soft_iic_obj->addr << 1 | 0x01);
    temp = soft_iic_read_data(soft_iic_obj, 0);
    temp = ((temp << 8)| soft_iic_read_data(soft_iic_obj, 1));
    soft_iic_stop(soft_iic_obj);
    return temp;
}

//-------------------------------------------------------------------------------------------------------------------
//       IIC ӿڴӴĴȡ 16bit 
// ˵     *soft_iic_obj    IIC ָϢ Բ zf_driver_soft_iic.h ĸʽ
// ˵     register_name   ļĴַ
// ˵     *data           ҪȡݵĻָ
// ˵     len             Ҫȡݳ
// ز     void
// ʹʾ     soft_iic_read_16bit_registers(soft_iic_obj, 0x0101, data, 8);
// עϢ
//-------------------------------------------------------------------------------------------------------------------
void soft_iic_read_16bit_registers (soft_iic_info_struct *soft_iic_obj, const uint16 register_name, uint16 *data, uint32 len)
{
    soft_iic_start(soft_iic_obj);
    soft_iic_send_data(soft_iic_obj, soft_iic_obj->addr << 1);
    soft_iic_send_data(soft_iic_obj, (uint8)((register_name & 0xFF00) >> 8));
    soft_iic_send_data(soft_iic_obj, (uint8)(register_name & 0x00FF));
    soft_iic_start(soft_iic_obj);
    soft_iic_send_data(soft_iic_obj, soft_iic_obj->addr << 1 | 0x01);
    while(len --)
    {
        *data = soft_iic_read_data(soft_iic_obj, 0);
        *data = ((*data << 8)| soft_iic_read_data(soft_iic_obj, len == 0));
        data ++;
    }
    soft_iic_stop(soft_iic_obj);
}

//-------------------------------------------------------------------------------------------------------------------
//       IIC ӿڴ 8bit  дȡ
// ˵     *soft_iic_obj    IIC ָϢ Բ zf_driver_soft_iic.h ĸʽ
// ˵     *write_data     ݴŻ
// ˵     write_len       ͻ
// ˵     *read_data      ȡݴŻ
// ˵     read_len        ȡ
// ز     void
// ʹʾ     iic_transfer_8bit_array(IIC_1, addr, data, 64, data, 64);
// עϢ
//-------------------------------------------------------------------------------------------------------------------
void soft_iic_transfer_8bit_array (soft_iic_info_struct *soft_iic_obj, const uint8 *write_data, uint32 write_len, uint8 *read_data, uint32 read_len)
{
    soft_iic_start(soft_iic_obj);
    soft_iic_send_data(soft_iic_obj, soft_iic_obj->addr << 1);
    while(write_len --)
    {
        soft_iic_send_data(soft_iic_obj, *write_data ++);
    }
    if(read_len)
    {
        soft_iic_start(soft_iic_obj);
        soft_iic_send_data(soft_iic_obj, soft_iic_obj->addr << 1 | 0x01);
        while(read_len --)
        {
            *read_data ++ = soft_iic_read_data(soft_iic_obj, 0 == read_len);
        }
    }
    soft_iic_stop(soft_iic_obj);

}

//-------------------------------------------------------------------------------------------------------------------
//       IIC ӿڴ 16bit  дȡ
// ˵     *soft_iic_obj    IIC ָϢ Բ zf_driver_soft_iic.h ĸʽ
// ˵     *write_data     ݴŻ
// ˵     write_len       ͻ
// ˵     *read_data      ȡݴŻ
// ˵     read_len        ȡ
// ز     void
// ʹʾ     iic_transfer_16bit_array(IIC_1, addr, data, 64, data, 64);
// עϢ
//-------------------------------------------------------------------------------------------------------------------
void soft_iic_transfer_16bit_array (soft_iic_info_struct *soft_iic_obj, const uint16 *write_data, uint32 write_len, uint16 *read_data, uint32 read_len)
{
    soft_iic_start(soft_iic_obj);
    soft_iic_send_data(soft_iic_obj, soft_iic_obj->addr << 1);
    while(write_len--)
    {
        soft_iic_send_data(soft_iic_obj, (uint8)((*write_data & 0xFF00) >> 8));
        soft_iic_send_data(soft_iic_obj, (uint8)(*write_data ++ & 0x00FF));
    }
    if(read_len)
    {
        soft_iic_start(soft_iic_obj);
        soft_iic_send_data(soft_iic_obj, soft_iic_obj->addr << 1 | 0x01);
        while(read_len --)
        {
            *read_data = soft_iic_read_data(soft_iic_obj, 0);
            *read_data = ((*read_data << 8)| soft_iic_read_data(soft_iic_obj, 0 == read_len));
            read_data ++;
        }
    }
    soft_iic_stop(soft_iic_obj);
}

//-------------------------------------------------------------------------------------------------------------------
//       IIC ӿ SCCB ģʽ򴫸Ĵд 8bit 
// ˵     *soft_iic_obj    IIC ָϢ Բ zf_driver_soft_iic.h ĸʽ
// ˵     register_name   ļĴַ
// ˵     data            Ҫд
// ز     void
// ʹʾ     soft_iic_sccb_write_register(soft_iic_obj, 0x01, 0x01);
// עϢ
//-------------------------------------------------------------------------------------------------------------------
void soft_iic_sccb_write_register (soft_iic_info_struct *soft_iic_obj, const uint8 register_name, uint8 data)
{
    soft_iic_start(soft_iic_obj);
    soft_iic_send_data(soft_iic_obj, soft_iic_obj->addr << 1);
    soft_iic_send_data(soft_iic_obj, register_name);
    soft_iic_send_data(soft_iic_obj, data);
    soft_iic_stop(soft_iic_obj);
}

//-------------------------------------------------------------------------------------------------------------------
//       IIC ӿ SCCB ģʽӴĴȡ 8bit 
// ˵     *soft_iic_obj    IIC ָϢ Բ zf_driver_soft_iic.h ĸʽ
// ˵     register_name   ļĴַ
// ز     uint8           ضȡ 8bit 
// ʹʾ     soft_iic_sccb_read_register(soft_iic_obj, 0x01);
// עϢ
//-------------------------------------------------------------------------------------------------------------------
uint8 soft_iic_sccb_read_register (soft_iic_info_struct *soft_iic_obj, const uint8 register_name)
{
    uint8 temp = 0;
    soft_iic_start(soft_iic_obj);
    soft_iic_send_data(soft_iic_obj, soft_iic_obj->addr << 1);
    soft_iic_send_data(soft_iic_obj, register_name);
    soft_iic_stop(soft_iic_obj);

    soft_iic_start(soft_iic_obj);
    soft_iic_send_data(soft_iic_obj, soft_iic_obj->addr << 1 | 0x01);
    temp = soft_iic_read_data(soft_iic_obj, 1);
    soft_iic_stop(soft_iic_obj);
    return temp;
}

//-------------------------------------------------------------------------------------------------------------------
//       IIC ӿڳʼ Ĭ MASTER ģʽ ṩ SLAVE ģʽ
// ˵     *soft_iic_obj    IIC ָϢŽṹָ
// ˵     addr             IIC ַ Ҫע ׼λַ λ дʱȷ
// ˵     delay            IIC ʱ ʱӸߵƽʱ Խ IIC Խ
// ˵     scl_pin          IIC ʱ  zf_driver_gpio.h  gpio_pin_enum ö嶨
// ˵     sda_pin          IIC   zf_driver_gpio.h  gpio_pin_enum ö嶨
// ز     void
// ʹʾ     soft_iic_init(&soft_iic_obj, addr, 100, B6, B7);
// עϢ
//-------------------------------------------------------------------------------------------------------------------
void soft_iic_init (soft_iic_info_struct *soft_iic_obj, uint8 addr, uint32 delay, gpio_pin_enum scl_pin, gpio_pin_enum sda_pin)
{
    zf_assert(scl_pin != sda_pin);                                              // ѣ scl_pin  sda_pin ôͬһţ
    soft_iic_obj->scl_pin = scl_pin;
    soft_iic_obj->sda_pin = sda_pin;
    soft_iic_obj->addr = addr;
    soft_iic_obj->delay = delay;
    soft_iic_obj->iic_scl = (void *)get_port(scl_pin);
    soft_iic_obj->iic_sda = (void *)get_port(sda_pin);
    gpio_init(scl_pin, GPO, GPIO_HIGH, GPO_PUSH_PULL);                          // ȡӦIO AFܱ
    gpio_init(sda_pin, GPO, GPIO_HIGH, GPO_OPEN_DTAIN);                         // ȡӦIO AFܱ
}
