IIC加载以及存在的问题---lattice XO3

XO2/XO3系列使用IIC进行在线升级的时候使用的I2C Embedded(在diamond软件安装目录下可以找到在线升级的C代码,<install_path>\embedded_source\i2cembedded\src\i2cem),IIC总线的信号是漏极开路的,所以默认情况下是,信号线是低电平,需要加上啦电阻,使其默认是高电平。IIC总线上建议不要挂太多的器件,建议只挂我们一个CPLD,因为信号质量无法保证。为了能够使用IIC总线进行在线加载(program),I2C_PORT必须要设置为ENABLE特别是使用2B线,用PC烧写的时候(默认是diable3.2以前的版本是直接软件里面改为ENABLE就可以了但是3.2以后的版本设置相对复杂点),diamond3.2及以前版本中设置如下截图

diamond3.2以后的版本如何使能I2C_PORT,先看看用上述操作的结果,如下图报错了呵呵

那么我们要加入EFB模块,而且wb_clk_i的频率要>=3MHZ,而且还有把sda scl引到顶层。调用EFBPrimary ConfigurationUser Flash Memory一定都要选上,如下图

代码中例化如下

/*******************************************************************

*******************************************************************/

module       control(

inout       wire            scl,

inout       wire            sda

);

 

wire osc_clk;

defparam OSCH_inst.NOM_FREQ = "7.00";

 

