/***********************************************************************
 * Copyright (c)  2017 - 2022, Unicmicro Co.,Ltd .
 * All rights reserved.
 * Filename    : i2c0_master.h
 * Description : i2c0_master driver header file
 * Author(s)   : Chloe
 * version     : V1.0
 * Modify date : 2019-05-21
 ***********************************************************************/
#ifndef __I2C_H__
#define __I2C_H__

#include  "um321xF.h"


//建议：master用查询，slave中断查询均可；
//#define I2C_Tx_INT_MODE	
//#define I2C_Rx_INT_MODE

#define I2C_IRQ_DISABLE      0
#define I2C_IRQ_ENABLE       1

#define I2C_READ 	  (1<<0)
#define I2C_WRITE 	(0<<0)

//0x10000:20ms, 0x8000:10ms, 0x4000:5ms,
#define I2C_TIMEOUT	0x4000   

#define I2C_NACK  //最后一个字节发NAK

/*  
	10bit or 7bit address mode switch
	10bit: please note this macro
*/
#define I2C_7BIT_ADDR                  								    

#ifdef I2C_7BIT_ADDR
  // scope 0x00~0x7F
	#define I2C_SLAVE_ADDR 		0x12   	//7bit slave address
	#define I2C_SLAVE_ADDR1     0x34
	#define I2C_SLAVE_ADDR2  	0x56
	#define I2C_SLAVE_ADDR3  	0x78
#else
  #define I2C_SLAVE_ADDR    0x123	 //10bit slave address
#endif

//SYSCFG REG (PERI_CLKEN) I2C 时钟选择(test)
#define I2C_CLKEN  	            			(uint32_t)(0x1<<15)
			
//I2C复位(test)			
#define I2C_RESET  	            			(uint32_t)(0x1<<15)
			
//Slave Addr广播地址应答使能			
#define I2C_SAD_GC  	           			(uint32_t)(1<<0)

/*------------REG I2C_CR----------------*/
#define I2C_CR_GCAVAL  	           		    (uint32_t)(1<<8)		//General Call使能
#define I2C_CR_IEN  	           			(uint32_t)(1<<7)		//I2C中断使能
#define I2C_CR_ENAB  	           			(uint32_t)(1<<6)		//I2C模块从模式使能位
#define I2C_CR_STA  	           			(uint32_t)(1<<5)		//发送START标志
#define I2C_CR_STP  	           			(uint32_t)(1<<4)		//发送STOP标志
#define I2C_CR_IFLG  	           			(uint32_t)(1<<3)		//中断标志位
#define I2C_CR_AAK  	           			(uint32_t)(1<<2)		//发送ACK标志
#define I2C_CR_SLAV10M  	       			(uint32_t)(1<<1)		//从模式时，收到的数据与SLAVE拓展地址寄存器中的数值相匹配
#define I2C_CR_SLAV7M	  	       			(uint32_t)(1<<0)		//从模式时，收到的数据与SLAVE地址寄存器中的数值相匹配


