Files
FireAlarmCtrlCn/FW/Core/my_src/I2C_eeprom.c
2026-04-06 19:02:09 +08:00

374 lines
7.1 KiB
C

#include "main.h"
#include "I2C_eeprom.h"
//--------------------------724KHz-----------------sys:480MHz--------stm32H743-----------------
#define I2C_ADDR_READ 0xA1
#define I2C_ADDR_WRITE 0xA0
#define I2C_WP_PT() LL_GPIO_SetOutputPin(GPIOD,LL_GPIO_PIN_11)
#define I2C_WP_UNPT() LL_GPIO_ResetOutputPin(GPIOD,LL_GPIO_PIN_11)
#define I2C_SCL_HI() LL_GPIO_SetOutputPin(GPIOD,LL_GPIO_PIN_12)
#define I2C_SCL_LO() LL_GPIO_ResetOutputPin(GPIOD,LL_GPIO_PIN_12)
#define I2C_SDA_HI() LL_GPIO_SetOutputPin(GPIOD,LL_GPIO_PIN_13)
#define I2C_SDA_LO() LL_GPIO_ResetOutputPin(GPIOD,LL_GPIO_PIN_13)
#define SDA_VALUE() ((0x2000 & GPIOD->IDR)>>13)
static volatile unsigned short delay_4_pgm;
static volatile unsigned char delay_x_tick;
static void delay_x(void)
{
for(delay_x_tick=0;delay_x_tick<16;delay_x_tick++);
}
static void I2C_SCL_hi(void)
{
I2C_SCL_HI();delay_x();
}
static void I2C_SCL_lo(void)
{
I2C_SCL_LO();delay_x();
}
static void I2C_SDA_hi(void)
{
I2C_SDA_HI();delay_x();
}
static void I2C_SDA_lo(void)
{
I2C_SDA_LO();delay_x();
}
static void wait(void)
{
__nop();
__nop();
__nop();
__nop();
}
static void I2C_start(void)
{
I2C_SCL_lo(); //SCL low
wait();
I2C_SDA_lo(); //SDA low
wait();
I2C_SDA_hi(); //SDA high
wait();
I2C_SCL_hi(); //SCL high
wait();
I2C_SDA_lo(); //SDA goes low before the clock
wait();
I2C_SCL_lo(); //SCL low
wait();
}
static void I2C_stop(void)
{
I2C_SDA_lo(); //SDA low
wait();
I2C_SCL_hi(); //SCL high
wait();
I2C_SDA_hi(); //SDA goes from low to high when SCL is already high,
wait();
}
static unsigned char I2C_send_byte(unsigned char bb)
{
unsigned int i;
unsigned char noack;
unsigned char b,s;
b=bb;
for (i=8; i>0; i--)
{
I2C_SCL_lo(); //Reset SCL
wait();
s = b >> 7; //Send data to SDA pin
if(1==(s & 0x01))I2C_SDA_hi();else I2C_SDA_lo();
wait();
I2C_SCL_hi(); //Set SCL
wait();
I2C_SCL_lo(); //Reset SCL
wait();
b<<=1; //Rotate data
}
I2C_SDA_hi();
I2C_SCL_lo(); //Reset SCL
wait();
I2C_SCL_hi(); //Set SCL
wait();
delay_x();
delay_x();
noack = SDA_VALUE(); //Check SDA for ACKN
wait();
I2C_SCL_lo();
wait();
I2C_SDA_lo();
wait();
return(noack);
}
static unsigned char I2C_read_byte(unsigned char ackn)
{
unsigned int i;
unsigned char ReceivedByte;
ReceivedByte=0x0000;
I2C_SDA_hi(); //Make SDA an input
I2C_SCL_lo(); //Reset SCL
for (i=8; i>0; i--)
{
wait();
I2C_SCL_hi(); //Set SCL
ReceivedByte <<= 1; //Rotate data
ReceivedByte |= SDA_VALUE(); //Read SDA -> data
wait();
I2C_SCL_lo(); //Reset SCL
wait();
}
if(0==ackn)I2C_SDA_lo();else I2C_SDA_hi(); //SDA = ACK bit
wait();
I2C_SCL_hi(); //Set SCL
wait();
I2C_SCL_lo(); //Reset SCL
wait();
return(ReceivedByte);
}
unsigned int I2C_byte_write_via_page(unsigned int chip_cs, unsigned int addr, unsigned char *p, unsigned int len)
{
unsigned int i;
unsigned char data;
unsigned char addr_hi,addr_lo;
unsigned int i2c_page_size;
unsigned char i2c_addr_write_cmd;
unsigned char offset;
if(chip_cs){
i2c_page_size = I2C_PAGE_SIZE_24M01;
}else{
i2c_page_size = I2C_PAGE_SIZE_24512;
}
offset = addr & (i2c_page_size - 1);
if((offset + len) > i2c_page_size)return 1;
if(chip_cs)i2c_addr_write_cmd = I2C_ADDR_WRITE | 0x08 | ((addr&0x00010000)>>15);
else i2c_addr_write_cmd = I2C_ADDR_WRITE;
I2C_WP_UNPT();
addr_hi = (unsigned char)(addr >> 8);
addr_lo = (unsigned char)(addr);
I2C_start();
if(!I2C_send_byte(i2c_addr_write_cmd))
{
if(!I2C_send_byte(addr_hi))
{
if(!I2C_send_byte(addr_lo))
{
for(i=0;i<len;i++)
{
data=*p;
I2C_send_byte(data);
p++;
}
}else return 1;
}else return 1;
}else return 1;
I2C_stop();
//for(delay_4_pgm = 0; delay_4_pgm < 8000; delay_4_pgm++);
I2C_WP_PT();
return 0;
}
unsigned int I2C_page_write(unsigned int chip_cs, unsigned int addr, unsigned char *p)
{
unsigned int i;
unsigned char data;
unsigned char addr_hi,addr_lo;
unsigned int i2c_page_size;
unsigned char i2c_addr_write_cmd;
if(chip_cs){
i2c_page_size = I2C_PAGE_SIZE_24M01;
addr_hi = (unsigned char)(addr >> 8);
addr_lo = 0;
}else{
i2c_page_size = I2C_PAGE_SIZE_24512;
addr_hi = (unsigned char)(addr >> 8);
addr_lo = (unsigned char)(addr & 0x80);
}
if(chip_cs)i2c_addr_write_cmd = I2C_ADDR_WRITE | 0x08 | ((addr&0x00010000)>>15);
else i2c_addr_write_cmd = I2C_ADDR_WRITE;
I2C_WP_UNPT();
I2C_start();
if(!I2C_send_byte(i2c_addr_write_cmd))
{
if(!I2C_send_byte(addr_hi))
{
if(!I2C_send_byte(addr_lo))
{
for(i=0;i<i2c_page_size;i++)
{
data=*p;
I2C_send_byte(data);
p++;
}
}else return 1;
}else return 1;
}else return 1;
I2C_stop();
//for(delay_4_pgm = 0; delay_4_pgm < 8000; delay_4_pgm++);
I2C_WP_PT();
return 0;
}
unsigned int I2C_page_read(unsigned int chip_cs, unsigned int addr, unsigned char *p, unsigned int len)
{
unsigned int i;
unsigned char addr_hi,addr_lo;
unsigned int i2c_page_size;
unsigned int chip_size;
unsigned char i2c_addr_write_cmd;
unsigned char i2c_addr_read_cmd;
if(chip_cs){
i2c_page_size = I2C_PAGE_SIZE_24M01;
chip_size = I2C_CHIP_SIZE_24M01;
}else{
i2c_page_size = I2C_PAGE_SIZE_24512;
chip_size = I2C_CHIP_SIZE_24512;
}
if((addr + len) > chip_size)return 1;
if(chip_cs){
i2c_addr_write_cmd = I2C_ADDR_WRITE | 0x08 | ((addr&0x00010000)>>15);
i2c_addr_read_cmd = I2C_ADDR_READ | 0x08 | ((addr&0x00010000)>>15);
}else{
i2c_addr_write_cmd = I2C_ADDR_WRITE;
i2c_addr_read_cmd = I2C_ADDR_READ;
}
addr_hi = (unsigned char)(addr >> 8);
addr_lo = (unsigned char)(addr);
I2C_start();
if(!I2C_send_byte(i2c_addr_write_cmd))
{
if(!I2C_send_byte(addr_hi))
{
if(!I2C_send_byte(addr_lo))
{
I2C_stop();
I2C_start();
I2C_send_byte(i2c_addr_read_cmd);
for(i=0;i<len;i++)
{
if(i<(len - 1))
{
*p=I2C_read_byte(0);
}
else
{
*p=I2C_read_byte(1);
}
p++;
}
}else return 1;
}else return 1;
}else return 1;
I2C_stop();
return 0;
}
/*
void I2C_page_write(unsigned int page_addr, unsigned char *p)
{
unsigned int i;
unsigned char data;
unsigned char addr_hi,addr_lo;
I2C_WP_UNPT();
addr_hi = (unsigned char)(page_addr >> 8);
addr_lo = (unsigned char)(page_addr&0xFF);
I2C_start();
if(!I2C_send_byte(I2C_addr_write))
{
if(!I2C_send_byte(addr_hi))
{
if(!I2C_send_byte(addr_lo))
{
for(i=0;i<I2C_PAGE_SIZE;i++)
{
data=*p;
I2C_send_byte(data);
p++;
}
}
}
}
I2C_stop();
for(delay_4_pgm = 0; delay_4_pgm < 8000; delay_4_pgm++);
I2C_WP_PT();
}
void I2C_page_read(unsigned int page_addr, unsigned char *p)
{
unsigned char i;
unsigned char addr_hi,addr_lo;
addr_hi = (unsigned char)(page_addr >> 8);
addr_lo = (unsigned char)(page_addr&0xFF);
I2C_start();
if(!I2C_send_byte(I2C_addr_write))
{
if(!I2C_send_byte(addr_hi))
{
if(!I2C_send_byte(addr_lo))
{
I2C_stop();
I2C_start();
I2C_send_byte(I2C_addr_read);
for(i=0;i<I2C_PAGE_SIZE;i++)
{
if(i<(I2C_PAGE_SIZE - 1))
{
*p=I2C_read_byte(0);
}
else
{
*p=I2C_read_byte(1);
}
p++;
}
}
}
}
I2C_stop();
}
*/