OSCH OSCH_inst( .STDBY(1'b0),  // 0=Enabled, 1=Disabled

.OSC (osc_clk),

.SEDSTDBY()

   );

 

 

efb    efb_inst(.wb_clk_i( osc_clk),

.i2c1_scl( scl ), //要把IIC的脚接到顶层

.i2c1_sda( sda )

/* .wb_rst_i( ),

.wb_cyc_i( ),

.wb_stb_i( ),

.wb_we_i( ),

.wb_adr_i( ),

.wb_dat_i( ),

.wb_dat_o( ),

.wb_ack_o( ),

.i2c1_irqo( ),

.wbc_ufm_irq( )*/

);

endmodule

/*******************************************************************

*******************************************************************/

不选Primary ConfigurationIIC脚根本就无法访问,也就无法使能,同时MAP的时候也会报上诉错误,如下图没有i2c1_sda  i2c1_scl

不选User Flash Memorywb_clk_i无法给入,同时MAP的时候也会报上诉错误,如下图没有i2c1_sda  i2c1_scl

1.跑一遍产生.JED

 

2按照ProgrammingToolsUserGuide38128继续往下跑设置流程截图如下

随便解释一下.iea是指令  .ied是数据,给出的参考嵌入式代码不是lattice自己人写的,是lattice找人开发的,所以有BUG的话是没办法解决的,只能避开。所以建议客户不要用传.iea  .ied的参考代码。客户自己写C代码,只传要加载的数据,这样出了问题客户自己可控,就不用找我们麻烦。

在安装目录C:\lscc\diamond\3.8_x64\embedded_source\i2cembedded\src有两份IIC加载的C代码,这个是客户根据需求选择的

调试过程

感觉XO3LF空白芯片(擦除后和买回来没试用过的芯片)没法在线加载,调了好几天没有几把用,XO2我之前在另外一个部门调试是OK的。调试的思路和过程如下

 

首先检查客户的硬件PROGRAMN和SN管脚都是已经拉高了,这个是因为加载时有优先级的,而且空白芯片SPI IIC JTAG使能都是打开的,假如那两个脚没有拉高进入他们的加载状态,IIC优先级比较低级无法进入IIC在线升级的状态了,优先级JTAG>SPI>IIC

 

 

 

然后测试了以下几种情况

1.例化EFB,把IIC脚拉到顶层,通过jtag方式烧写到芯片,然后用CPUCPLD

进行在线升级是可以的,具体操作流程如下

/**********************JTAG烧写的代码***************/

module       control(

inout       wire            scl,

inout       wire            sda

);

 

wire osc_clk;

defparam OSCH_inst.NOM_FREQ = "7.00";

 

OSCH OSCH_inst( .STDBY(1'b0),  // 0=Enabled, 1=Disabled

.OSC (osc_clk),

.SEDSTDBY()

   );

 

 

efb    efb_inst(.wb_clk_i( osc_clk),

.i2c1_scl( scl ),

.i2c1_sda( sda )

);

endmodule

/**********************JTAG烧写的代码***************/

烧写完毕之后,用CPUCPLD进行在线升级是没有问题的,作为对比我读取了Feature Rows的值

 

首先先把芯片jed读回来

然后在用软件读取读回来的JEDfeature rows的值,操作如下

跳出来一个界面,操作如下

 

读回来的信息如下

 

default是默认值,IIC_PORT默认值是打开的(Enable,也就是说FILE_VALUE=0,说明是打开的,当擦除之后FILE_VALUE的所有值应该与default所有值相同

/**********************JTAG烧写的代码***************/

module       control(

output       wire            led

);

 

assign led=1;

endmodule

/**********************JTAG烧写的代码***************/

 

烧写流程如上,现仅将回来的feature rows的值作为对比,如下图

 

发现读回来的值是不一样的file value=1,这个应该是关掉了IIC_PORT,但是默认的情况不是打开的吗?是什么操作是它被关掉的呢?然后查了手册,手册写的默认值如下图,感觉好奇葩file value=1不是关掉IIC_PORT吗?怎么手册给出来的值是file value=1HW DEFAULT中确是ENBALE

疑问自答:1.读回来的file value=1是关掉IIC_PORT的意思,芯片默认确实是打开的,但是软件默认是关闭的IIC_PORT,而且下载了一段不加EFB去打开IIC_PORT的代码,所以IIC_PORT自然而然就关掉了,所有IIC无法在线升级就可以理解了,因为IIC_PORT被关掉了啊。

2.写文档的人瞎搞,截出来的图不是空白芯片的值,只是一个feature rows的例子而已。

 

 

 

 

3.尝试了用jtag对芯片进行擦除操作,再进行在线加载,发现也是无法在线加载的,表现为没有发响应,iic没有通信上(手册上说这种方式可以实现在线升级的,草)。操作流程如下:

 

擦除之后用jtag回读回来的feature rows的值如下

 

 

通过对比可以发现,FILE Value=0的时候且在有程序的前提下,是可以实现在线加载的。但是这个官网数据手册说的不一致,数据手册说空白芯片和擦除的情况下是可以进行在线加载的。所以得继续查问题______————————________

 

经过对比调试发现,有程序在芯片时,program=1diable,IIC_PORT=0(enable);空白芯片时program=0enable, IIC_PORT=0(enable),如下图。

 

所以尝试测试在有程序的情况下,把Program改为enable,假如修改为Program改为enable之后,无法实现在线升级了,那么问题就明了了,下图是如何把Program改为enable

 

修改了之后发现确实无法升级了那么是不是可以说明是Programenable使得无法进行在线升级呢?为了确保万无一失,我们再进行一个测试。在芯片没有程序的情况下,将Program改为disable。这个怎么改呢?有点学问。首先你不能烧程序进去,因为烧了程序进去就不是空白芯片了,其次你还要修改program的值,而且只改一位。不幸中的万幸,软件可以进行只加载Feature row,也就是说我可以通过通过软件生成带程序的而且programdisableJED,然后加载JED的时候只进行feature row的加载,不加载用户逻辑。操作如下

操作完上述过程相当于空白芯片,Program改为disable,嵌入式系统那边跑起来,惊奇发现测试灯亮了,亮了(用于测试升级的代码),妈呀成功了。

 

以上说明什么问题,lattice给的升级参考嵌入式代码有问题,有BUG。为什么这样说呢?因为我们用2B线测试过,不管在什么情况下,都是可以program的,说明不管Programdisabe还是enable,不管是不是空白芯片,都是可以program的。唯一的不就是一个通过C代码配合CPUprogram,一个是通过线去加载,硬件完全一样。

 

 

通过上述可以明显知道是lattice提供的C代码有bug,那么在线升级的时候怎么解决呢?做了上面的测试,思路很明显出来了。生成两份.ied .iea,第一份做事情是将空白芯片的Program改为disable,第二份做的事情是加载用户逻辑,当然客户嵌入式那边也要做两份Makefile。为了修复这个BUG,如下做出详细操作流程。

 

生成第一份.ied .iea,目的Program改为disable

 

做好下图设置之后先生成.jed

 

 

下面这一步非常重要一定要选对选只加载feature的值这就相当于只把program改为diable而不加载用户程序,然后狂点next就可以生成了。

 

生成第二份.ied .iea,目的是生成加载的用户程序,流程在最开始就说了,不再累赘。

 

用两份IED IEA,可以实现空白芯片的加载,但是在客户多次尝试之后发现新的问题:芯片里面有程序的时候,用用两份IED IEA是无法在线加载的!!!!!!!现在出现了两种情况:有程序的时候,只能用有用户数据的IEA IED去升级,没有程序的时候需要用两份IEA IED去升级。叫客户将就着用,但是客户死活不肯。接下来的解决思路:通过CPU发读Read FEABITs (0xFB)指令PROGRAMN的值读回来PROGRAMN=1,说明是有程序(有feature row)在芯片的,这时候让CPU去加载两份IEA IEDPROGRAMN=0,说明是没有程序(擦除过或者是出厂的空白芯片)在芯片的,这时候让CPU只加载一份包含用户逻辑数据的IEA IED。这个方法就需要用户去写C,试了好几天大华也没写出来。另辟蹊径,看了各种手册,发现有程序(有feature row)的时候,写两份IEA IED无法实现在线加载,原因是加载第一份的时候feature row已经被写过一次,在不擦除去情况下,再去写feature row就会导致芯片hold死,从而导致芯片升级不成功。那么解决思路就出来,无论哪种情况,都用两份IEA IED实现在线加载,但是在加载第一份IEA IED(仅仅包含feature row的值)之前,先erase一次feature row,问题就可以解决了。但是问题又来了,erase feature row怎么操作呢?是否有这个指令让cpuerase feature row。幸运的是,在文档中给出了这个指令。

仔细想想这个方法还是不够简洁,既然可以通过cpu去发erase feature row,那么软件生成的时候应该也有对应的选型,然后在软件中找到对应的,感觉像自己想要的选型,进行尝试。非常有意思,一把就试成功,不管有没有程序,不管是否断电,在生成第一份IEA IED的时候,选择I2C Erase Program Verify Feature一切搞定(因为这个选项包含erase feature row),选项如下截图。

总结IIC升级步骤:

1)调用EFBIIC_PORT口打开

2)生成第一份IEA IED,目的disable programn而且应该选择I2C Erase Program Verify Feature(这选项会更新Feature Row的值的),仅仅更新Feature Row

3)生成第二份IEA IED,目的生成用户数据,而且应该选择I2C Erase,Program,Verify(这选项是不会更新Feature Row的值的),仅仅更新用户逻辑

 

 

 

结束语干这行的,一定要有怀疑的精神,怀疑的不仅仅是客户芯片厂家也是完全可能出现问题的,厂家的bug也是正常的厂家没有BUGFAE就没有存在的意义了。上述发现的BUG不是芯片本身的bug,是提供的参考C代码的bug.

 

posted on 2017-02-25 16:24  小诸葛叶  阅读(3770)  评论(1编辑  收藏  举报