Files
TSCP/TSCP/src/DRV/imx8_drv_i2c.c
T

773 lines
13 KiB
C

#include "imx8_drv_i2c.h"
static int fd_i2c_1;
static int fd_i2c_8;
static int fd_sc;
static imx_dcmd_sc_misc_temp_t cpu_temp;
int16_t temperature_read(int fd, uint8_t reg, uint8_t slave_addr)
{
uint8_t v1, v2;
uint16_t val = (uint16_t)0;
struct send_recv
{
i2c_sendrecv_t hdr;
uint8_t buf[2];
} read;
read.buf[0] = reg ;
read.hdr.send_len = (uint32_t)1;
read.hdr.recv_len = (uint32_t)2;
read.hdr.slave.addr = slave_addr;
read.hdr.slave.fmt = (uint32_t)I2C_ADDRFMT_7BIT;
read.hdr.stop = (uint32_t)1;
if((devctl(fd, DCMD_I2C_SENDRECV, (void *)&read, sizeof(read),(int *)NULL)) > 0)
{
perror("Failed to read to temp ! ");
}
else
{
}
v1 = read.buf[0];
v2 = read.buf[1];
if(slave_addr == (uint8_t)0x48)
{
val = (v1 << 4) | (v2 >> 4);
}
else
{
}
if(slave_addr == (uint8_t)0x49)
{
val = v2 | (uint16_t)((uint16_t)v1 << 8);
}
else
{
}
return val;
}
int eeprom_read_data(int fd, uint32_t regaddr, uint8_t rx_buf[],uint32_t len,uint8_t slave_addr)
{
int i = 0,ret = 0;
struct send_recv
{
i2c_sendrecv_t hdr;
uint8_t buf[128];
} eeprom_read;
/* Read the Registers Current Value */
eeprom_read.buf[0] = (uint8_t)((regaddr >> 8) & 0xFFUL);
eeprom_read.buf[1] = (uint8_t)(regaddr & 0xFFUL);
eeprom_read.hdr.send_len = (uint32_t)2;
eeprom_read.hdr.recv_len = (uint32_t)len ;
eeprom_read.hdr.slave.addr = slave_addr;
eeprom_read.hdr.slave.fmt = (uint32_t)I2C_ADDRFMT_7BIT;
eeprom_read.hdr.stop = (uint32_t)1;
ret = devctl(fd, (uint32_t)DCMD_I2C_SENDRECV, (void*)&eeprom_read,sizeof(eeprom_read),(int *)NULL);
if(ret > 0)
{
perror("eeprom read i2c error ");
}
else
{
}
for(i = 0; i < (int32_t)len; i++)
{
rx_buf[i] = eeprom_read.buf[i];
}
return ret;
}
int eeprom_write_data(int fd, uint32_t regaddr, uint8_t tx_buf[],uint32_t len,uint8_t slave_addr)
{
int ret = 0,i = 0;
struct send_recv
{
i2c_sendrecv_t hdr;
uint8_t buf[2 + 128];
} eeprom_write;
/*Read the Registers Current Value */
eeprom_write.buf[0] = (uint8_t)((regaddr >> 8) & 0xFFUL);
eeprom_write.buf[1] = (uint8_t)(regaddr & 0xFFUL);
for(i = 0; i < (int32_t)len; i++)
{
eeprom_write.buf[2 + i] = tx_buf[i];
}
eeprom_write.hdr.send_len = (uint32_t)2 + len;
eeprom_write.hdr.recv_len = (uint32_t)0;
eeprom_write.hdr.slave.addr = slave_addr;
eeprom_write.hdr.slave.fmt = (uint32_t)I2C_ADDRFMT_7BIT;
eeprom_write.hdr.stop = (uint32_t)1;
ret = devctl(fd, (uint32_t)DCMD_I2C_SENDRECV, &eeprom_write, sizeof(eeprom_write),NULL);
if(ret > 0)
{
}
else
{
}
return ret;
}
int imx8_i2c_init(void)
{
fd_i2c_1 = open(I2C_1, O_RDWR);
if(fd_i2c_1 == -1)
{
perror("can't open I2C1\n");
}
else
{
}
fd_i2c_8 = open(I2C_8, O_RDWR);
if(fd_i2c_8 == -1)
{
perror("can't open I2C8\n");
}
else
{
}
return 0;
}
int imx8_cpu_temp_init(void)
{
int ret = 0;
fd_sc = open(SC_TEMP, O_RDWR);
if(fd_sc == -1)
{
ret = -1;
perror("can't open sc");
}
else
{
}
return ret;
}
int imx8_read_cpu_temp(void)
{
devctl(fd_sc, 0xc00c0557U, &cpu_temp, sizeof(cpu_temp),0);
return cpu_temp.celsius;
}
/*There are 4 eeproms, one is in board,the other is out board,8R 12R switchboard
* the first parameter must write EEPROM_IN_BOARD,or EEPROM_OUT_BOARD,define in imx8_drv_i2c.h*/
int imx8_write_eeprom(int board,uint8_t tx_buf[], unsigned int len)
{
int division = 0,modular = 0,ret = 0;
int i;
if((len > (uint32_t)65536) || (len < (uint32_t)0) || (tx_buf == NULL))
{
perror("wrong para");
ret = -1;
}
else
{
switch(board)
{
case EEPROM_IN_BOARD:
if(len <= (uint32_t)128)
{
ret = eeprom_write_data(fd_i2c_1,0x0U,tx_buf,len,(uint8_t)I2C_1_EEPROM_ADDR);
}
else
{
}
if(len > (uint32_t)128)
{
division = (int)len/128;
modular = (int)len%128;
for(i = 0; i < division; i++)
{
ret = eeprom_write_data(fd_i2c_1,i * 128,tx_buf + 128 * i,128U,(uint8_t)I2C_1_EEPROM_ADDR);
ret = (int)delay((uint32_t)5);
}
ret = (int)delay((uint32_t)5);
if(modular > 0)
{
ret = eeprom_write_data(fd_i2c_1,division * 128,tx_buf + 128 * division,(uint32_t)modular,(uint8_t)I2C_1_EEPROM_ADDR);
}
else
{
}
}
else
{
}
break;
case EEPROM_OUT_BOARD:
if(len <= (uint32_t)128)
{
ret = eeprom_write_data(fd_i2c_8,0x0U,tx_buf,len,(uint8_t)I2C_8_EEPROM_ADDR);
}
else
{
}
if(len > (uint32_t)128)
{
division = (int)len/128;
modular = (int)len%128;
for(i = 0; i < division; i++)
{
ret = eeprom_write_data(fd_i2c_8,i * 128,tx_buf + 128 * i,128U,(uint8_t)I2C_8_EEPROM_ADDR);
ret = (int)delay((uint32_t)5);
}
ret = (int)delay((uint32_t)5);
if(modular > 0)
{
ret = eeprom_write_data(fd_i2c_8,division * 128,tx_buf + 128 * division,(uint32_t)modular,(uint8_t)I2C_8_EEPROM_ADDR);
}
else
{
}
}
else
{
}
break;
case EEPROM_8R:
if(len <= (uint32_t)64)
{
ret = eeprom_write_data(fd_i2c_8,0x0U,tx_buf,len,(uint8_t)I2C_8_EEPROM_8R_ADDR);
}
else
{
}
if((len > (uint32_t)64) && (len < (uint32_t)32768))
{
division = (int)len/64;
modular = (int)len%64;
for(i = 0; i < division; i++)
{
ret = eeprom_write_data(fd_i2c_8,i * 64,tx_buf + 64 * i,64U,(uint8_t)I2C_8_EEPROM_8R_ADDR);
ret = (int)delay((uint32_t)5);
}
ret = (int)delay((uint32_t)5);
if(modular > 0)
{
ret = eeprom_write_data(fd_i2c_8,division * 64,tx_buf + 64 * division,(uint32_t)modular,(uint8_t)I2C_8_EEPROM_8R_ADDR);
}
else
{
}
}
else
{
ret = -1;
}
break;
case EEPROM_12R:
if(len <= (uint32_t)64)
{
ret = eeprom_write_data(fd_i2c_8,0x0U,tx_buf,len,(uint8_t)I2C_8_EEPROM_12R_ADDR);
}
else
{
}
if((len > (uint32_t)64) && (len < (uint32_t)32768))
{
division = (int)len/64;
modular = (int)len%64;
for(i = 0; i < division; i++)
{
ret = eeprom_write_data(fd_i2c_8,i * 64,tx_buf + 64 * i,64U,(uint8_t)I2C_8_EEPROM_12R_ADDR);
ret = (int)delay((uint32_t)5);
}
ret = (int)delay((uint32_t)5);
if(modular > 0)
{
ret = eeprom_write_data(fd_i2c_8,division * 64,tx_buf + 64 * division,(uint32_t)modular,(uint8_t)I2C_8_EEPROM_12R_ADDR);
}
else
{
}
}
else
{
ret = -1;
}
break;
default:
perror("board must be EEPROM_IN_BOARD, EEPROM_IN_BOARD, EEPROM_8R, EEPROM_12R");
ret = -1;
break;
}
}
return ret;
}
int imx8_read_eeprom(int board,uint8_t rx_buf[], unsigned int len)
{
int division = 0,modular = 0,ret = 0;
int i;
if((len > (uint32_t)65536) || (len < (uint32_t)0) || (rx_buf == NULL))
{
perror("wrong para");
ret = -1;
}
else
{
switch(board)
{
case EEPROM_IN_BOARD:
if(len <= (uint32_t)128)
{
ret = eeprom_read_data(fd_i2c_1,0x0U,rx_buf,len,(uint8_t)I2C_1_EEPROM_ADDR);
}
else
{
}
if(len > (uint32_t)128)
{
division = (int)len/128;
modular = (int)len%128;
for(i = 0; i < division; i++)
{
ret = eeprom_read_data(fd_i2c_1,i * 128,rx_buf + 128 * i,128U,(uint8_t)I2C_1_EEPROM_ADDR);
}
if(modular > 0)
{
ret = eeprom_read_data(fd_i2c_1,division * 128,rx_buf + 128 * division,(uint32_t)modular,(uint8_t)I2C_1_EEPROM_ADDR);
}
else
{
}
}
else
{
}
break;
case EEPROM_OUT_BOARD:
if(len <= (uint32_t)128)
{
ret = eeprom_read_data(fd_i2c_8,0x0U,rx_buf,len,(uint8_t)I2C_8_EEPROM_ADDR);
}
else
{
}
if(len > (uint32_t)128)
{
division = (int)len/128;
modular = (int)len%128;
for(i = 0; i < division; i++)
{
ret = eeprom_read_data(fd_i2c_8,i * 128,rx_buf + 128 * i,128U,(uint8_t)I2C_8_EEPROM_ADDR);
}
if(modular > 0)
{
ret = eeprom_read_data(fd_i2c_8,division * 128,rx_buf + 128 * division,(uint32_t)modular,(uint8_t)I2C_8_EEPROM_ADDR);
}
else
{
}
}
else
{
}
break;
case EEPROM_8R:
if(len <= (uint32_t)64)
{
ret = eeprom_read_data(fd_i2c_8,0x0U,rx_buf,len,(uint8_t)I2C_8_EEPROM_8R_ADDR);
}
else
{
}
if((len > (uint32_t)64) && (len < (uint32_t)32768))
{
division = (int)len/64;
modular = (int)len%64;
for(i = 0; i < division; i++)
{
ret = eeprom_read_data(fd_i2c_8,i * 64,rx_buf + 64 * i,64U,(uint8_t)I2C_8_EEPROM_8R_ADDR);
}
if(modular > 0)
{
ret = eeprom_read_data(fd_i2c_8,division * 64,rx_buf + 64 * division,(uint32_t)modular,(uint8_t)I2C_8_EEPROM_8R_ADDR);
}
else
{
}
}
else
{
ret = -1;
}
break;
case EEPROM_12R:
if(len <= (uint32_t)64)
{
ret = eeprom_read_data(fd_i2c_8,0x0U,rx_buf,len,(uint8_t)I2C_8_EEPROM_12R_ADDR);
}
else
{
}
if((len > (uint32_t)64) && (len < (uint32_t)32768))
{
division = (int)len/64;
modular = (int)len%64;
for(i = 0; i < division; i++)
{
ret = eeprom_read_data(fd_i2c_8,i * 64,rx_buf + 64 * i,64U,(uint8_t)I2C_8_EEPROM_12R_ADDR);
}
if(modular > 0)
{
ret = eeprom_read_data(fd_i2c_8,division * 64,rx_buf + 64 * division,(uint32_t)modular,(uint8_t)I2C_8_EEPROM_12R_ADDR);
}
else
{
}
}
else
{
ret = -1;
}
break;
default:
perror("board must be EEPROM_IN_BOARD, EEPROM_IN_BOARD, EEPROM_8R, EEPROM_12R");
ret = -1;
break;
}
}
return ret;
}
int imx8_write_fram(uint8_t tx_buf[], unsigned int len)
{
int division = 0,modular = 0,ret = 0;
int i;
if(len > (uint32_t)32768)
{
perror("FRAM write than 32KB\n");
ret = -1;
}
else
{
}
if(len <= (uint32_t)128)
{
ret = eeprom_write_data(fd_i2c_1,0x0U,tx_buf,len,(uint8_t)I2C_1_FRAM_ADDR);
}
else
{
}
if(len > (uint32_t)128)
{
division = (int)len/128;
modular = (int)len%128;
for(i = 0; i < division; i++)
{
ret = eeprom_write_data(fd_i2c_1,i * 128,tx_buf + 128 * i,128U,(uint8_t)I2C_1_FRAM_ADDR);
ret = (int)delay((uint32_t)5);
}
ret = (int)delay((uint32_t)5);
if(modular > 0)
{
ret = eeprom_write_data(fd_i2c_1,division * 128,tx_buf + 128 * division,(uint32_t)modular,(uint8_t)I2C_1_FRAM_ADDR);
}
else
{
}
}
return ret;
}
int imx8_read_fram(uint8_t rx_buf[], unsigned int len)
{
int division = 0,modular = 0,ret = 0;
int i;
if(len > (uint32_t)32768)
{
perror("FRAM read than 32KB\n");
ret = -1;
}
else
{
}
if(len <= (uint32_t)128)
{
ret = eeprom_read_data(fd_i2c_1,0x0U,rx_buf,len,(uint8_t)I2C_1_FRAM_ADDR);
}
else
{
}
if(len > (uint32_t)128)
{
division = (int)len/128;
modular = (int)len%128;
for(i = 0; i < division; i++)
{
ret = eeprom_read_data(fd_i2c_1,i * 128,rx_buf + 128 * i,128U,(uint8_t)I2C_1_FRAM_ADDR);
}
if(modular > 0)
{
ret = eeprom_read_data(fd_i2c_1,division * 128,rx_buf + 128 * division,(uint32_t)modular,(uint8_t)I2C_1_FRAM_ADDR);
}
else
{
}
}
else
{
}
return ret;
}
static uint16_t ina3321_read(int fd, uint8_t reg)
{
uint8_t v1, v2;
uint16_t result = 0;
struct send_recv
{
i2c_sendrecv_t hdr;
uint8_t buf[2];
} ina3321_rd;
ina3321_rd.buf[0] = reg ;
ina3321_rd.hdr.send_len = (uint32_t)1;
ina3321_rd.hdr.recv_len = (uint32_t)2;
ina3321_rd.hdr.slave.addr = (uint8_t)I2C_8_INA3321_ADDR;
ina3321_rd.hdr.slave.fmt = (uint32_t)I2C_ADDRFMT_7BIT;
ina3321_rd.hdr.stop = (uint32_t)1;
if (devctl(fd, DCMD_I2C_SENDRECV, &ina3321_rd, sizeof(ina3321_rd),NULL))
{
perror("Failed to read to ina3321\n");
result = -1;
}
else
{
}
v1 = ina3321_rd.buf[0];
v2 = ina3321_rd.buf[1];
result = v2 | (uint16_t)((uint16_t)v1 << 8);
return result;
}
int imx8_read_ina3221(struct ina3221* ina3221)
{
int ret = 0;
if(ina3221 == NULL)
{
ret = -1;
}
else
{
ina3221->channel_1_shunt = (ina3321_read(fd_i2c_8,(uint8_t)0x1) >> 3) * 4;
ina3221->channel_2_shunt = (ina3321_read(fd_i2c_8,(uint8_t)0x3) >> 3) * 4;
ina3221->channel_3_shunt = (ina3321_read(fd_i2c_8,(uint8_t)0x5) >> 3) * 4;
ina3221->channel_1_bus = (float)(ina3321_read(fd_i2c_8,(uint8_t)0x2) >> 3) * 8 / 1000;
ina3221->channel_2_bus = (float)(ina3321_read(fd_i2c_8,(uint8_t)0x4) >> 3) * 8 / 1000;
ina3221->channel_3_bus = (float)(ina3321_read(fd_i2c_8,(uint8_t)0x6) >> 3) * 8 / 1000;
}
return ret;
}
double imx8_read_tmp117(void)
{
return (double)temperature_read(fd_i2c_8,(uint8_t)0,(uint8_t)I2C_8_TMP117_ADDR) * 0.0078125;
}
double imx8_read_tmp112(void)
{
uint16_t temp;
double value;
temp = temperature_read(fd_i2c_1,(uint8_t)0,(uint8_t)I2C_1_TMP112_ADDR);
if((temp & 0x800u) == 0x800u)
{
temp <<= 4;
value = (double)(((short int)temp * 0.0625) / 16);
}
else
{
value = (double)temp * 0.0625;
}
return value;
}
/*i2c release*/
int imx8_release_i2c(void)
{
int ret = 0;
ret = close (fd_i2c_1);
ret = close (fd_i2c_8);
return ret;
}