374 lines
7.1 KiB
C
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();
|
|
}
|
|
*/
|