/*------------REG I2C_STAT----------------*/
#define I2C_STA_START_BIT_SENT  	    	(uint8_t)(0x08)			//已发送START
#define I2C_STA_RESTART_BIT_SENT  	    	(uint8_t)(0x10)			//已发送RESTART
#define I2C_STA_TX_ADDR_W_ACK 	         	(uint8_t)(0x18)			//已发送SLAVE地址加写标志，并接收ACK
#define I2C_STA_TX_ADDR_W_NAK 	         	(uint8_t)(0x20)			//已发送SLAVE地址加写标志，并接收NACK
#define I2C_STA_TX_DATA_ACK   	         	(uint8_t)(0x28)         //已发送I2C_DATA中的数据，已接收ACK
#define I2C_STA_TX_DATA_NAK  	         	(uint8_t)(0x30)
#define I2C_STA_ID_LOST  	         		(uint8_t)(0x38)
#define I2C_STA_TX_ADDR_R_ACK 	         	(uint8_t)(0x40)			//已发送SLAVE地址加读标志，并接收ACK
#define I2C_STA_TX_ADDR_R_NAK 	         	(uint8_t)(0x48)			//已发送SLAVE地址加读标志，并接收NACK
#define I2C_STA_RX_DATA_ACK  	        	(uint8_t)(0x50)
#define I2C_STA_RX_DATA_NAK  	        	(uint8_t)(0x58)
#define I2C_STA_SLAVE_RX_DEVADDRW_ACK     	(uint8_t)(0x60)
#define I2C_STA_SLAVE_RX_DEVADDR_ACK      	(uint8_t)(0x68)
#define I2C_STA_SLAVE_RX_ADDR0			    (uint8_t)(0x70)
#define I2C_STA_SLAVE_RX_ADDR0W	      		(uint8_t)(0x78)
#define I2C_STA_SLAVE_LRX_ADDR_ACK			(uint8_t)(0x80)
#define I2C_STA_SLAVE_LRX_ADDR_NAK	      	(uint8_t)(0x88)
#define I2C_STA_SLAVE_LRX_ADDR0_ACK		    (uint8_t)(0x90)
#define I2C_STA_SLAVE_LRX_ADDR0_NAK      	(uint8_t)(0x98)
#define I2C_STA_SLAVE_RX_STP_RSTA      		(uint8_t)(0xA0)
#define I2C_STA_SLAVE_RX_ADDR_ACK      		(uint8_t)(0xA8)
#define I2C_STA_SLAVE_RX_ADDR0R		    	(uint8_t)(0xB0)
#define I2C_STA_SLAVE_TX_DATA_ACK	    	(uint8_t)(0xB8)
#define I2C_STA_SLAVE_TX_DATA_NAK	    	(uint8_t)(0xC0)
#define I2C_STA_SLAVE_TX_BYTE_ACK	    	(uint8_t)(0xC8)
#define I2C_STA_SECOND_ADD_ACK				(uint8_t)(0xe0)
#define I2C_STA_SECOND_ADD_NAK				(uint8_t)(0xe8)


typedef enum
{
    I2C_SPEED_STAD = 0,
    I2C_SPEED_FAST,
    I2C_SPEED_HIGH
}i2c_speed_typedef;


/************************************************************************
 * function   : i2c_master_init
 * Description: i2c pin init, config interruption
 * input : 
			uint8_t speed:  i2c SCL clk
 * return: none
 ************************************************************************/
void i2c_master_init( uint8_t speed );

/************************************************************************
 * function   : i2c_master_send
 * Description: i2c master send data by commond mode
 * input      : 
			    uint16_t slave_addr: slave device address 
			    uint8_t *buff      : data buff
			    uint32_t length    : data length
 * return     :  
                0: error， 1: OK  
 ************************************************************************/
uint8_t i2c_master_send(uint16_t slave_addr, uint8_t *buff, uint32_t length);

/************************************************************************
 * function   :  i2c_master_recv
 * Description:  i2c_master receive data
 * input      : 
			    uint16_t slave_addr: slave device address 
			    uint8_t       *buff: data buff
			    uint32_t     length: data length
 * return     :  
                 0: error， 1: OK  
 ************************************************************************/
uint8_t i2c_master_recv(uint16_t slave_addr, uint8_t *buff, uint32_t length);

/************************************************************************
 * function   : i2c_master_send_mix
 * Description: i2c master send data by mix mode （针对需要单独发memory地址的设备，如I2C EEPROM设备）
 * input      : 
				uint16_t slave_addr: slave device address 
				uint32_t write_addr：write address
				uint8_t    addr_num：addre size（eg：1,2,3,4）
			    uint8_t        buff: data buff
			    uint32_t     length: data length
 * return     :  
                0: error， 1: OK  
 ************************************************************************/
uint8_t i2c_master_send_mix(uint16_t slave_addr, uint32_t* write_addr, uint8_t addr_num, uint8_t *buff, uint32_t length);

/************************************************************************
 * function   : i2c_master_receive_mix
 * Description: i2c_master receive data （针对需要单独发memory地址的设备，如I2C EEPROM设备）
 * input 	: 
				uint16_t slave_addr: slave device address 
				uint32_t read_addr ：read address
				uint8_t addr_num   ：addre size（eg：0,1,2,3,4）
				uint8_t *buff      : data buff
				uint32_t length    : data length
 * return	:  
				0: error，
				1: OK  
 ************************************************************************/
uint8_t i2c_master_recv_mix(uint16_t slave_addr, uint32_t* read_addr, uint8_t addr_num, uint8_t *buff, uint32_t length);

#endif

