/*
  ******************************************************************************
  * @file    APP.c
  * @author  PJ
  * @version V1.0.0
  * @date    2021
  * @brief   I2C Master demo source code.
  ******************************************************************************
*/
#include "app.h"

#define BUFFER_LENGTH    (256)

#define SLAVE_ADDRESS    (0xA6)

uint8_t gu8_TxBuffer[BUFFER_LENGTH];
uint8_t gu8_RxBuffer[BUFFER_LENGTH];

GPIO_InitTypeDef    KEY_Handle;
Slave_Comm_TypeDef   Slave_Comm;
/*********************************************************************************
* Function    : UserKEY_Init
* Description : User key initialize
* Input       : None
* Output      : None
**********************************************************************************/
void UserKEY_Init(void)
{
    KEY_Handle.Pin       = GPIO_PIN_9;
    KEY_Handle.Mode      = GPIO_MODE_INPUT;
    KEY_Handle.Pull      = GPIO_PULLUP;
    KEY_Handle.Alternate = GPIO_FUNCTION_0;

    GPIO_Init(GPIOB, &KEY_Handle);
}

/*********************************************************************************
* Function    : UserKEY_Get
* Description : detection button is pressed
* Input       : None
* Output      : None
**********************************************************************************/
bool UserKEY_Get(void)
{
    if (Bit_RESET == GPIO_ReadInputDataBit(GPIOB, GPIO_PIN_9)) 
    {
        System_Delay_MS(20);
        
        if (Bit_RESET == GPIO_ReadInputDataBit(GPIOB, GPIO_PIN_9)) 
        {
            return true;
        }
    }

    return false;
}

/************************************************************************
 * function   : User_I2C_Init
 * Description: I2C Initiation. 
 ************************************************************************/ 
void User_I2C_Init(void)
{
	I2C_InitTypeDef I2C1_InitStruc;
	GPIO_InitTypeDef GPIO_Handle;
	
	 /* Enable Clock */
	System_Module_Enable(EN_I2C1);
	System_Module_Enable(EN_GPIOAB);
    /* GPIO Config */
	/* I2C1 SDA ->PB7 I2C1 SCL ->PB6 */
	GPIO_Handle.Pin            = GPIO_PIN_6 | GPIO_PIN_7;
	GPIO_Handle.Mode           = GPIO_MODE_AF_PP;
	GPIO_Handle.Pull           = GPIO_PULLUP;
	GPIO_Handle.Alternate      = GPIO_FUNCTION_6;
	GPIO_Init(GPIOB, &GPIO_Handle);        
	/* NVIC Config */
	NVIC_ClearPendingIRQ(I2C1_IRQn);
	NVIC_EnableIRQ(I2C1_IRQn);
	/* I2C Config */
    I2C1_InitStruc.I2C_Mode        = I2C_MODE_MASTER;
    I2C1_InitStruc.I2C_Tx_Auto_En  = TX_AUTO_EN_ENABLE;
    I2C1_InitStruc.I2C_ClockSpeed  = CLOCK_SPEED_STANDARD;
	
    I2C_Init(I2C1,&I2C1_InitStruc);
	
	/* Enable I2C1 */
	I2C_Cmd(I2C1,ENABLE);
}

