/**
  ******************************************************************************
  * @file    main.h
  * @author  kevin_guo
  * @version V1.0.0
  * @date    01-03-2019
  * @brief   This file contains all files for main.
  ******************************************************************************
  * @attention
  ******************************************************************************
  */
	
/* Includes ------------------------------------------------------------------*/
#include <stdio.h>
#include <string.h>
#include "M451Series.h"	
#include "board.h"				

#include "VK16D32A_IO_I2C_QUASI.h"			//单片机SDA脚设为双向IO
//#include "VK16D32A_IO_I2C_DIR.h"				//单片机SDA脚设为单向IO
//#include "VK16D32A_I2C.h"								//单片机硬件I2C

/* extern variables ----------------------------------------------------------*/
/* Private typedef -----------------------------------------------------------*/
/* Private defines -----------------------------------------------------------*/
/* Private macros ------------------------------------------------------------*/	
/* Private variables ---------------------------------------------------------*/
typedef void (*I2C_FUNC)(unsigned int i2cstatus);
static I2C_FUNC i2c0handlerflag = NULL;
unsigned char i2cwrbuf[64];
unsigned char i2crdtx;
unsigned char i2crdrx;
unsigned char rxdummy;
unsigned char txlen,txcnt;
unsigned char rxlen,rxcnt;
unsigned char endflag= 0;
/* Private function prototypes -----------------------------------------------*/
/* Private functions ---------------------------------------------------------*/
/*---------------------------------------------------------------------------------------------------------*/
/*  I2C0 IRQ Handler                                                                                       */
/*---------------------------------------------------------------------------------------------------------*/
void I2C0_IRQHandler(void)
{
    unsigned int status;

    status = I2C_GET_STATUS(I2C0);
    if(I2C_GET_TIMEOUT_FLAG(I2C0))
    {
        /* Clear I2C0 Timeout Flag */
        I2C_ClearTimeoutFlag(I2C0);
    }
    else
    {
        if(i2c0handlerflag != NULL)
            i2c0handlerflag(status);
    }
}

/*---------------------------------------------------------------------------------------------------------*/
/*  I2C Rx Callback Function                                                                               */
/*---------------------------------------------------------------------------------------------------------*/
void I2C_MasterRx(unsigned int rxstatus)
{
    if(rxstatus == 0x08)                       /* START has been transmitted and prepare SLA+W */
    {
        I2C_SET_DATA(I2C0, (VK16D32A_ADDR << 1));    /* Write SLA+W to Register I2CDAT */
				I2C_SET_CONTROL_REG(I2C0, I2C_CTL_SI);	//发送地址写bit，读ACK
    }
    else if(rxstatus == 0x18)                  /* SLA+W has been transmitted and ACK has been received */
    {
				I2C_SET_DATA(I2C0, i2crdtx);
				I2C_SET_CONTROL_REG(I2C0, I2C_CTL_SI);	//发送数据，读ACK
    }
    else if(rxstatus == 0x20)                  /* SLA+W has been transmitted and NACK has been received */
    {
        I2C_STOP(I2C0);
        I2C_START(I2C0);
    }
    else if(rxstatus == 0x28)                  /* DATA has been transmitted and ACK has been received */
    {
        I2C_SET_CONTROL_REG(I2C0, I2C_CTL_STA_SI);  //数据·发送完SR START
    }
    else if(rxstatus == 0x10)                  /* Repeat START has been transmitted and prepare SLA+R */
    {
        I2C_SET_DATA(I2C0, ((VK16D32A_ADDR << 1) | 0x01));   /* Write SLA+R to Register I2CDAT */
			I2C_SET_CONTROL_REG(I2C0, I2C_CTL_SI);	//发送地址读bit，读ACK
    }
    else if(rxstatus == 0x40)                  /* SLA+R has been transmitted and ACK has been received */
    {
        I2C_SET_CONTROL_REG(I2C0, I2C_CTL_SI);
    }
    else if(rxstatus == 0x58)                  /* DATA has been received and NACK has been returned */
    {
			i2crdrx = (unsigned char) I2C_GET_DATA(I2C0);
			I2C_SET_CONTROL_REG(I2C0, I2C_CTL_STO_SI); //发送STOP
			endflag = 1;
    } 
    else
    {
        /* TO DO */
        //rxstatusis NOT processed
			__nop();
    }
}

/*---------------------------------------------------------------------------------------------------------*/
/*  I2C Tx Callback Function                                                                               */
/*---------------------------------------------------------------------------------------------------------*/
void I2C_MasterTx(unsigned int txstatus)
{
    if(txstatus == 0x08)                       /* START has been transmitted */
    {
        I2C_SET_DATA(I2C0, VK16D32A_ADDR << 1);    /* Write SLA+W to Register I2CDAT */
        I2C_SET_CONTROL_REG(I2C0, I2C_CTL_SI);
    }
    else if(txstatus == 0x18)                  /* SLA+W has been transmitted and ACK has been received */
    {
        I2C_SET_DATA(I2C0, i2cwrbuf[txcnt++]);
        I2C_SET_CONTROL_REG(I2C0, I2C_CTL_SI);
    }
    else if(txstatus == 0x20)                  /* SLA+W has been transmitted and NACK has been received */
    {
        I2C_STOP(I2C0);
        I2C_START(I2C0);
    }
    else if(txstatus == 0x28)                  /* DATA has been transmitted and ACK has been received */
    {
        if(txcnt != txlen)
        {
            I2C_SET_DATA(I2C0, i2cwrbuf[txcnt++]);
            I2C_SET_CONTROL_REG(I2C0, I2C_CTL_SI);
        }
        else
        {
            I2C_SET_CONTROL_REG(I2C0, I2C_CTL_STO_SI);
            endflag = 1;
        }
    }
    else
    {
       /* TO DO */
      //txstatus is NOT processed
			__nop();
    }
}

