C언어,ARM

i2c - AT24C16

안녕1999 2020. 2. 15. 23:33

 

 

#include "..\src\sI2C.h"
#include "..\src\cpu.h"
#ifndef I2C_MSB_first
	#define I2C_MSB_first
#endif

#ifdef I2C_MSB_first
	#define for_loop8(i)	for(i=7;i>=0;i--)
#else
	#define for_loop8(i)	for(i=0;i<=7;i++)
#endif

#ifndef SCL_H
	#define SCL_H()	I2C_CLK_H()
	#define SCL_L()	I2C_CLK_L()
#endif

#ifndef SDA_H
	#define SDA_H()	I2C_DATA_H()
	#define SDA_L()	I2C_DATA_L()
#endif


void SCL_set_IN(void)
{
	GPIO_InitTypeDef GPIO_InitStruct;

	//GPIO-IN
	GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
	GPIO_InitStruct.Pull = GPIO_PULLUP;
	GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
	
	GPIO_InitStruct.Pin = GPIO_PIN_9;//I2C_CLK
	HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
}
void SCL_set_OUT(void)
{
	GPIO_InitTypeDef GPIO_InitStruct;
	
	//GPIO-OUT
	GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
	GPIO_InitStruct.Pull = GPIO_PULLUP;
	GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
	
	GPIO_InitStruct.Pin = GPIO_PIN_9;//I2C_CLK
	HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
}
void SDA_set_IN(void)
{
	GPIO_InitTypeDef GPIO_InitStruct;

	//GPIO-IN
	GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
	GPIO_InitStruct.Pull = GPIO_PULLUP;
	GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
	
	GPIO_InitStruct.Pin = GPIO_PIN_2;//I2C_DATA
	HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
}
void SDA_set_OUT(void)
{
	GPIO_InitTypeDef GPIO_InitStruct;

	//GPIO-OUT
	GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
	GPIO_InitStruct.Pull = GPIO_PULLUP;
	GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
	
	GPIO_InitStruct.Pin = GPIO_PIN_2;//I2C_DATA
	HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
}
extern void delay_us(int n);
extern void delay_nsec(byte1 n);

void I2C_delay(void)
{
	delay_nsec(1);
}
void sI2C_init(void)
{
	//DEBUG_UART_puts_rn("sI2C_init()");
	SCL_set_OUT();
	SDA_set_OUT();
	SCL_H();
	SDA_H();
	I2C_delay();
}
void sI2C_START(void)
{
	//DEBUG_puts("sI2C_START()");
	sI2C_init();

	SDA_L();
	I2C_delay();
	SCL_L();
	I2C_delay();
}
void sI2C_STOP(void)
{
	SDA_L();
	I2C_delay();
	SCL_H();
	I2C_delay();

	SDA_H();
	I2C_delay();
	//DEBUG_puts("sI2C_STOP()");
}
int sI2C_read_ACK(void)
{
	int bok;
	//DEBUG_puts("sI2C_read_ACK()");
	SDA_H();
	I2C_delay();
	SDA_set_IN();
		SCL_H();
			I2C_delay();
			bok=SDA_get();
		SCL_L();
		I2C_delay();
	SDA_set_OUT();
	SDA_H();
	//DEBUG_puts_int("ACK(0)/NACK(1)",bok);
	return bok;
}
void sI2C_SCL_H_L(void)
{
	//DEBUG_UART_puts_rn("sI2C_SCL_H_L()");
	SCL_H();
	I2C_delay();
	SCL_L();
	I2C_delay();
}
int sI2C_wait_ACK(void)
{
	//DEBUG_UART_puts_rn("DEBUG : sI2C_wait_ACK()=ACK");
	//return 0;//DEBUG 무조건 ACK
	
	int bok=0,n=0x0fff;
	//DEBUG_UART_puts_rn("sI2C_wait_ACK()");
	//DEBUG_printf(("sI2C_wait_ACK()"));
	SDA_H();
	//I2C_delay();
	SDA_set_IN();
		while(n--)
		{
			I2C_delay();
			bok=SDA_get();
			//bok=0;//DEBUG 무조건 ACK
			if(bok==0)
			{
				//ACK(OK)
				break;
			}
		}
		//_UART_HEX_puts(&n,sizeof(n),"sI2C_wait_ACK(n)");
		sI2C_SCL_H_L();
	SDA_set_OUT();
	SDA_H();
	//DEBUG_UART_puts_rn("sI2C_wait_ACK() END");
	//return 0;//DEBUG 무조건 ACK
	return bok;
}
void sI2C_write_1bit(int a)
{
	//DEBUG_UART_puts_rn("sI2C_write_1bit()");
	if(a)
	{
		SDA_H();
		//DEBUG_UART_puts_rn("SDA_H()");
	}
	else
	{
		SDA_L();
		//DEBUG_UART_puts_rn("SDA_L()");
	}
	I2C_delay();
	sI2C_SCL_H_L();
	
	//SDA 기본상태는 L
	I2C_delay();
	SDA_L();
}
#define write_ACK(psI2C)	sI2C_write_1bit(0)
#define write_NACK(psI2C)	sI2C_write_1bit(1)

