/**
 * *************************************************************************************************************
 * @file I2c.c
 * @author BH_CodeGenerator
 * @version 0.1
 * @date 2022-04-01
 * @warning <!--auto generated by Tools, do not modify or add anything, otherwise, your change will be lost!!! -->
 * @brief all the functions prototypes for I2c firmware library
 * MCU / CFG Ver. :BH66F2475/1.7
 * Version = 1.0.1

 * *************************************************************************************************************
 *  @attention
 *
 *  Firmware Disclaimer Information
 *
 *  1. The customer hereby acknowledges and agrees that the program technical documentation, including the
 *     code, which is supplied by BEST HEALTH ELECTRONIC Inc., (hereinafter referred to as BestHealth) is the
 *     proprietary and confidential intellectual property of BestHealth, and is protected by copyright law and
 *     other intellectual property laws.
 *
 *  2. The customer hereby acknowledges and agrees that the program technical documentation, including the
 *     code, is confidential information belonging to BestHealth, and must not be disclosed to any third parties
 *     other than BestHealth and the customer.
 *
 *  3. The program technical documentation, including the code, is provided and for customer reference
 *     only. After delivery by BestHealth, the customer shall use the program technical documentation, including
 *     the code, at their own risk. BestHealth disclaims any expressed, implied or statutory warranties, including
 *     the warranties of merchantability, satisfactory quality and fitness for a particular purpose.
 *
 *  <h2><center>Copyright (C) BEST HEALTH ELECTRONIC Inc. All rights reserved</center></h2>
 */
#include "I2c.h"
#include "..\board\BoardCfg.h"

static volatile uint8_t *regAddress;
static volatile bit isAddress;

/**
 * @brief config I2c
 *
 * @param Cfg @ref I2c_Cfg_t
 * @note I2C time out time is equal to (timeOutPeriod 1)×(32/fsub)
 */
void I2c_Cfg(const I2c_Cfg_t *Cfg)
{
#if defined(PIN_SDA_PA7)
    PIN_PA7_SDA();
#endif
#if defined(PIN_SDA_PA2)
    PIN_PA2_SDA();
#endif
#if defined(PIN_SCL_PB0)
    PIN_PB0_SCL();
#endif
#if defined(PIN_SCL_PA4)
    PIN_PA4_SCL();
#endif
    _sima  = Cfg->addr;
    _simc0 = 0xC0;    // config to I2c mode
    _simc0 &= 0xE3;
    _simc0 |= Cfg->debounce;
    _iamwu   = Cfg->flag.b.wakeUp;
    _simtoc  = Cfg->timeOutMs;
    _simtoen = Cfg->flag.b.timeOut;
}

// @ -------- I2c interrupt entry function---------------@
DEFINE_ISR(I2C_ISR, 0x30)
{
    // clang-format off
    if (_simtof)
    {
        _simtof  = 0;
        _simtoen = 1;    // reset TimerOut
        _iamwu   = 1;
    }
    else
    {
        if (_haas && _srw)
        {
            // addres match and IIC tx mode
            _htx  = 1;
            _simd = *regAddress;
            regAddress++;
        }
        else if (_haas && !_srw)
        {
            // addres match and IIC rx mode
            _htx      = 0;        // config SLAVE TO RX
            _txak     = 0;        // SET ACK signal
            _acc      = _simd;    // Dummy read from SIMD to release SCL line
            isAddress = false;
        }
        else if (!_haas && _htx)
        {
            // addres not match and IIC tx mode
            if (_rxak)
            {
                _htx  = 0;// Rxak = 1: the host stops refusing to receive the next byte and sends a stop signal
                _txak = 0;
                _acc  = _simd;    // Dummy read from SIMD to release SCL Line
            }
            else
            {
                _simd = *regAddress;// Send data
                regAddress++;
            }
        }
        else if (!_haas && !_htx)
        {
            if (!isAddress)
            {
                isAddress     = true;
                uint16_t temp = _simd;
                regAddress    = (uint8_t *)temp;    // addres not match and IIC rx mode
            }
            else
            {
                *regAddress = _simd;    // addres not match and IIC rx mode
                regAddress++;
            }
        }
    }
    // clang-format on
}