/*************************For I2C Master Test******************/ 
void I2C_Master_Comm_Test(void)
{
    uint32_t i;
    uint32_t Lu32_Length  = 1;
    uint32_t lu32_COM_OK  = 0;
    uint32_t lu32_COM_Err = 0;
    uint8_t Status;

    User_I2C_Init();
    
    while (1) 
    {
        if (Lu32_Length > BUFFER_LENGTH) 
        {
            Lu32_Length = 1;
        }

        for (i = 0; i < Lu32_Length; i++)
        {
            gu8_TxBuffer[i] = i+1;
        }
        
        printfS("I2C Master Test is Ready!!! \r\n");
        
        do
        {
            Status = I2C_Master_Transmit(I2C1, SLAVE_ADDRESS, gu8_TxBuffer, Lu32_Length,1000);
        }while(Status != I2C_OK);
        
        System_Delay(500000);
//		System_Delay_MS(20);
        
        do
        {
            Status = I2C_Master_Receive(I2C1, SLAVE_ADDRESS, gu8_RxBuffer, Lu32_Length,10000);
        }while(Status != I2C_OK);
        
        for (i = 0; i < Lu32_Length; i++)
        {
            if (gu8_TxBuffer[i] != gu8_RxBuffer[i]) 
            {
                printfS("There is one mistake : gu8_TxBuffer[%d] != gu8_RxBuffer[%d] \r\n", i, i);
                
                lu32_COM_Err++;
            }
            else 
            {
                lu32_COM_OK++;
            }
        }
        
        printfS("I2C Master Test OK count %d times \r\n",  lu32_COM_OK);
        printfS("I2C Master Test Err count %d times \r\n", lu32_COM_Err);
        
        printfS("I2C Master Test End!!! \r\n");

        for (i = 0; i < BUFFER_LENGTH; i++)
        {
            gu8_TxBuffer[i] = 0;
            gu8_RxBuffer[i] = 0;
        }

        lu32_COM_Err  = 0;
        lu32_COM_OK   = 0;

        Lu32_Length++;

        System_Delay(1000000);
    }
}

/*************************For I2C EEprom Test******************/ 
#define AT24_I2C                I2C1
#define AT24_DEV_ADDRESS        0xA0

#define I2C_EEWR_WRITE_READ_LENGTH  128

uint8_t I2C_EEWR_Test(void)
{

    uint8_t i;
    uint8_t wr_buff[128], rd_buff[128];

    for(i = 0; i < 128; i++)
    {
        wr_buff[i] = i+2;
    }
    printfS("iic write data\n");
    IC_AT24_WriteBytes(AT24_I2C, AT24_DEV_ADDRESS, 0x02, wr_buff, I2C_EEWR_WRITE_READ_LENGTH,1000);

    printfS("iic read data\n");
    IC_AT24_ReadBytes(AT24_I2C, AT24_DEV_ADDRESS, 0x02, rd_buff, I2C_EEWR_WRITE_READ_LENGTH,1000);  

    for(i = 0; i < I2C_EEWR_WRITE_READ_LENGTH; i++)
    {
        printfS("wr_buff[%d]= 0x%x,rd_buff[%d]= 0x%x \n", i, wr_buff[i], i, rd_buff[i]);
    }
		
    if (0 == memcmp(wr_buff, rd_buff, I2C_EEWR_WRITE_READ_LENGTH))
    {
        printfS("PASS\n"); 
        return 0;  
    }
    else
    {
        printfS("FAIL\n");  
        return 1;   
    }
}


/************************************************************************
 * function   : I2C_EEprom_Test
 * Description: I2C EEprom Test. 
 ************************************************************************/ 
void I2C_EEprom_Test(void)
{
    uint32_t test_times, total_times;
    
    test_times = 0;
    total_times = 5;
    printfS("iic write eeprom test starts!\n");

    User_I2C_Init();

    while(test_times < 5)
    {
        if (0 != I2C_EEWR_Test())     
        {
            break; 
        }
        else
        {
            test_times++;
        }
    }
    printfS("iic write eeprom test ends, success times:%d, total test times:%d!\n", test_times, total_times);
}


/************************************************************************
 * function   : I2C_Master_Test
 * Description: I2C Master Test. 
 ************************************************************************/ 
void I2C_Master_Test(enum_TEST_MODE_t fe_Mode)
{
    printfS("---------- I2C Master Test ----------\r\n");
        
    UserKEY_Init();
    
    printfS("---------- Please press the USR_PB button ----------\r\n");
    
    while(false == UserKEY_Get());

    switch (fe_Mode)
    {
        case TEST_MASTER_COMM: 
            I2C_Master_Comm_Test();
            break; 
        
        case TEST_MASTER_EEPROM: 
            I2C_EEprom_Test();
            break;
        
        default: break;     
    }
}