byte1 sI2C_read_byte(int ack)
{
	int i;
	byte1 a=0;
	//DEBUG_UART_puts_rn("sI2C_read_byte()");
	//DEBUG_printf(("sI2C_read_byte()"));
	SDA_H();
	SDA_set_IN();
		for_loop8(i)
		{
			I2C_delay();
			SCL_H();
			I2C_delay();
				a|=(SDA_get()<<i);
			SCL_L();
			I2C_delay();
		}
	SDA_set_OUT();
	sI2C_write_1bit(ack);
	//DEBUG_printf(("sI2C_read_byte()=%d(0x%X) ACK=%d\r\n",a,a,ack));
	//_UART_HEX_puts(&a,sizeof(a),"sI2C_read_byte()");
	//DEBUG_puts_int("sI2C_read_byte() END a",a);
	return a;
}
void sI2C_read(byte1 *pbuf,int len)
{
	int rlen=len;
	byte1 *p=pbuf;
	//DEBUG_UART_puts_rn("sI2C_read() START");
	while(len--)
	{
		*p=sI2C_read_byte(len==0);
		p++;
	}
	//UART3_send_value_HEX("sI2C_read",pbuf,rlen);//DEBUG
	//DEBUG_UART_puts_rn("sI2C_read() END");
	//DEBUG_HEX_puts("sI2C_read",pbuf,rlen);//DEBUG
}
void sI2C_write_byte(byte1 a)
{
	int i;
	//DEBUG_UART_puts_rn("sI2C_write_byte()");
	//_UART_HEX_puts(&a,sizeof(a),"sI2C_write_byte");
	//DEBUG_printf(("sI2C_write_byte=%d(0x%X)",a,a));
	for_loop8(i)
	{
		if(gbi(a,i))
		{
			SDA_H();
		}
		else
		{
			SDA_L();
		}
		I2C_delay();
		sI2C_SCL_H_L();
	}
}
int sI2C_write(byte1 *pbuf,int len)
{
	byte1 *p=pbuf;
	int wlen=0;
	//DEBUG_UART_puts_rn("sI2C_write()");
	//DEBUG_puts_int("len",len);
	//WDT_reset();//DEBUG
	while(len--)
	{
		sI2C_write_byte(*p);
		//ACK
		if(sI2C_wait_ACK())
		{
			//DEBUG_puts("ERR : sI2C_wait_ACK");//DEBUG
			break;//err
		}
		else
		{
			//ok
		}
		wlen++;
		p++;
	}
	//SDA_H();
	//UART3_send_value_HEX("sI2C_write()1",pbuf,wlen);//DEBUG
	//DEBUG_HEX_puts("sI2C_write",pbuf,wlen);//DEBUG
	return wlen;
}
int sI2C_write_START_device_addr1(byte1 device,byte1 addr1)
{
	//DEBUG_UART_puts_rn("sI2C_write_START_device_addr1()");
	sI2C_START();
		sI2C_write(&device,1);
		sI2C_write(&addr1,1);
	return 1;
}
int sI2C_write_START_device_addr1_STOP(byte1 device,byte1 addr1)
{
	int bok;
	//DEBUG_UART_puts_rn("sI2C_write_START_device_addr1_STOP()");
	bok=sI2C_write_START_device_addr1(device,addr1);
	sI2C_STOP();
	return bok;
}