Files
smod_atsc_app/atsc_app/bsp/i2c_drv.c
T

1821 lines
44 KiB
C
Executable File
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <unistd.h>
#include <pthread.h> /* mux- */
#include <unistd.h> /* -System V */
#include <stropts.h> /* -XSI STREAMS */
#include <linux/types.h>
#include <linux/i2c.h>
#include <linux/i2c-dev.h>
#include <sys/types.h>
#include <sys/ioctl.h> /* ioctl - BSD and Linux */
#include "../inc/type.h"
#include "../inc/i2c_drv.h"
#include "../inc/sys_config.h"
#include "../inc/delay.h"
#include "../inc/ipara_cfg.h"
#include "../inc/igpio.h"
#include "../inc/isys_com.h"
#include "../inc/tsoip.h"
#define PRINT_TUNER_ERR 1
#if PRINT_TUNER_ERR
#define PR_ERR(...) printf(__VA_ARGS__)
#else
#define PR_ERR(...)
#endif
#define FORCE_WR_SEGMENT (1)
#define USE_I2C_HW 1
#define USE_I2C_HW_DIRECT_WR 0
//----------------------------------------
#define __un_used_stm32_i2c__ 1
#define __un_used_stm32_e2p__ 1
//----------------------------------------
extern volatile uint8 dpd_wr_cksum;
extern volatile uint8 dpd_rd_cksum;
extern uint8 dpd_data;
extern volatile uint32 dbg_wr_checksum;
//STM平台,底层处理逻辑和6911的不同,发送器件地址时,6911的API函数将地址左移了一位,而STM的没有,所以需要将6911平台定义的地址手动左移一位
//#define EXT_I2C_NUM 0
/*#define FPGA_I2C_NUM 1
#define E2_PROM_I2C_NUM 2
#define TUNER_I2C_NUM 3
#define DRYLOOP_I2C_NUM 4
#define E2_PROM_DEV1_ADDRESS (0X50<<1) //E2rom的器件地址
#define E2_PROM_DEV2_ADDRESS (0X53<<1) //片2E2器件地址
#define E2_PROM_DEV3_ADDRESS (0X57<<1) //片3E2器件地址
#define FPGA_DEV_ADDRESS (0X5A<<1)
#define DRYLOOP_DEV_ADDRESS (0x42<<1)
*/
#define I2C_SDA_H(num) do{set_gpio_io_direct(t_i2c_gp[num].sda_gp_num,E_IO_OUT); set_gpio_value(t_i2c_gp[num].sda_gp_num,1);}while(0)
#define I2C_SDA_L(num) do{set_gpio_io_direct(t_i2c_gp[num].sda_gp_num,E_IO_OUT); set_gpio_value(t_i2c_gp[num].sda_gp_num,0);}while(0)
#define I2C_SCL_H(num) do{set_gpio_io_direct(t_i2c_gp[num].scl_gp_num,E_IO_OUT); set_gpio_value(t_i2c_gp[num].scl_gp_num,1);}while(0)
#define I2C_SCL_L(num) do{set_gpio_io_direct(t_i2c_gp[num].scl_gp_num,E_IO_OUT); set_gpio_value(t_i2c_gp[num].scl_gp_num,0);}while(0)
//#define TS2IP_DEV_ADDRESS (0x70<<1)
//#define FPGA2_DEV_ADDRESS (0x25<<1)
static int fd_i2c_fpga = -1;
static int fd_i2c_tsoip = -1;
static int fd_i2c_tsoip2 = -1;
int fd_i2c_tuner = -1;
static volatile uint32 fpga1_segment_bak = (uint32)-1;
pthread_mutex_t mux_i2c_fpga;
pthread_mutex_t mux_i2c_tsoip;
pthread_mutex_t mux_i2c_tuner;
pthread_mutex_t mux_e_cfg;
pthread_mutex_t mux_dpd_wr_ck;
#if !USE_I2C_HW
static void i2c_cfg_para_init(void);
#endif
void e_map_init(void)
{
pthread_mutex_init(&mux_e_cfg, NULL);
}
void e2_byte_write(uint16 addr,uint8 data,uint32 chip)
{
int ret;
uint8 rdata;
rdata = e2_byte_read(addr, chip&E2_TOTAL_NUM);
if(rdata != data){
pthread_mutex_lock(&mux_e_cfg);
ret = set_para_to_e_map(addr,data,chip&E2_TOTAL_NUM);
pthread_mutex_unlock(&mux_e_cfg);
}
}
uint8 e2_byte_read(uint16 addr,uint32 chip)
{
uint8 data = 0xff;
pthread_mutex_lock(&mux_e_cfg);
data = get_para_from_e_map(addr, chip&E2_TOTAL_NUM);
pthread_mutex_unlock(&mux_e_cfg);
return data;
}
uint8 e2_byte_read_v2(uint16 addr, uint8 default_value,uint32 chip)
{
uint8 data = 0xff;
pthread_mutex_lock(&mux_e_cfg);
data = get_para_from_e_map_v2(addr, default_value, chip&E2_TOTAL_NUM);
pthread_mutex_unlock(&mux_e_cfg);
return data;
}
static uint32 e2_read_buf(uint8* pbuf, uint16 offset, uint16 num,uint32 chip)
{
return I2C_READ_OK;
}
static uint32 e2_write_page(uint8* pbuf, uint16 offset, uint16 num,uint32 chip)
{
}
static uint32 e2_write_buf(uint8* pbuf, uint16 offset, uint16 write_num,uint32 chip)
{
return I2C_WRITE_OK;
}
#if USE_I2C_HW
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <linux/i2c.h>
#include <linux/i2c-dev.h>
#include <string.h>
#include "../inc/dpd_proc.h"
#define I2C_WRITE_DATA 0
#define I2C_READ_DATA 1
struct i2cMsg
{
unsigned short addr;
unsigned short flags;
unsigned short len;
unsigned char *buf;
};
struct i2c_ioctl_data
{
struct i2cMsg *msgs;
int nmsgs;
};
static int i2c_hw_write(int fd,unsigned short devaddr,unsigned char *buf,unsigned short buflen)
{
struct i2cMsg msg[2];
struct i2c_ioctl_data date;
int ret = 0;
if(buf == NULL)
return -1;
msg[0].len = buflen;//buf len
msg[0].flags = I2C_WRITE_DATA;//0write 1read
msg[0].addr = devaddr;
msg[0].buf = buf;
date.nmsgs = 1;
date.msgs = (struct i2cMsg *)&msg;
ret = ioctl(fd, I2C_RDWR, (unsigned long)&date);
if(ret < 0){
//usr_sec_printf(" [write-ioctrl-i2c] failed,ret = %d\r\n", ret);
}
return ret;
}
static int i2c_hw_read(int fd,unsigned short devaddr,unsigned char *buf,unsigned short buflen,unsigned char *retbuf,unsigned short retbuflen)
{
struct i2cMsg msg[2];
struct i2c_ioctl_data date;
int ret = 0;
if(buf == NULL)
return -1;
msg[0].len = buflen;//buf len
msg[0].flags = I2C_WRITE_DATA;//0write 1read
msg[0].addr = devaddr;//dev addr
msg[0].buf = buf;
msg[1].len = retbuflen;//buf len
msg[1].flags = I2C_READ_DATA;//0write 1read
msg[1].addr = devaddr;//dev addr
msg[1].buf = retbuf;
date.nmsgs = 2;
date.msgs = (struct i2cMsg *)&msg;
ret = ioctl(fd, I2C_RDWR, (unsigned long)&date);
if(ret < 0){
usr_sec_printf(" [read-ioctrl-i2c] failed,ret = %d\r\n", ret);
}
//@tmp
//printf("r fd=%d addr=0x%x buflen=%d\n",fd, buf[0], buflen);
return ret;
}
static int i2c_hw_read2(int fd,unsigned short addr,unsigned char *retbuf,unsigned short retbuflen)
{
struct i2cMsg msg[1];
struct i2c_ioctl_data date;
int ret = 0;
if(retbuf == NULL)
return -1;
msg[0].len = retbuflen;//buf len
msg[0].flags = I2C_READ_DATA;//0write 1read
msg[0].addr = addr;//dev addr
msg[0].buf = retbuf;
date.nmsgs = 1;
date.msgs = (struct i2cMsg *)&msg;
ret = ioctl(fd, I2C_RDWR, (unsigned long)&date);
if(ret < 0){
//usr_sec_printf(" [read2-ioctrl-i2c] failed,ret = %d\r\n", ret);
}
//@tmp
//printf("r fd=%d addr=0x%x buflen=%d\n",fd, buf[0], buflen);
return ret;
}
//FPGA_I2C_NUM
static void i2c_hw_mode_init()
{
char buf[20];
//FPGA_I2C_NUM
memset(buf,0,sizeof(buf));
sprintf(buf,"/dev/i2c-%d",FPGA_I2C_NUM);
fd_i2c_fpga = open(buf, O_RDWR);
if(fd_i2c_fpga < 0){
log_printf(LOG_ERR, I_NOUSED, "i2c-%d fd(fpga) open failed.\n",FPGA_I2C_NUM);
fd_i2c_fpga = -1;
return;
}
else{
ioctl(fd_i2c_fpga,I2C_TIMEOUT,1);/*超时时间*/
ioctl(fd_i2c_fpga,I2C_RETRIES,3);/*重复次数*/
//printf(">>i2c-%d fd(fpga) open ok\n",FPGA_I2C_NUM);
}
//EXT_I2C_NUM
/*memset(buf,0,sizeof(buf));
sprintf(buf,"/dev/i2c-%d",EXT_I2C_NUM);
fd_i2c_tsoip = open(buf, O_RDWR);
if(fd_i2c_tsoip < 0){
log_printf(LOG_ERR, I_NOUSED, "i2c-%d fd(tsoip) open failed.\n", EXT_I2C_NUM);
fd_i2c_tsoip = -1; }
else{
ioctl(fd_i2c_tsoip,I2C_TIMEOUT,1);//超时时间
ioctl(fd_i2c_tsoip,I2C_RETRIES,2);//重复次数
//printf(">>i2c-%d fd(tsoip) open ok\n",EXT_I2C_NUM);
}*/
//tuner
memset(buf,0,sizeof(buf));
sprintf(buf,"/dev/i2c-%d",TUNER_I2C_NUM);
fd_i2c_tuner = open(buf, O_RDWR);
if(fd_i2c_tuner < 0){
log_printf(LOG_ERR, I_NOUSED, "i2c-%d fd(tuner) open failed.\n", TUNER_I2C_NUM);
fd_i2c_tuner = -1; }
else{
ioctl(fd_i2c_tuner,I2C_TIMEOUT,1);/*超时时间*/
ioctl(fd_i2c_tuner,I2C_RETRIES,2);/*重复次数*/
//printf(">>i2c-%d fd(tuner) open ok\n",TUNER_I2C_NUM);
}
}
#if 0
static void i2c_tuner_hw_mode_init(void)
{
char buf[20];
memset(buf,0,sizeof(buf));
sprintf(buf,"/dev/i2c-%d", TUNER_I2C_NUM);
fd_i2c_tuner = open(buf, O_RDWR);
if(fd_i2c_tuner < 0){
log_printf(LOG_ERR, I_NOUSED, "Err. i2c-%d fd open failed.\r\n", TUNER_I2C_NUM);
fd_i2c_tuner = -1;
return;
}
else{
ioctl(fd_i2c_tuner,I2C_TIMEOUT,1);/*超时时间*/
ioctl(fd_i2c_tuner,I2C_RETRIES,3);/*重复次数*/
}
}
#endif
#endif//USE_I2C_HW
#if !USE_I2C_HW
static void i2c_soft_mode_init()
{
i2c_cfg_para_init();
i2c_gpio_init();
}
#endif
#if !USE_I2C_HW //I2C_SOFT_GPIO
#define I2C_Direction_Transmitter ((uint8_t)0x00)
#define I2C_Direction_Receiver ((uint8_t)0x01)
#define I2C_SOFT_DELAY_TIME 1 //100k 单周期12us,80k
#define I2C_SOFT_EXTRA_DELAY 280 //ip2ts模块等待时间
#define DLY_TEST() ;
typedef struct {
uint16 sda_gp_num;
uint16 scl_gp_num;
}S_I2C_GPIO_N;
static uint32 g_byte_cnt=0;
S_I2C_GPIO_N t_i2c_gp[2]={0};
static void i2c_cfg_para_init(void)
{
t_i2c_gp[0].sda_gp_num = I2C1_SDA_GP_NUM;
t_i2c_gp[0].scl_gp_num = I2C1_SCL_GP_NUM;
t_i2c_gp[1].sda_gp_num = I2C2_SDA_GP_NUM;
t_i2c_gp[1].scl_gp_num = I2C2_SCL_GP_NUM;// R350
}
uint8 I2C_SDA_READ(uint8 num){
int ret;
uint8 u8val;
set_gpio_io_direct(t_i2c_gp[num].sda_gp_num,E_IO_IN);
ret = get_gpio_value(t_i2c_gp[num].sda_gp_num, &u8val);
//printf("sda read=%d\n",u8val);
return u8val;
}
uint8 I2C_SCL_READ(uint8 num){
int ret;
uint8 u8val;
set_gpio_io_direct(t_i2c_gp[num].scl_gp_num,E_IO_IN);
ret = get_gpio_value(t_i2c_gp[num].scl_gp_num, &u8val);
return u8val;
}
//100K
static void i2c_soft_delay(uint32 nus)
{
delay_us(I2C_SOFT_DELAY_TIME*nus);
}
static void i2c_soft_delay_ext(uint32 nus)
{
delay_us(I2C_SOFT_EXTRA_DELAY*nus);
}
static uint32 i2c_soft_start(uint32 i2c_num)
{
BOOL tmp;
I2C_SDA_H(i2c_num);
I2C_SCL_H(i2c_num);
i2c_soft_delay(1);
//tmp = I2C_SDA_READ(i2c_num);
//printf("1.tmp=%d\n",tmp);
/*if(!tmp)
{
//printf("2.tmp=%d\n",tmp);
return 1;
}*/
I2C_SDA_L(i2c_num);
i2c_soft_delay(1);
/*tmp = I2C_SDA_READ(i2c_num);
if(tmp)
{
//printf("3.tmp=%d\n------------\n\n",tmp);
return 2;
}*/
I2C_SCL_L(i2c_num);//I2C_SDA_L
i2c_soft_delay(1);
//printf("i2c start ok.\n");
return 0;
}
static void i2c_soft_stop(uint32 i2c_num)
{
I2C_SCL_L(i2c_num);
i2c_soft_delay(1);
I2C_SDA_L(i2c_num);
i2c_soft_delay(1);
I2C_SCL_H(i2c_num);
i2c_soft_delay(1);
I2C_SDA_H(i2c_num);
i2c_soft_delay(1);
}
static void i2c_soft_ack(uint32 i2c_num)
{
I2C_SCL_L(i2c_num);
i2c_soft_delay(1);
I2C_SDA_L(i2c_num);
i2c_soft_delay(1);
I2C_SCL_H(i2c_num);
i2c_soft_delay(1);
I2C_SCL_L(i2c_num);
i2c_soft_delay(1);
//add
I2C_SDA_H(i2c_num);
}
//读取时,最后一字节不需要ACK
static void i2c_no_ack(uint32 i2c_num)
{
I2C_SCL_L(i2c_num);
i2c_soft_delay(1);
I2C_SDA_H(i2c_num);
i2c_soft_delay(1);
I2C_SCL_H(i2c_num);
i2c_soft_delay(1);
I2C_SCL_L(i2c_num);
i2c_soft_delay(1);
}
//true:等待到ACK false:无 ack
static BOOL i2c_wait_ack(uint32 i2c_num)
{
BOOL tmp;
I2C_SCL_L(i2c_num);
i2c_soft_delay(1);
I2C_SDA_H(i2c_num);
i2c_soft_delay(1);
I2C_SCL_H(i2c_num);
i2c_soft_delay(1);
tmp = I2C_SDA_READ(i2c_num);
if(tmp)
{
I2C_SCL_L(i2c_num);
return FALSE;
}
I2C_SCL_L(i2c_num);
return TRUE;
}
//MSB
static void i2c_soft_send_byte(uint32 i2c_num,uint8 data)
{
uint32 i=8;
while(i--)
{
I2C_SCL_L(i2c_num);
i2c_soft_delay(1);
if(data&0x80)
{
I2C_SDA_H(i2c_num);
}
else
{
I2C_SDA_L(i2c_num);
}
data<<=1;
i2c_soft_delay(1);
I2C_SCL_H(i2c_num);
i2c_soft_delay(2);
}
I2C_SCL_L(i2c_num);
//printf("byte send.\n");
}
static uint8 i2c_soft_read_byte(uint32 i2c_num)
{
BOOL tmp;
uint32 i=8;
uint8 data=0;
I2C_SDA_H(i2c_num);
while(i--)
{
data<<=1;
I2C_SCL_L(i2c_num);
i2c_soft_delay(2);
I2C_SCL_H(i2c_num);
i2c_soft_delay(1);
tmp = I2C_SDA_READ(i2c_num);
if(tmp)
{
data|=0x01;
}
i2c_soft_delay(1);
}
I2C_SCL_L(i2c_num);
return data;
}
//读取偏移地址为单字节的I2C底层函数,不考虑页
static uint32 i2c1_read_offset8(uint8* pbuf,uint8 offset,uint32 num,uint8 dev,uint8 i2c)
{
uint16 read_cnt = num;
uint32 time_in,time_out;
if((num==0)||(pbuf==NULL))
return I2C_PARA_INVALID;
if(i2c>=I2C_MAX_NUM)
return I2C_PARA_INVALID;
if(i2c_soft_start(i2c))
{
log_printf(LOG_ERR,I_NOUSED,"i2c start for r failed.\n==============\n");
return 1;
}
// time_in = usr_get_cur_time_ms();
i2c_soft_send_byte(i2c, dev|I2C_Direction_Transmitter);
// time_out = usr_get_cur_time_ms();
// printf(" time_byte1:%d\n",time_out-time_in);
// time_in = usr_get_cur_time_ms();
if(!i2c_wait_ack(i2c))
{
i2c_soft_stop(i2c);
return 2;
}
DLY_TEST();
// time_out = usr_get_cur_time_ms();
// printf(" time_wait1:%d\n",time_out-time_in);
i2c_soft_send_byte(i2c,offset);
i2c_wait_ack(i2c);
if(i2c_soft_start(i2c))
{
return 3;
}
DLY_TEST();
// time_in = usr_get_cur_time_ms();
i2c_soft_send_byte(i2c, dev|I2C_Direction_Receiver);
// time_out = usr_get_cur_time_ms();
// printf(" time_byte2:%d\n",time_out-time_in);
// time_in = usr_get_cur_time_ms();
if(!i2c_wait_ack(i2c))
{
i2c_soft_stop(i2c);
return 3;
}
DLY_TEST();
// time_out = usr_get_cur_time_ms();
// printf(" time_wait2:%d\n",time_out-time_in);
while(read_cnt--)
{
// time_in = usr_get_cur_time_ms();
*pbuf++ = i2c_soft_read_byte(i2c);
DLY_TEST();
// time_out = usr_get_cur_time_ms();
// printf(" time_byte3:%d\n",time_out-time_in);
if(read_cnt==0)
{
i2c_no_ack(i2c);
i2c_soft_stop(i2c);
}
else
{
i2c_soft_ack(i2c);
}
}
return I2C_READ_OK;
}
//参数偏移地址为1字节的i2c写函数
static uint32 i2c1_write_offset8(uint8* pbuf,uint8 offset,uint32 num,uint8 dev,uint8 i2c)
{
uint16 read_cnt = num;
if((num==0)||(pbuf==NULL))
return I2C_PARA_INVALID;
i2c_soft_start(i2c);
i2c_soft_send_byte(i2c, dev|I2C_Direction_Transmitter);
//写器件地址
if(!i2c_wait_ack(i2c))
{
i2c_soft_stop(i2c);
return 2;
}
DLY_TEST();
i2c_soft_send_byte(i2c,offset);
i2c_wait_ack(i2c);
DLY_TEST();
while(read_cnt--)
{
i2c_soft_send_byte(i2c,*pbuf++);
i2c_wait_ack(i2c);
DLY_TEST();
if(read_cnt==0)
{
i2c_soft_stop(i2c);
}
}
return I2C_READ_OK;
}
//IP2TS读写专用函数,读写时,速度比较慢,需要加较长的延时,否则读写会出现异常
static uint32 i2c1_read_offset8_ip2ts(uint8* pbuf,uint8 offset,uint32 num,uint8 dev,uint8 i2c)
{
}
//参数偏移地址为1字节的i2c写函数
static uint32 i2c1_write_offset8_ip2ts(uint8* pbuf,uint8 offset,uint32 num,uint8 dev,uint8 i2c)
{
}
void test_i2c_io_time()
{
int i;
uint32 time_in;
uint32 time_out;
time_in = usr_get_cur_time_ms();
for(i=0;i<50;i++){
I2C_SDA_H(FPGA_I2C_NUM);
I2C_SDA_L(FPGA_I2C_NUM);
//I2C_SCL_H(FPGA_I2C_NUM);
//I2C_SCL_L(FPGA_I2C_NUM);
}
time_out = usr_get_cur_time_ms();
log_printf(LOG_DEBUG,I_NOUSED," time_read:%d [cnt=%d]\n",time_out-time_in,g_byte_cnt);
}
#endif
#if 1
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#define I2C_RETRIES 0x0701
#define I2C_TIMEOUT 0x0702
#define I2C_SLAVE 0x0703 //IIC从器件的地址设置
//#define I2C_BUS_MODE 0x0780
static int i2c_cdev_init(void);
static int i2c_cdev_write(int fd, uint8 reg, uint8 *pval,uint8 wlen);
static int i2c_cdev_read(int fd, uint8 reg, uint8 *pval,uint8 rlen);
static int i2c_cdev_init(void)
{
char buf[20];
//FPGA_I2C_NUM
memset(buf,0,sizeof(buf));
sprintf(buf,"/dev/i2c-%d",FPGA_I2C_NUM);
fd_i2c_fpga = open(buf, O_RDWR);
if(fd_i2c_fpga < 0){
log_printf(LOG_ERR,I_NOUSED," i2c-%d fd open failed.\r\n",FPGA_I2C_NUM);
fd_i2c_fpga = -1;
return -1;
}
else{
ioctl(fd_i2c_fpga,I2C_TIMEOUT,1);/*超时时间*/
ioctl(fd_i2c_fpga,I2C_RETRIES,0);/*重复次数*/
if(ioctl(fd_i2c_fpga, I2C_SLAVE, FPGA_DEV_ADDRESS>>1)<0) { //设置iic从器件地址
printf("fail to set fpga i2c device slave address!\n");
return -1;
}
}
return 0;
}
static int i2c_cdev_write(int fd, uint8 reg, uint8 *pval,uint8 wlen)
{
uint8 dbuf[50];//temp use 50
if((wlen+1) > 50)
return -1;
memset(dbuf, 0, sizeof(dbuf));
dbuf[0] = reg;
memcpy(&dbuf[1], pval, wlen+1);
if(write(fd, dbuf, wlen+1) == (wlen+1))
return 0;
return -1;
}
static int i2c_cdev_read(int fd, uint8 reg, uint8 *pval,uint8 rlen)
{
int ret;
uint8 reg_addr;
reg_addr = reg;
ret = write(fd, &reg_addr, 1);
/*if(ret!=-1)
printf("write addr ok.\n");*/
ret = read(fd, pval, rlen);
if(ret==1){
return 0;
//printf("read data ok.\n");
}
return -1;
}
//extern S_CTTB_PARA cttb_para;
//#include "../inc/dpd_proc.h"
uint8 fpga_byte_reads(uint8 segment,uint32 addr,uint8 *pdata,uint8 rlen)
{
uint8 data=0xff;
#if !DBG_DISABLE_I2C
int ret;
uint8 buf[5];
uint8 retbuf[5];
uint32 time_in;
uint32 time_out;
pthread_mutex_lock(&mux_i2c_fpga);
if(fpga1_segment_bak != segment)
{
#if USE_I2C_HW
memset(buf,0,sizeof(buf));
buf[0] = 0x00;//reg ==> 0x00
buf[1] = segment;//seg ==> 0x01
ret = i2c_hw_write(fd_i2c_fpga, FPGA_DEV_ADDRESS>>1, buf, 2);
if(ret<0){
log_printf(LOG_ERR,I_NOUSED,"Err.fpga set msg segment ret err.\n");
}
#elif USE_I2C_HW_DIRECT_WR
ret = i2c_cdev_write(fd_i2c_fpga, 0x00, &segment, 1);
if(ret<0){
log_printf(LOG_ERR,I_NOUSED,"fpga set cdev segment ret err.\n");
}
#else
ret = i2c1_write_offset8(&segment, 0, 1, FPGA_DEV_ADDRESS, FPGA_I2C_NUM);
if(ret!=0){
log_printf(LOG_ERR,I_NOUSED,"fpga set soft segment ret err.\n");
}
#endif
fpga1_segment_bak = segment;
}
#if USE_I2C_HW
memset(buf,0,sizeof(buf));
memset(retbuf,0,sizeof(retbuf));
buf[0] = addr;//reg addr ==> 0x12
ret = i2c_hw_read(fd_i2c_fpga, FPGA_DEV_ADDRESS>>1, buf, 1, pdata, rlen);
data= retbuf[0];
if(ret<0){
log_printf(LOG_ERR, I_NOUSED, "Err.fpga read msg byte errnum=%d.\n",ret);
data =0xff;
}
#elif USE_I2C_HW_DIRECT_WR
memset(buf,0,sizeof(buf));
memset(retbuf,0,sizeof(retbuf));
buf[0] = addr;//reg addr ==> 0x12
ret = i2c_cdev_read(fd_i2c_fpga, addr, pdata, rlen);
//printf("%d\n",*pdata[0]);
data= retbuf[0];
#else
ret = i2c1_read_offset8(&data,addr,1,FPGA_DEV_ADDRESS, FPGA_I2C_NUM);
if(ret!=0){
log_printf(LOG_ERR,I_NOUSED,"Err.fpga read soft byte errnum=%d.\n",ret);
data =0xff;
}
#endif
pthread_mutex_unlock(&mux_i2c_fpga);
#endif
return data;
}
int fpga_byte_writes(uint8 segment,uint32 addr,uint8 *pdata,uint8 wlen)
{
int ret=0;
uint8 buf[5];
#if !DBG_DISABLE_I2C
//printf("fpga write[addr=0x%x,data=0x%x]\n",addr,data);
pthread_mutex_lock(&mux_i2c_fpga);
if(fpga1_segment_bak != segment)
{
#if USE_I2C_HW
memset(buf,0,sizeof(buf));
buf[0] = 0x00;//reg ==> 0x00
buf[1] = segment;//seg ==> 0x01
ret = i2c_hw_write(fd_i2c_fpga, FPGA_DEV_ADDRESS>>1, buf, 2);
if(ret<0){
log_printf(LOG_ERR,I_NOUSED,"Err.fpga set segment ret err.\n");
}
#elif USE_I2C_HW_DIRECT_WR
ret = i2c_cdev_write(fd_i2c_fpga, 0x00, &segment, 1);
if(ret<0){
log_printf(LOG_ERR,I_NOUSED,"fpga set cdev segment ret err.\n");
}
#else
ret = i2c1_write_offset8(&segment, 0, 1, FPGA_DEV_ADDRESS, FPGA_I2C_NUM);
if(ret!=0){
log_printf(LOG_DEBUG,I_NOUSED,"fpga set segment ret err.\n");
}
#endif
fpga1_segment_bak = segment;
}
#if USE_I2C_HW
uint8 dbuf[50];
memset(dbuf, 0,sizeof(dbuf));
dbuf[0] = addr;
if(wlen<50)
memcpy(&dbuf[1],pdata,wlen);
else{
ret = -1;
log_printf(LOG_ERR,I_NOUSED,"fpga write byte errnum=%d.\n",ret);
pthread_mutex_unlock(&mux_i2c_fpga);
return ret;
}
ret = i2c_hw_write(fd_i2c_fpga, FPGA_DEV_ADDRESS>>1, &dbuf[0], wlen);
if(ret<0){
log_printf(LOG_ERR,I_NOUSED,"fpga write byte errnum=%d.\n",ret);
}
#elif USE_I2C_HW_DIRECT_WR
ret = i2c_cdev_write(fd_i2c_fpga, addr, pdata, wlen);
if(ret<0){
log_printf(LOG_ERR,I_NOUSED,"fpga set cdev data ret err.\n");
}
#else
i2c1_write_offset8(pdata, addr, 1, FPGA_DEV_ADDRESS,FPGA_I2C_NUM);
if(ret!=0){
log_printf(LOG_ERR,I_NOUSED,"pga write byte errnum=%d.\n",ret);
}
#endif
pthread_mutex_unlock(&mux_i2c_fpga);
#endif
}
uint8 fpga_byte_read(uint8 segment,uint32 addr)
{
uint8 data=0xff;
int ret;
#if !DBG_DISABLE_I2C
uint8 buf[5];
uint8 retbuf[5];
uint32 time_in;
uint32 time_out;
pthread_mutex_lock(&mux_i2c_fpga);
if(fpga1_segment_bak != segment || FORCE_WR_SEGMENT)
{
memset(buf,0,sizeof(buf));
buf[0] = 0x00; //reg ==> 0x00
buf[1] = segment; //seg ==> 0x01
ret = i2c_hw_write(fd_i2c_fpga, FPGA_DEV_ADDRESS>>1, buf, 2);
if(ret < 0){
log_printf(LOG_ERR,I_NOUSED,"fpga set msg segment ret err.\n");
}
fpga1_segment_bak = segment;
}
memset(buf,0,sizeof(buf));
memset(retbuf,0,sizeof(retbuf));
buf[0] = addr;//reg addr ==> 0x12
ret = i2c_hw_read(fd_i2c_fpga, FPGA_DEV_ADDRESS>>1, buf, 1, retbuf, 1);
data= retbuf[0];
if(ret<0){
log_printf(LOG_ERR,I_NOUSED,"fpga read msg byte errnum=%d.\n",ret);
data =0xff;
}
pthread_mutex_unlock(&mux_i2c_fpga);
#endif//DBG_DISABLE_I2C
#if DBG_I2C_ERR_DELAY
if(ret<0)sleep(1);
#endif
return data;
}
extern volatile uint32 usr_sys_ready;
void fpga_byte_write(uint8 segment,uint32 addr,uint8 data)
{
#if !DBG_DISABLE_I2C
int ret=0;
uint8 buf[5];
pthread_mutex_lock(&mux_i2c_fpga);
if(fpga1_segment_bak != segment || FORCE_WR_SEGMENT)
{
memset(buf,0,sizeof(buf));
buf[0] = 0x00;//reg ==> 0x00
buf[1] = segment;//seg ==> 0x01
ret = i2c_hw_write(fd_i2c_fpga, FPGA_DEV_ADDRESS>>1, buf, 2);
if(ret<0){
log_printf(LOG_ERR, I_NOUSED, "fpga set segment ret err.\n");
}
fpga1_segment_bak = segment;
}
memset(buf,0,sizeof(buf));
buf[0] = (uint8)addr; //reg ==> 0x12
buf[1] = data; //data ==> 0x25
ret = i2c_hw_write(fd_i2c_fpga, FPGA_DEV_ADDRESS>>1, buf, 2);
if(ret < 0){
log_printf(LOG_ERR, I_NOUSED, "fpga write byte errnum=%d.\n", ret);
}
pthread_mutex_unlock(&mux_i2c_fpga);
#if DBG_I2C_ERR_DELAY
if(ret<0)sleep(1);
#endif
#endif//DBG_DISABLE_I2C
}
void tsoip_byte_write(int tsoip_index, uint32 addr, uint8 data)
{
#if !DBG_DISABLE_I2C
int ret = 0;
uint8 buf[5] = {0};
tsoip_index = tsoip_index & 0x1;
pthread_mutex_lock(&mux_i2c_fpga);
memset(buf, 0, sizeof(buf));
buf[0] = (uint8)addr;
buf[1] = data;
ret = i2c_hw_write(fd_i2c_fpga, (tsoip_index==TSOIP_1)?(TS2IP_DEV_ADDRESS>>1):(TS2IP2_DEV_ADDRESS>>1), buf, 2);
if(ret < 0) {
log_printf(LOG_ERR,I_NOUSED,"fpga write [tsoip] byte errnum=%d\n", ret);
}
pthread_mutex_unlock(&mux_i2c_fpga);
#if DBG_I2C_ERR_DELAY
if(ret<0)sleep(1);
#endif
#endif
}
uint8 tsoip_byte_read(int tsoip_index,uint32 addr)
{
uint8 data = 0xff;
#if !DBG_DISABLE_I2C
int ret;
uint8 buf[5];
uint8 retbuf[5];
uint32 time_in;
uint32 time_out;
tsoip_index = tsoip_index & 0x01;
pthread_mutex_lock(&mux_i2c_fpga);
memset(buf, 0, sizeof(buf));
memset(retbuf,0,sizeof(retbuf));
buf[0] = addr;
ret = i2c_hw_read(fd_i2c_fpga, (tsoip_index==TSOIP_1)?(TS2IP_DEV_ADDRESS>>1) :(TS2IP2_DEV_ADDRESS>>1) , buf, 1, retbuf, 1);
data= retbuf[0];
if(ret < 0) {
log_printf(LOG_ERR,I_NOUSED,"Err.fpga read [tsoip] msg byte errnum=%d.\n",ret);
data = 0xff;
}
pthread_mutex_unlock(&mux_i2c_fpga);
#if DBG_I2C_ERR_DELAY
if(ret<0)sleep(1);
#endif
#endif
return data;
}
void fpga_i2c_sim_spi_write(uint16 addr, uint32 data)
{
// addr
fpga_byte_write(JESD_SEG_ADDR, JESD204B_AXI_ADDRESS_L_OFFSET_ADDR, addr & 0xFF);
fpga_byte_write(JESD_SEG_ADDR, JESD204B_AXI_ADDRESS_H_OFFSET_ADDR, (addr>>8) & 0x0F);
// data
fpga_byte_write(JESD_SEG_ADDR, JESD204B_AXI_WR_RD_1_OFFSET_ADDR, (data>> 0) & 0xFF);
fpga_byte_write(JESD_SEG_ADDR, JESD204B_AXI_WR_RD_2_OFFSET_ADDR, (data>> 8) & 0xFF);
fpga_byte_write(JESD_SEG_ADDR, JESD204B_AXI_WR_RD_3_OFFSET_ADDR, (data>>16) & 0xFF);
fpga_byte_write(JESD_SEG_ADDR, JESD204B_AXI_WR_RD_4_OFFSET_ADDR, (data>>24) & 0xFF);
// Wr
fpga_byte_write(JESD_SEG_ADDR, JESD204B_AXI_WR_RD_CTRL_OFFSET_ADDR, JESD204b_WR);
// restore
fpga_byte_write(JESD_SEG_ADDR, JESD204B_AXI_WR_RD_CTRL_OFFSET_ADDR, 0x00);
}
void fpga_i2c_sim_spi_read(uint16 addr, uint32 *p_data)
{
uint8 d[4] = {0};
// addr
fpga_byte_write(JESD_SEG_ADDR, JESD204B_AXI_ADDRESS_L_OFFSET_ADDR, addr & 0xFF);
fpga_byte_write(JESD_SEG_ADDR, JESD204B_AXI_ADDRESS_H_OFFSET_ADDR, (addr>>8) & 0x0F);
// rd
fpga_byte_write(JESD_SEG_ADDR, JESD204B_AXI_WR_RD_CTRL_OFFSET_ADDR, JESD204b_RD);
// data
d[0] = fpga_byte_read(JESD_SEG_ADDR, JESD204B_AXI_WR_RD_1_OFFSET_ADDR);
d[1] = fpga_byte_read(JESD_SEG_ADDR, JESD204B_AXI_WR_RD_2_OFFSET_ADDR);
d[2] = fpga_byte_read(JESD_SEG_ADDR, JESD204B_AXI_WR_RD_3_OFFSET_ADDR);
d[3] = fpga_byte_read(JESD_SEG_ADDR, JESD204B_AXI_WR_RD_4_OFFSET_ADDR);
*p_data = d[0]+ (d[1]<<8)+(d[2]<<16)+(d[3]<<24);
// restore
fpga_byte_write(JESD_SEG_ADDR, JESD204B_AXI_WR_RD_CTRL_OFFSET_ADDR, 0x00);
}
void fpga_reset_save_segment(void)
{
fpga1_segment_bak = (uint32)-1;
}
void ii2c_hw_init(void)
{
pthread_mutex_init(&mux_i2c_fpga, NULL);
#if USE_I2C_HW
i2c_hw_mode_init();
//i2c_tuner_hw_mode_init();
#elif USE_I2C_HW_DIRECT_WR
i2c_cdev_init();
#else
i2c_soft_mode_init();
#endif
}
#if 1 // @tmpNot
uint32 dryloop_write(uint32 addr,uint8 data)
{
return 0;
}
uint8 dryloop_read(uint32 addr)
{
}
void ip2ts_i2c_rw(uint8 *pucData, uint8 addr,uint16 cnt, uint32 rw)
{
}
void ip2ts2_i2c_rw(uint8 *pucData, uint8 addr,uint16 cnt, uint32 rw)//h20190220
{
}
uint32 atmel_write_e2rom_buf(uint8 *pbuf,uint16 offset,uint16 num,uint8 chip)
{
uint32 ret = 0;
return ret;
}
uint32 atmel_read_e2rom_buf(uint8 *pbuf,uint16 offset,uint16 num,uint8 chip)
{
uint32 ret = 0;
return ret;
}
#if 1//@TMP_UNUSED_TUNER TMP_NOT_USED
//mux_i2c_tuner
uint32 tuner_byte_write(uint32 addr,uint8 data)
{
#if USE_TUNER
/*
@f attation: not used, slave addr not used
*/
int ret = 0;
uint8 buf[5] = {0};
pthread_mutex_lock(&mux_i2c_tuner);
memset(buf, 0, sizeof(buf));
buf[0] = (uint8)addr;
buf[1] = data;
ret = i2c_hw_write(fd_i2c_tuner, TUNER18273_ADDRESS, buf, 2);
if(ret < 0) {
log_printf(LOG_ERR,I_NOUSED,"tuner write byte errnum=%d.\n", ret);
sleep(1);
}
pthread_mutex_unlock(&mux_i2c_tuner);
return ret;
#else
return 0;
#endif
}
/*
{
uint32 ret = 0;
take_mutex(i2c_mutex[TUNER_I2C_NUM]);
ret = i2c1_write_offset8(&data, addr, sizeof(data), TUNER18273_ADDRESS,TUNER_I2C_NUM);
give_mutex(i2c_mutex[TUNER_I2C_NUM]);
delay_ms(4);
return ret;
}
*/
uint8 tuner_byte_read(uint32 addr)
{
#if USE_TUNER
/*
@f attation: not used, slave addr not used
*/
uint8 data = 0xff;
int ret;
uint8 buf[5];
uint8 retbuf[5];
uint32 time_in;
uint32 time_out;
pthread_mutex_lock(&mux_i2c_tuner);
memset(buf, 0, sizeof(buf));
memset(retbuf,0,sizeof(retbuf));
buf[0] = addr;
ret = i2c_hw_read(fd_i2c_tuner, TUNER18273_ADDRESS , buf, 1, retbuf, 1);
data= retbuf[0];
if(ret < 0) {
log_printf(LOG_ERR,I_NOUSED,"tuner read msg byte errnum=%d.[%s,%d]\n",ret);
sleep(1);
data = 0xff;
}
pthread_mutex_unlock(&mux_i2c_tuner);
return data;
#else
return 0;
#endif
}
/*
{
uint8 data = 0xff;
uint32 ret = 0;
take_mutex(i2c_mutex[TUNER_I2C_NUM]);
ret = i2c1_read_offset8(&data,addr,sizeof(data),TUNER18273_ADDRESS,TUNER_I2C_NUM);
give_mutex(i2c_mutex[TUNER_I2C_NUM]);
if(ret!=I2C_READ_OK)
{
data =0xff;
}
delay_ms(2);
return data;
}*/
//调用时,第一个字节为地址
uint32 tuner_i2c_write(uint8 addr,uint8 *pdata,uint8 length)
{
#if USE_TUNER
static uint8 stc_shot=0;
int ret = length;
uint8 buf[5] = {0};
static uint8 stc_addr=0;
if(stc_addr!=addr){
stc_addr = addr;
//log_printf(LOG_ERR,I_NOUSED,"w_tuner_addr=0x%x\n",stc_addr);
}
pthread_mutex_lock(&mux_i2c_tuner);
ret = i2c_hw_write(fd_i2c_tuner, addr, pdata, length);
if(ret < 0) {
if(stc_shot==0){
stc_shot=1;
printf("Err.W.tuner addr/len={0x%x %d},[%s,%d]\n",addr,length,__FUNCTION__,__LINE__);
}
//log_printf(LOG_DEBUG,I_NOUSED,"Err.tuner W.addr/len={0x%x %d},[%s,%d]\n",addr,length,__FUNCTION__,__LINE__);
//usleep(2*1000);
ret=0;
}
else{
ret = length;
}
pthread_mutex_unlock(&mux_i2c_tuner);
return ret;
#else
return 0;
#endif
}
uint32 tuner_i2c_read(uint8 addr,uint8 *pdata,uint8 length)
{
#if USE_TUNER
//----------------------------------
int ret;
int retdata=1;
uint8 buf[5];
uint32 time_in;
uint32 time_out;
static uint8 stc_addr=0;
if(stc_addr!=addr){
stc_addr = addr;
//log_printf(LOG_ERR,I_NOUSED,"r_tuner_addr=0x%x\n",stc_addr);
}
pthread_mutex_lock(&mux_i2c_tuner);
#if 1
ret = i2c_hw_read2(fd_i2c_tuner, addr , pdata, length);
#else
//...
#endif
if(ret < 0) {
//usr_sec_printf("Err.R.tuner i2c addr/len={0x%x %d},[%s,%d]\n",addr,length,__FUNCTION__,__LINE__);
//log_printf(LOG_DEBUG,I_NOUSED,"Err.tuner R.addr/len={0x%x %d} [%s,%d]\n",addr,length,__FUNCTION__,__LINE__);
retdata = 0;
//usleep(2*1000);
}
else{
//log_printf(LOG_DEBUG,I_NOUSED,"Ok.tuner R.addr/len={0x%x %d} [%s,%d]\n",addr,length,__FUNCTION__,__LINE__);
}
pthread_mutex_unlock(&mux_i2c_tuner);
return retdata;
//------------------------------------
#else
return 0;
#endif
}
uint32 tuner_i2c_read_offset8(uint8 slave_addr,uint8 offset,uint8 *pdata,uint8 length)
{
#if USE_TUNER
int ret;
int retdata=1;
uint8 buf[5];
uint32 time_in;
uint32 time_out;
pthread_mutex_lock(&mux_i2c_tuner);
memset(buf, 0, sizeof(buf));
buf[0] = offset;
ret = i2c_hw_read(fd_i2c_tuner, slave_addr , buf, 1, pdata, length);
if(ret < 0) {
usr_sec_printf("Err.R.tuner offset8 addr/len={0x%x %d},[%s,%d]\n",slave_addr,length,__FUNCTION__,__LINE__);
//log_printf(LOG_DEBUG,I_NOUSED,"Err.tuner read msg offset8 byte errnum=%d.addr/len={0x%x %d}\n",ret,slave_addr,length);
retdata = 0;
//sleep(1);
}
pthread_mutex_unlock(&mux_i2c_tuner);
return retdata;
#else
return 0;
#endif
}
uint32 tuner_i2c_read_offset16(uint8 slave_addr,uint8 offset[8],uint8 *pdata,uint8 length)
{
#if USE_TUNER
int ret;
int retdata=length;
uint8 buf[5];
uint32 time_in;
uint32 time_out;
pthread_mutex_lock(&mux_i2c_tuner);
memset(buf, 0, sizeof(buf));
buf[0] = offset[0];
buf[1] = offset[1];
ret = i2c_hw_read(fd_i2c_tuner, slave_addr , buf, 2, pdata, length);
if(ret < 0) {
usr_sec_printf("Err.R.tuner offset16 addr/len={0x%x %d},[%s,%d]\n",slave_addr,length,__FUNCTION__,__LINE__);
//log_printf(LOG_DEBUG,I_NOUSED,"Err.tuner read msg offset16 byte errnum=%d.addr/len={0x%x %d} \n",ret,slave_addr,length);
retdata = 0;
//sleep(1);
}
pthread_mutex_unlock(&mux_i2c_tuner);
return retdata;
#else
return 0;
#endif
}
/*
{
uint32 ret = 0;
take_mutex(i2c_mutex[TUNER_I2C_NUM]);
ret = i2c1_read_offset_tuner(pdata,offset,length,slave_addr,TUNER_I2C_NUM);
give_mutex(i2c_mutex[TUNER_I2C_NUM]);
delay_ms(2);
if(ret!=I2C_READ_OK)
return 0;
else
return length;
}
*/
#endif //TMP_NOT_USED
#endif // @tmpNot
void fpga_write_axi0(uint32 addr, uint32 data, uint32 count)
{
/*uint32 tmp_cnt = count;
uint32 tmp_addr = addr;
//printf(">>W [fpga_wr_axi] addr=0x%x data=0x%x\n", addr, data);
while (count--)
{
// 向地址 0x040 写入 0x000000A5
fpga_byte_write(JESD_SEG_ADDR, 0xB6, (addr)&0xff); // 地址低 8 位
fpga_byte_write(JESD_SEG_ADDR, 0xB7, (addr>>8)&0xff); // 地址高 4 位
fpga_byte_write(JESD_SEG_ADDR, 0xB8, data&0xff); // 写数据低 8 位(高 24 位固定为 0)
fpga_byte_write(JESD_SEG_ADDR, 0xB5, 0x00); // 确保 AXI_WR = 0,便于形成新的上升沿
fpga_byte_write(JESD_SEG_ADDR, 0xB5, 0x04); // 触发 AXI 写(AXI_WR: 0 -> 1)
printf(" -W- [fpga_wr_i2c] addr=0x%x data=0x%x\n", addr, data);
// 写操作无需等待完成标志,FPGA 内部自动处理
addr += 1;
}
*/
fpga_byte_write(JESD_SEG_ADDR, addr, data);
}
int fpga_read_axi0(uint32 addr, uint32 *pdata, uint32 count)
{
uint8 tmp_data;
//printf(">>R [fpga_rd_axi] addr=0x%x count=0x%x\n", addr, count);
/*while (count--) {
// 读取地址 0x040 的寄存器
fpga_byte_write(JESD_SEG_ADDR, 0xB6, (addr)&0xff); // 地址低 8 位
fpga_byte_write(JESD_SEG_ADDR, 0xB7, (addr>>8)&0xff); // 地址高 4 位
fpga_byte_write(JESD_SEG_ADDR, 0xB5, 0x00); // 确保 AXI_RD = 0,便于形成新的上升沿
fpga_byte_write(JESD_SEG_ADDR, 0xB5, 0x02); // 触发 AXI 读(AXI_RD: 0 -> 1)
// 等待读完成
uint8_t status;
uint32_t time_out=5000;
do {
status = fpga_byte_read(JESD_SEG_ADDR, 0xB4);
time_out--;
if(time_out<=0){
time_out = 1;
break;
}
} while (!(status & 0x04)); // 等待 AXI_RD_DONE = 1
// 读取 32 位数据
uint8_t d0, d1, d2, d3;
d0 = fpga_byte_read(JESD_SEG_ADDR, 0xB5);
d1 = fpga_byte_read(JESD_SEG_ADDR, 0xB6);
d2 = fpga_byte_read(JESD_SEG_ADDR, 0xB7);
d3 = fpga_byte_read(JESD_SEG_ADDR, 0xB8);
uint32_t result = ((uint32_t)d3 << 24) | ((uint32_t)d2 << 16)
| ((uint32_t)d1 << 8) | d0;
*pdata = result;
printf(" -R- fpga_rd_i2c addr=0x%x data=0x%x timeout=%d\n", addr, result, time_out);
pdata += 1;
addr += 1;
}*/
while (count--) {
tmp_data = fpga_byte_read(JESD_SEG_ADDR, addr);
*pdata = tmp_data;
}
return 0;
}
void fpga_write_axi0_test(uint32 addr, uint32 data, uint32 count)
{
uint32 tmp_cnt = count;
uint32 tmp_addr = addr;
//printf(">>W [fpga_wr_axi] addr=0x%x data=0x%x\n", addr, data);
while (count--)
{
// 向地址 0x040 写入 0x000000A5
fpga_byte_write(JESD_SEG_ADDR, 0xB6, (addr)&0xff); // 地址低 8 位
fpga_byte_write(JESD_SEG_ADDR, 0xB7, (addr>>8)&0xff); // 地址高 4 位
fpga_byte_write(JESD_SEG_ADDR, 0xB8, data&0xff); // 写数据低 8 位(高 24 位固定为 0)
fpga_byte_write(JESD_SEG_ADDR, 0xB5, 0x00); // 确保 AXI_WR = 0,便于形成新的上升沿
fpga_byte_write(JESD_SEG_ADDR, 0xB5, 0x04); // 触发 AXI 写(AXI_WR: 0 -> 1)
printf(" -W- [fpga_wr_i2c] addr=0x%x data=0x%x\n", addr, data);
// 写操作无需等待完成标志,FPGA 内部自动处理
addr += 1;
}
}
int fpga_read_axi0_test(uint32 addr, uint32 *pdata, uint32 count)
{
uint8 tmp_data;
//printf(">>R [fpga_rd_axi] addr=0x%x count=0x%x\n", addr, count);
while (count--) {
// 读取地址 0x040 的寄存器
fpga_byte_write(JESD_SEG_ADDR, 0xB6, (addr)&0xff); // 地址低 8 位
fpga_byte_write(JESD_SEG_ADDR, 0xB7, (addr>>8)&0xff); // 地址高 4 位
fpga_byte_write(JESD_SEG_ADDR, 0xB5, 0x00); // 确保 AXI_RD = 0,便于形成新的上升沿
fpga_byte_write(JESD_SEG_ADDR, 0xB5, 0x02); // 触发 AXI 读(AXI_RD: 0 -> 1)
// 等待读完成
uint8_t status;
uint32_t time_out=5000;
do {
status = fpga_byte_read(JESD_SEG_ADDR, 0xB4);
time_out--;
if(time_out<=0){
time_out = 1;
break;
}
} while (!(status & 0x04)); // 等待 AXI_RD_DONE = 1
// 读取 32 位数据
uint8_t d0, d1, d2, d3;
d0 = fpga_byte_read(JESD_SEG_ADDR, 0xB5);
d1 = fpga_byte_read(JESD_SEG_ADDR, 0xB6);
d2 = fpga_byte_read(JESD_SEG_ADDR, 0xB7);
d3 = fpga_byte_read(JESD_SEG_ADDR, 0xB8);
uint32_t result = ((uint32_t)d3 << 24) | ((uint32_t)d2 << 16)
| ((uint32_t)d1 << 8) | d0;
*pdata = result;
printf(" -R- [fpga_rd_i2c] addr=0x%x data=0x%x timeout=%d\n", addr, result, time_out);
pdata += 1;
addr += 1;
}
return 0;
}
#endif
/* ================= Sony CXD2878 i2c glue (ported from EMV9.3) ================= */
#include "../sonytuner/sony_i2c.h"
#ifndef BURST_WRITE_MAX
#define BURST_WRITE_MAX 128
#endif
sony_result_t i2c_read(sony_i2c_t* pI2c, uint8_t deviceAddress, uint8_t* pData, uint32_t numberOfBytes, uint8_t mode)
{
int ret;
sony_result_t result=SONY_RESULT_OK;
uint8_t reg_addr = (uint8_t)pData[0];
printf("[%s,%d] deviceAddress=0x%x reg_addr=0x%x numberOfBytes=0x%x\n", __FUNCTION__,__LINE__,deviceAddress,reg_addr,numberOfBytes);
/*ret = HI_UNF_I2C_Read(SONY_CXD_I2C_NUM, deviceAddress, reg_addr, 1, pData+1, numberOfBytes-1);
if(ret != HI_SUCCESS)
{
printf("[%s] ret error code:0x%x.",__FUNCTION__,ret);
}*/
pthread_mutex_lock(&mux_i2c_tuner);
ret = i2c_hw_read(fd_i2c_tuner, deviceAddress>>1, &reg_addr, 1, (pData+1), numberOfBytes-1);//pData������ַ
if(ret < 0) {
printf("Err.tuner read byte errnum=%d.[%s,%d]\n", ret,__FUNCTION__,__LINE__);
result = SONY_RESULT_ERROR_I2C;
}
else{
result = SONY_RESULT_OK;
}
pthread_mutex_unlock(&mux_i2c_tuner);
return result;
}
// CXD2878 family can be accessed through the I2C bus with burst-write and burst-read operations
/* S | SLAVE ADDRESS | R/W | A| DATA | A | DATA | P <0 W>
*/
sony_result_t i2c_write(sony_i2c_t* pI2c, uint8_t deviceAddress,uint8_t* pData, uint32_t numberOfBytes, uint8_t mode)
{
int ret;
sony_result_t result=SONY_RESULT_OK;
uint32_t reg_addr = (uint32_t)pData[0];
printf("[%s,%d] deviceAddress=0x%x reg_addr=0x%x numberOfBytes=0x%x\n", __FUNCTION__,__LINE__,deviceAddress,reg_addr,numberOfBytes);
//sony_result_t (*Write)(struct sony_i2c_t* pI2c, uint8_t deviceAddress, const uint8_t *pData, uint32_t size, uint8_t mode);
/*ret = HI_UNF_I2C_Write(SONY_CXD_I2C_NUM, deviceAddress, reg_addr, 1, pData+1, numberOfBytes-1);
if(ret != HI_SUCCESS)
{
printf("[%s] ret error code:0x%x.",__FUNCTION__,ret);
}*/
ret = i2c_hw_write(fd_i2c_tuner, deviceAddress>>1, pData, numberOfBytes);//pData������ַ
if(ret < 0) {
printf("Err.tuner write byte errnum=%d.[%s,%d]\n", ret,__FUNCTION__,__LINE__);
result = SONY_RESULT_ERROR_I2C;
}
else{
result = SONY_RESULT_OK;
}
return result;
}
sony_result_t sony_i2c_CommonReadRegister(sony_i2c_t* pI2c, uint8_t deviceAddress, uint8_t subAddress, uint8_t* pData, uint32_t size)
{
sony_result_t result = SONY_RESULT_OK;
int ret;
SONY_TRACE_I2C_ENTER("sony_i2c_CommonReadRegister");
if(!pI2c || (!pData)){
SONY_TRACE_I2C_RETURN(SONY_RESULT_ERROR_ARG);
}
#if 0
result = pI2c->Write(pI2c, deviceAddress, &subAddress, 1, SONY_I2C_START_EN);
if(result == SONY_RESULT_OK){
result = pI2c->Read(pI2c, deviceAddress, pData, size, SONY_I2C_START_EN | SONY_I2C_STOP_EN);
}
SONY_TRACE_I2C_RETURN(result);
#else
uint8 sub_addr;
sub_addr = subAddress;
pthread_mutex_lock(&mux_i2c_tuner);
ret = i2c_hw_read(fd_i2c_tuner, deviceAddress>>1, &sub_addr, 1, pData, size);
if(ret < 0) {
printf("Err.tuner read byte errnum=%d.[%s,%d]\n", result,__FUNCTION__,__LINE__);
result = SONY_RESULT_ERROR_I2C;
}
else{
result = SONY_RESULT_OK;
}
pthread_mutex_unlock(&mux_i2c_tuner);
//printf("I2CR addr=0x%0X data=0x%02X slv=0x%X\n", subAddress, *pData, deviceAddress);
return result;
#endif
}
sony_result_t sony_i2c_CommonWriteRegister(sony_i2c_t* pI2c, uint8_t deviceAddress, uint8_t subAddress, const uint8_t* pData, uint32_t size)
{
sony_result_t result = SONY_RESULT_OK;
int ret;
uint8_t buffer[BURST_WRITE_MAX + 1];
#if 0
SONY_TRACE_I2C_ENTER("sony_i2c_CommonWriteRegister");
if(!pI2c || (!pData)){
SONY_TRACE_I2C_RETURN(SONY_RESULT_ERROR_ARG);
}
if(size > BURST_WRITE_MAX){
/* Buffer is too small... */
SONY_TRACE_I2C_RETURN(SONY_RESULT_ERROR_ARG);
}
buffer[0] = subAddress;
memcpy(&(buffer[1]), pData, size);
/* send the new buffer */
result = pI2c->Write(pI2c, deviceAddress, buffer, size+1, SONY_I2C_START_EN | SONY_I2C_STOP_EN);
SONY_TRACE_I2C_RETURN(result);
#else
ret = tuner_nbytes_write(deviceAddress>>1, subAddress, (uint8_t*)pData, size); // deviceAddress=0xdc
if(ret < 0) {
printf("Err.tuner write byte errnum=%d.[%s,%d]\n", result,__FUNCTION__,__LINE__);
result = SONY_RESULT_ERROR_I2C;
}
else {
result = SONY_RESULT_OK;
}
//printf("I2CW addr=0x%0X data=0x%02X slv=0x%X\n", subAddress, *pData, deviceAddress);
return result;
#endif
}
sony_result_t sony_i2c_CommonWriteOneRegister(sony_i2c_t* pI2c, uint8_t deviceAddress, uint8_t subAddress, uint8_t data)
{
sony_result_t result = SONY_RESULT_OK;
SONY_TRACE_I2C_ENTER("sony_i2c_CommonWriteOneRegister");
//printf("sony_i2c_CommonWriteOneRegister\r\n");
if(!pI2c){
SONY_TRACE_I2C_RETURN(SONY_RESULT_ERROR_ARG);
}
result = pI2c->WriteRegister(pI2c, deviceAddress, subAddress, &data, 1);
SONY_TRACE_I2C_RETURN(result);
}
/* For Read-Modify-Write */
sony_result_t sony_i2c_SetRegisterBits(sony_i2c_t* pI2c, uint8_t deviceAddress, uint8_t subAddress, uint8_t data, uint8_t mask)
{
sony_result_t result = SONY_RESULT_OK;
SONY_TRACE_I2C_ENTER("sony_i2c_SetRegisterBits");
if(!pI2c){
SONY_TRACE_I2C_RETURN(SONY_RESULT_ERROR_ARG);
}
if(mask == 0x00){
/* Nothing to do */
SONY_TRACE_I2C_RETURN(SONY_RESULT_OK);
}
if(mask != 0xFF){
uint8_t rdata = 0x00;
result = pI2c->ReadRegister(pI2c, deviceAddress, subAddress, &rdata, 1);
if(result != SONY_RESULT_OK){ SONY_TRACE_I2C_RETURN(result); }
data = (uint8_t)((data & mask) | (rdata & (mask ^ 0xFF)));
}
result = pI2c->WriteOneRegister(pI2c, deviceAddress, subAddress, data);
SONY_TRACE_I2C_RETURN(result);
}
/* I2c object creation , Repeater*/
sony_result_t i2c_drv_imx_init(sony_i2c_t* pI2c)//i2c_drv_his3796mv100_init
{
SONY_TRACE_I2C_ENTER("drvi2c_feusb_CreateI2c");
if( !pI2c ) {
SONY_TRACE_I2C_RETURN(SONY_RESULT_ERROR_ARG);
}
pI2c->Read = i2c_read;
pI2c->Write = i2c_write;
pI2c->ReadRegister = sony_i2c_CommonReadRegister;
pI2c->WriteRegister = sony_i2c_CommonWriteRegister;
pI2c->WriteOneRegister = sony_i2c_CommonWriteOneRegister;
pI2c->gwAddress = 0;
pI2c->gwSub = 0;
//pI2c->user = pDrvI2c; /* Store driver object to user pointer */
SONY_TRACE_I2C_RETURN(SONY_RESULT_OK);
}
/* PR04 SMOD: multi-byte tuner i2c write (ported from EMV9.3, used by sony_i2c glue) */
int tuner_nbytes_write(uint32 dev_addr, uint32 offset, uint8 *pdata, uint32 wlen)
{
int ret = 0;
uint8 dbuf[50] = {0};
pthread_mutex_lock(&mux_i2c_tuner);
dbuf[0] = (uint8)offset;
if(wlen<50){ memcpy(&dbuf[1], pdata, wlen); }
else{ printf("Err.tuner nbytes wlen over_range wlen=%u\n", (unsigned)wlen); }
ret = i2c_hw_write(fd_i2c_tuner, dev_addr, dbuf, wlen+1);
if(ret < 0){ printf("Err.tuner nbytes write errnum=%d\n", ret); }
pthread_mutex_unlock(&mux_i2c_tuner);
return ret;
}