/*******************************************************************************
* Function Name  : loopshift_left8
* Description    : 循环左移8位
* Input          : None
* Output         : None
* Return         : None
*******************************************************************************/
unsigned char loopshift_left8(unsigned char dat)
{
	unsigned char i,retval,datval;
	
	datval=dat;
	retval=0;
	for(i=0;i<8;i++)
	{
		retval>>=1;
		if((datval&0x80)==0x80)
			retval|=0x80;
		datval<<=1;
	}
	return retval;
}
/*******************************************************************************
* Function Name  : VK16D32A_I2C_Dat
* Description    : i2c发送数据
* Input          : None
* Output         : None
* Return         : None
*******************************************************************************/
void VK16D32A_I2C_WRDat(unsigned char Addr,unsigned char *Databuf,unsigned char cnt)
{
	unsigned char i;
	
	i2cwrbuf[0] = Addr&0xff; //字节0是显示ram地址或者按键ram地址或者INF标志寄存器地址
	for(i=0;i<cnt;i++)
	{
		//i2cdatbuf[1+i] = loopshift_left8(*Databuf++);  //显示数据是低位先送，字节0是地址		
		i2cwrbuf[1+i] = *Databuf++; 
	}
	txcnt = 0;
	txlen=cnt+1;  //字节0是地址
	endflag = 0;

	/* I2C function to write data to slave */
	i2c0handlerflag = (I2C_FUNC)I2C_MasterTx;

	/* I2C as master sends START signal */
	I2C_SET_CONTROL_REG(I2C0, I2C_CTL_STA);

	/* Wait I2C Tx Finish */
	while(endflag == 0);
	endflag = 0;
}

/*******************************************************************************
* Function Name  : VK16D32A_I2C_RDDat
* Description    : i2c接收数据
* Input          : None
* Output         : None
* Return         : None
*******************************************************************************/
void VK16D32A_I2C_RDDat(unsigned char Addr,unsigned char *Databuf,unsigned char cnt)
{	
	unsigned char i,rxnum;
	
	rxnum=cnt;
	for(i=0;i<rxnum;i++)
	{
		//I2C发送地址
		i2crdtx = (Addr&0xff)+i;
		txcnt = 0;
		txlen=1;
		endflag = 0;
		//I2C接收数据
	/* I2C function to read data from slave */
		i2c0handlerflag = (I2C_FUNC)I2C_MasterRx;

		rxcnt = 0;
		rxlen=1;

		I2C_SET_CONTROL_REG(I2C0, I2C_CTL_STA);

		/* Wait I2C Rx Finish */
		while(endflag == 0);
		//*Databuf++=loopshift_left8(i2cdatbuf[txlen]); //显示数据是低位先读
		*Databuf++=i2crdrx; 
	}
}

/*******************************************************************************
* Function Name  : VK16D32A_I2C_Cmd
* Description    : i2c发送命令
* Input          : cmdbuf-命令buf
* 				       : cnt-命令数量
* Output         : None
* Return         : None
*******************************************************************************/
void VK16D32A_I2C_Cmd(unsigned char* cmdbuf,unsigned char cnt)
{
	unsigned char i;
	
	for(i=0;i<cnt;i++)
	{
		i2cwrbuf[i] = *cmdbuf++;
	}
	txcnt = 0;
	txlen = cnt;
	endflag = 0;

	/* I2C function to write data to slave */
	i2c0handlerflag = (I2C_FUNC)I2C_MasterTx;

	/* I2C as master sends START signal */
	I2C_SET_CONTROL_REG(I2C0, I2C_CTL_STA);

	/* Wait I2C Tx Finish */
	while(endflag == 0);
	endflag = 0;

}
/*******************************************************************************
* Function Name  : main
* Description    : 主程序
* Input          : None
* Output         : None
* Return         : None
*******************************************************************************/
int main(void)
{
	/* Unlock protected registers */
	SYS_UnlockReg();
	SYS_Init();
	/* Lock protected registers */
	SYS_LockReg();
	
	//配置PC15脚为PWM输出，频率32K
	//Set Pwm mode as complementary mode
	PWM_ENABLE_COMPLEMENTARY_MODE(PWM1);
	PWM_ConfigOutputChannel(PWM1, 0,32000, 50);//PWM频率32KHz，用做OSCI脚时钟
	// Enable output of PWM1 channel 0
	PWM_EnableOutput(PWM1, PWM_CH_0_MASK|PWM_CH_1_MASK);
	PWM_Start(PWM1, 0x1);	
	
	//硬件I2C配置，IO脚模拟I2C时屏蔽下面语句
	//配置PD5(SCL),PD4(SDA)脚为硬件I2C,频率100khz
	/* Open I2C module and set bus clock */
	I2C_Open(I2C0, 20000);  //100khz/30000
	/* Set I2C Slave Addresses */
	I2C_SetSlaveAddr(I2C0, 0, VK16D32A_ADDR, 0);   /* Slave Address : 0x15 */
	/* Enable I2C interrupt */
	I2C_EnableInt(I2C0);
	NVIC_EnableIRQ(I2C0_IRQn);
//		
	VK16D32A_Main();
	
	while(1)
	{					
	}
}	
/************************END OF FILE****/

