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

#include  "um321xF.h" 

//建议：master TX/RX均用查询，slave RX中断/查询均可，TX查询；
//#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)			//主机模式下，已发送I2C_DATA 中的数据，接收到NAK 
#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)			//主机模式下，已接收数据字节，ACK已发出
#define I2C_STA_RX_DATA_NAK  	        	(uint8_t)(0x58)			//主机模式下，已接收数据字节，NAK已发出
#define I2C_STA_SLAVE_RX_DEVADDRW_ACK    	(uint8_t)(0x60)			//已接收自身的SLAVE寄存器地址加W标志，ACK已发出。
#define I2C_STA_SLAVE_RX_DEVADDR_ACK      	(uint8_t)(0x68)			//作为主机时，丢失掉仲裁，并且以接收到自身的SLAVE寄存器地址加W标志，ACK已发出。
#define I2C_STA_SLAVE_RX_ADDR0			    (uint8_t)(0x70)			//已接收通用调用地址（0x00）；已发出ACK；
#define I2C_STA_SLAVE_RX_ADDR0W	      		(uint8_t)(0x78)			//作为主机时，丢失掉仲裁，并且已接收到通用调用地址加W标志，ACK已发出。
#define I2C_STA_SLAVE_LRX_ADDR_ACK			(uint8_t)(0x80)			//在接收到自身从地址后，接收到数据字节，已返回ACK
#define I2C_STA_SLAVE_LRX_ADDR_NAK	      	(uint8_t)(0x88)			//在接收到自身从地址后，接收到数据字节，已返回NAK
#define I2C_STA_SLAVE_LRX_ADDR0_ACK		    (uint8_t)(0x90)			//在接收到通用调用地址后，接收到数据字节，已返回ACK
#define I2C_STA_SLAVE_LRX_ADDR0_NAK      	(uint8_t)(0x98)			//在接收到通用调用地址后，接收到数据字节，已返回NAK
#define I2C_STA_SLAVE_RX_STP_RSTA      		(uint8_t)(0xA0)			//从机模式下，接收到停止条件或重复起始条件
#define I2C_STA_SLAVE_RX_ADDR_ACK      		(uint8_t)(0xA8)			//已接收自身的从地址加R标志；已返回ACK 
#define I2C_STA_SLAVE_RX_ADDR0R		    	(uint8_t)(0xB0)			//作为主机时，丢失掉仲裁，并且已接收到通用调用地址加R标志，ACK已发出。
#define I2C_STA_SLAVE_TX_DATA_ACK	    	(uint8_t)(0xB8)			//从机模式下（AAK=1），已发送数据；已收到ACK
#define I2C_STA_SLAVE_TX_DATA_NAK	    	(uint8_t)(0xC0)			//从机模式下（AAK=1），已发送数据；已收到NAK
#define I2C_STA_SLAVE_TX_BYTE_ACK	    	(uint8_t)(0xC8)			//从机模式下（AAK=0），已发送最后一个字节数据，已收到ACK
#define I2C_STA_SECOND_ADD_ACK				(uint8_t)(0xe0)			//从机模式下（AAK=0），已发送最后一个字节数据，已收到NAK
#define I2C_STA_SECOND_ADD_NAK				(uint8_t)(0xe8)			//已发送10位SLAVE第二段地址+W，接收到ACK


/************************************************************************
 * function   : i2c_slave_mixrecv_data_polling
 * Description: i2c从机接收处理函数,查询模式 ，如果不知道数据长度，可以输入一个很大的值，比如；256
 * input      : 
			           uint8_t *buff  : data buffer
			           uint32_t length: receive data length , （传入的length可能大于master实际发送的数据长度）
 * return     : 
                 0: error， 1: OK  
 ************************************************************************/
uint8_t i2c_slave_mixrecv_data(uint8_t addr_len, uint8_t *buff, uint32_t data_len);

/************************************************************************
 * function   : i2c_slave_mixsend_data
 * Description: i2c从机发送处理函数 for (模拟EEPROM的角色示例)
 * input      : 
			          uint8_t *buff  : data buffer
			          uint32_t length: receive data length      
 * return     : status
 ************************************************************************/
uint8_t i2c_slave_mixsend_data(uint8_t addr_len, uint32_t data_len);

/************************************************************************
 * function   : i2c_slave_recv_data_polling
 * Description: i2c从机接收处理函数,查询模式 ，如果不知道数据长度，可以输入一个很大的值，比如；256
 * input      : 
			           uint8_t *buff  : data buffer
			           uint32_t length: receive data length , （传入的length可能大于master实际发送的数据长度）
 * return     : 
                 0: error， 1: OK  
 ************************************************************************/
uint8_t i2c_slave_recv_data(uint8_t *buff, uint32_t length);

/************************************************************************
 * function   : i2c_slave_send_data
 * Description: i2c从机发送处理函数
 * input      : 
			          uint8_t *buff  : data buffer
			          uint32_t length: send data length      
 * return     : status
 ************************************************************************/
uint8_t i2c_slave_send_data(uint8_t *buff, uint32_t length);

/************************************************************************
 * function   : i2c_read_byte
 * Description: i2c_read_byte
 * input : none
 * return: rdata: 接收数据（1 Byte）
 ************************************************************************/
uint8_t i2c_read_byte(void);

/************************************************************************
 * function   : i2c_irq_init
 * Description: i2c interrupt enable
 * input : 
 *         uint8_t irqstate: 0 interrupt diable ，1 interrupt enable
 * 		   void (*pfunc_rec)(): receive callback function
 *		   void (*pfunc_send)() send callback function
 * return: none
 ************************************************************************/
void i2c_irq_init(uint8_t irqstate, void (*pfunc_rec)(), void (*pfunc_send)());

/************************************************************************
 * function   : i2c_init
 * Description: i2c pin init, config interruption
 * input : device type: slave or master
 * return: none
 ************************************************************************/
void i2c_slave_init(void);

#endif

