移植OPENCORES上的I2C MASTER到AXI接口处理器层面实现驱动 之一

来源:互联网 发布:html5权威指南 源码 编辑:程序博客网 时间:2024/05/16 19:56




由于之间就用过OPENCORES上的I2C MASTER,所以对他的接口时序以及处理器方面的驱动非常了解。这里主要做的工作是移植。





这个IP核来自www.opencores.org 是经过OPENCORES认证的IP核。




这个IP是采用了WISHBONE互联总线标准,是最简单最基本的互联总线,因此很容易移植上AXI_LITE接口。以下代码是我以前做的一个项目的例化代码,


 /* i2c_master_top U1(wb_clk_i ( ), wb_rst_i ( ), arst_i ( ), wb_adr_i ( ), wb_dat_i ( ), wb_dat_o ( ),wb_we_i ( ), wb_stb_i ( ), wb_cyc_i ( ), wb_ack_o ( ), wb_inta_o ( ),.scl_pad_i ( ), .scl_pad_o ( ), .scl_padoen_o ( ), .sda_pad_i ( ), .sda_pad_o ( ), .sda_padoen_o( ));*/

我们看到非常简单,下面做的工作就是直接简历AXI_LITE外设实现实例化此模块并将接口处理好。


下面做的主要工作就是接口的转换,将WISHBONE接口转成AXI LITE 接口。

1,WISHBONE只读写地址是一个,而AXI_LITE接口的读写地址是两个分开。这点要对I2C MASTER进行修改。

2,这里I2C_MASTER的WISHBONE用三位地址长度,所以我们也用三位的AXI_LITE地址总线。

3,这里I2C_MASTER的WISHBONE数据位长度是8位,而AXI_LITE 总线是32位数据长度。

4,对于I2C_MASTER来说不会挂起总线,任何时候的读和写都是READY的,因此就简单处理好读写时序就可以。

5,写寄存器时,地址,数据以及写信号同时出现在时钟的上升边缘,就完成写操作,所以我们做接口转换时候找到数据,地址,和写信号就行。

6,读数据的时候,我们加进去读地址,数据在下一周期出现在WB_DOUT。

7,I2C接口的 scl_pad_i, scl_pad_o, scl_padoen_o, sda_pad_i, sda_pad_o, sda_padoen_o 信号直接引出来到顶层处理。

8,wb_stb_i, wb_cyc_i, 两个原来的WISHBONE信号直接接1就可以。


简单修改一下原来WISHBONE接口的顶层文件,加上读寄存器地址,去掉多余的控制信号,接口成:

module i2c_master_top(wb_clk_i, wb_rst_i, //arst_i,wb_adr_i_wr,wb_adr_i_rd, wb_dat_i, wb_dat_o,wb_we_i, //wb_stb_i, wb_cyc_i, //wb_ack_o, wb_inta_o,scl_pad_i, scl_pad_o, scl_padoen_o, sda_pad_i, sda_pad_o, sda_padoen_o );

我们直接编写AXI LITE外设,步骤在我给大家的视频已经详细提过,这里注意设置8个寄存器。按照模板生产,之后加入做了简单修改后的2C_MASTER控制代码:

// Add user logic herei2c_master_top  u1(        .wb_clk_i( S_AXI_ACLK  ),         .wb_rst_i( ~S_AXI_ARESETN ),         .wb_adr_i_wr( axi_awaddr[ADDR_LSB+OPT_MEM_ADDR_BITS:ADDR_LSB] ),        .wb_adr_i_rd( axi_araddr[ADDR_LSB+OPT_MEM_ADDR_BITS:ADDR_LSB] ),         .wb_dat_i(  S_AXI_WDATA[7:0]),         .wb_dat_o( axi_rdata ),        .wb_we_i( slv_reg_wren  ),         .wb_inta_o(  ),        .scl_pad_i(  scl_pad_i),         .scl_pad_o( scl_pad_o ),         .scl_padoen_o( scl_padoen_o ),         .sda_pad_i( sda_pad_i ),         .sda_pad_o( sda_pad_o ),         .sda_padoen_o (sda_padoen_o  )         );// User logic ends
封装好以后就是现在的样子。


我们看到非常简介明了。这里没有引出中断,如果要引出并使用的画,要在I2C MASTER里面读明白中断是否保持,从而选择是边缘触发还是电平触发。我不是很倾向于使用中断,因为会将整个系统搞得不好预测,尤其是中断的丢失有时候危害是致命的。有些场合必须中断比如使用LWIP协议,就需要有中断来处理数据,如果用户再加上一个或多个中断,如果添加进来的中断优先级高,可能造成LWIP中断地址,如果添加进来的优先级低,可能造成用户优先级降低。另外中断一般很难在线调试,很多问题在实验没有出现,到用户现场就出现了。所以不是偶发时间或者是用轮询能及时处理的,不建议使用中断。(中断说得有点多哈)。



这样IP核做好了,下步就是调用这个IP并编写C程序驱动起来这个控制器。








阅读全文
0 0
原创粉丝点击