Programmable Devices
CPLDs, FPGAs, SoC FPGAs, Configuration, and Transceivers
20803 Discussions

Integrate the Opencores's I2C ip into SOPC

Altera_Forum
Honored Contributor II
2,538 Views

Hello: 

 

I gathered 2 messages about how to integrate Opencores's I2C IP into SOPC. 

And I just have got it work by following these instructions below. But one note 

is that you can not just include the header file "oc_i2c_master.h" directly. 

Please refer to Altera's application note "AN333" to wirte your own header file. 

 

 

================================================= 

you can easily connect the I2C Wishbone core to the NIOS processor  

 

1. Within SOPC builder, generate interface to user logic. 

2. Select bus interface type: avalon register slave. 

3. Add "i2c_master_top.v" design file. 

4. Read port list from file. 

5. Connect the signals as follow: 

wb_adr_i <=> address 

wb_dat_i <=> writedata 

wb_dat_o <=> readdata 

wb_we_i <=> write 

wb_stb_i <=> chipselect 

wb_cyc_i <=> chipselect 

wb_inta_o <=> irq 

wb_clk_i <=> clk 

wb_ack_o <=> waitrequest_n 

wb_rst_i <=> always0 

arst_i <=> reset_n 

scl_pad_i <=> export 

scl_pad_o <=> export 

scl_padoen_o <=> export 

sda_pad_i <=> export 

sda_pad_o <=> export 

sda_padoen_o <=> export 

6. Under timing tab, leave the setup, wait and hold settings at 0 cycles. 

 

 

You can now access the I2C core via included "oc_i2c_master.h". 

 

======================================================== 

Original message is written by "Guido Kuhlmann" from the Opencores forum. 

reference from: (http://www.opencores.org/forums.cgi/cores/2004/04/000609

======================================================== 

 

 

If you have integrated the I2C IP from Opencores into your system correctly there are only some more steps to bring it to work. 

 

1. Insert -> Symbol ... 

2. 2x primitives -> buffer -> tri 

3. 2x primitives -> logic -> not 

4. 2x primitives -> pin -> bidir 

5. connect "scl_padoen_o" and "sda_padoen_o" to the input of the "not"-logics 

6. connect "scl_pad_o" and "sda_pad_o" to the input of the "tri"-buffers 

7. connect the output of the "not"-logics to the corresponding output-enables of the "tri"-buffers 

8. name the output of the "tri"-buffers "i2c_scl" and "i2c_sda" 

9. connect "i2c_scl" and "i2c_sda" to the corresponding inputs of the I2C IP 

10. connect "i2c_scl" and "i2c_sda" to "bidir"-pins 

 

That&#39;s it! 

 

======================================================== 

Original message is written by "niosIIuser" from the Nios forum. 

reference from : (here (http://www.niosforum.com/forum/index.php?act=st&f=2&t=590&hl=opencore)) 

========================================================
0 Kudos
16 Replies
Altera_Forum
Honored Contributor II
1,640 Views

Thank U!! 

 

I will try .....
0 Kudos
Altera_Forum
Honored Contributor II
1,640 Views

The I2C slave model of OC is not synthesizable, but the master seems to work.

0 Kudos
Altera_Forum
Honored Contributor II
1,640 Views

Hi, 

 

I looked for the AN 333 and it&#39;s no longer available, does anyone have a modified oc_i2c_master.h file or some hints on how to modify the .h file to work with SOPC builder? 

 

Thanks
0 Kudos
Altera_Forum
Honored Contributor II
1,640 Views

 

--- Quote Start ---  

originally posted by tek66tim@Jun 2 2005, 04:08 PM 

hi, 

 

i looked for the an 333 and it&#39;s no longer available, does anyone have a modified oc_i2c_master.h file or some hints on how to modify the .h file to work with sopc builder? 

 

thanks 

--- Quote End ---  

 

There is a new document present on Altera web site who describe how to create a NIOS II / SOPC Builder component: 

Quartus II Development Software Handbook v5.0 Volume 4: SOPC Builder. 

It is available here (http://www.altera.com/literature/hb/qts/qts_qii5v4.pdf

or go to quartus literature page (http://www.altera.com/literature/lit-qts.jsp). 

 

I add opencores I2C master component to SOPC Builder, but to do that I have created an additionnal VHDL file because SOPC Builder seems to have problem with the STD_LOGIC GENERIC parameters. 

 

-------------------------------------------- -- Description VHDL d&#39;une interface I2C maître -- FM 28/06/2005 -------------------------------------------- -- Déclaration des bibliothèques library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_arith.all; -------------------------------------------- -- Déclaration de l&#39;entité entity oc_i2c_master_top is    port(        -- Signaux du bus Avalon        address:       in unsigned(2 downto 0);        readdata:      out std_logic_vector(7 downto 0);        writedata:     in std_logic_vector(7 downto 0);        write:         in std_logic;        chipselect:    in std_logic;        clk:           in std_logic;                     -- Entrée horloge        reset_n:       in std_logic;                     -- Entrée de RESET (actif à l&#39;état bas)        irq:           out std_logic;        waitrequest_n: out std_logic;                -- Sortie I2C        scl: inout std_logic;                -- i2c clock line output        sda: inout std_logic                 -- i2c data line output     ); end oc_i2c_master_top; -------------------------------------------- -- Déclaration de l&#39;architecture comportementale "algorithmique" de l&#39;entité architecture bhv of oc_i2c_master_top is component i2c_master_top is     generic(  ARST_LVL : std_logic                          -- asynchronous reset level     );     port (  -- wishbone signals  wb_clk_i  : in  std_logic;                    -- master clock input  wb_rst_i  : in  std_logic;                    -- synchronous active high reset  arst_i    : in  std_logic;                    -- asynchronous reset  wb_adr_i  : in  unsigned(2 downto 0);         -- lower address bits  wb_dat_i  : in  std_logic_vector(7 downto 0); -- Databus input  wb_dat_o  : out std_logic_vector(7 downto 0); -- Databus output  wb_we_i   : in  std_logic;               -- Write enable input  wb_stb_i  : in  std_logic;                    -- Strobe signals / core select signal  wb_cyc_i  : in  std_logic;               -- Valid bus cycle input  wb_ack_o  : out std_logic;                    -- Bus cycle acknowledge output  wb_inta_o : out std_logic;                    -- interrupt request output signal  -- i2c lines  scl_pad_i     : in  std_logic;                -- i2c clock line input  scl_pad_o     : out std_logic;                -- i2c clock line output  scl_padoen_o  : out std_logic;                -- i2c clock line output enable, active low  sda_pad_i     : in  std_logic;                -- i2c data line input  sda_pad_o     : out std_logic;                -- i2c data line output  sda_padoen_o  : out std_logic                 -- i2c data line output enable, active low     ); end component; signal scl_pad_i     : std_logic; signal scl_pad_o     : std_logic; signal scl_padoen_o  : std_logic; signal sda_pad_i     : std_logic; signal sda_pad_o     : std_logic; signal sda_padoen_o  : std_logic; begin    i2c_top : i2c_master_top        generic map ( ARST_LVL => &#39;0&#39;)        port map (            wb_adr_i  => address,            wb_dat_i  => writedata,            wb_dat_o  => readdata,            wb_we_i   => write,            wb_stb_i  => chipselect,            wb_cyc_i  => chipselect,            wb_inta_o => irq,            wb_clk_i  => clk,            wb_ack_o  => waitrequest_n,            wb_rst_i  => &#39;0&#39;,            arst_i    => reset_n,                        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        );    scl <= scl_pad_o when (scl_padoen_o = &#39;0&#39;) else &#39;Z&#39;;    sda <= sda_pad_o when (sda_padoen_o = &#39;0&#39;) else &#39;Z&#39;;    scl_pad_i <= scl;    sda_pad_i <= sda; end architecture bhv; 

 

Now I am working on I2C software driver, the basic functions are working. I can read and write I2C devices, now I have to clean up my code.
0 Kudos
Altera_Forum
Honored Contributor II
1,640 Views

Hi: 

I have designed a IPcore which is belown: 

 

library ieee; 

use ieee.std_logic_1164.all; 

 

entity ad574 is 

 

port(D :IN STD_LOGIC_VECTOR(15 DOWNTO 0);  

address: in std_logic_vector(1 downto 0);  

CLK ,STATUS,read: IN STD_LOGIC;--״̬»úʱÖÓCLK£¬AD574״̬ÐźÅSTATUS 

byteenable: in std_logic_vector(3 downto 0); 

chipselect: in std_logic; 

CE,CS,A0,RC,K12X8: OUT STD_LOGIC; --AD574¿ØÖÆÐźŠ

Q : out STD_LOGIC_VECTOR(31 DOWNTO 0)); 

end ad574; 

 

architecture behav of ad574 is 

type state is (st0, st1, st2, st3,st4); 

signal current_state,next_state :state:=st0; 

signal data_reg_select: std_logic; 

signal control_reg_select: std_logic; 

SIGNAL data_reg : STD_LOGIC_VECTOR(31 DOWNTO 0); 

SIGNAL lock: STD_LOGIC;  

begin 

K12X8 <= &#39;1&#39;;  

process(address,chipselect)  

begin  

data_reg_select<=&#39;0&#39;; 

control_reg_select<=&#39;0&#39;; 

if chipselect=&#39;1&#39; then 

case address is  

when "00" => data_reg_select<=&#39;1&#39;; 

when "01" => control_reg_select<=&#39;1&#39;; 

when others => null; 

end case; 

end if; 

end process;  

 

process(current_state,status) --»ù±¾ÈÎÎñÉè¼Æ(״̬ÄÚÐźű仯) 

begin 

case current_state is 

when st0 =>CE<=&#39;0&#39;;CS<=&#39;1&#39;; A0<=&#39;1&#39;;RC<=&#39;1&#39;;LOCK<=&#39;0&#39;;next_state <= st1; 

when st1 =>CE<=&#39;1&#39;;CS<=&#39;0&#39;; A0<=&#39;0&#39;;RC<=&#39;0&#39;;LOCK<=&#39;0&#39;; next_state <= st2; 

when st2 =>CE<=&#39;1&#39;;CS<=&#39;0&#39;; A0<=&#39;0&#39;;RC<=&#39;0&#39;;LOCK<=&#39;0&#39;;  

IF (STATUS=&#39;1&#39;) THEN next_state <= st2;  

ELSE next_state <= st3;  

END IF ; 

when st3 =>CE<=&#39;1&#39;;CS<=&#39;0&#39;; A0<=&#39;0&#39;;RC<=&#39;1&#39;;LOCK<=&#39;0&#39;; next_state <= st4; 

when st4 =>CE<=&#39;1&#39;;CS<=&#39;0&#39;; A0<=&#39;0&#39;;RC<=&#39;1&#39;;LOCK<=&#39;1&#39;; next_state <= st0; 

when others =>CE<=&#39;0&#39;;CS<=&#39;1&#39;; A0<=&#39;1&#39;;RC<=&#39;1&#39;;LOCK<=&#39;0&#39;;next_state <= st0; 

end case; 

end process; 

 

PROCESS (clk,control_reg_select,chipselect) --¿ØÖƼĴæÆ÷¿ØÖÆת»»¹ý³Ì  

BEGIN 

IF ( clk&#39;EVENT AND clk=&#39;1&#39;) THEN 

if (control_reg_select and chipselect)=&#39;1&#39; then 

current_state <= next_state;  

end if; 

END IF; 

END PROCESS ;  

 

process(lock) --Êý¾Ý¿ØÖƼĴæÆ÷²Ù×÷  

BEGIN 

IF LOCK=&#39;1&#39; AND LOCK&#39;EVENT THEN  

if byteenable(0)=&#39;1&#39; then data_reg(7 downto 0)<=d(7 downto 0);end if;data_reg<=d; 

if byteenable(1)=&#39;1&#39; then data_reg(15 downto 8)<=d(15 downto 8);end if; 

if byteenable(2)=&#39;1&#39; then data_reg(23 downto 16)<="00000000";end if; 

if byteenable(3)=&#39;1&#39; then data_reg(31 downto 24)<="00000000";end if; 

END IF; 

END PROCESS ; 

 

process(read,clk,data_reg_select,chipselect) --NIOS×ÜÏßͨѶ 

begin 

if clk&#39;event and clk=&#39;1&#39; then 

if (read and data_reg_select and chipselect)=&#39;1&#39; then  

Q <=data_reg;  

else 

Q<=(others=>&#39;Z&#39;); 

end if; 

end if ; 

end process; 

 

END behav; 

 

 

now I integerate the IP to sopc , and the base address of the IP is :0x02000008 and the end address is 0x0200000f , the generation of the system is successful . but when I built the software about the system above on the NiosII IDE , but there is error and display that the range of the IP ---ad16bit is out of the range of the address , what is it? while I change the "Q : out STD_LOGIC_VECTOR(31 DOWNTO 0));" to " Q : out STD_LOGIC_VECTOR(15 DOWNTO 0)); " the error is disappeared. why? 

and how can I write the drivers of the IP core ? who can help me?
0 Kudos
Altera_Forum
Honored Contributor II
1,640 Views

I have done the process as the trout writes, and generated a symbol named I2cCore. The I2cCore occupys 32 8-bit address. But in the 32 addresses, I find that I can only write 4 of them, why? I am confused that which are the registers? Is there anything I omitted? By the way, in the nios2 core, I have integrated cup, onchip_memory, timer, pio, epcs_controller, jtag and I2cCore. Does anyone can help me?

0 Kudos
Altera_Forum
Honored Contributor II
1,640 Views

Hi, 

I can&#39;t succesfully implement I2C opencore by Component Editor.  

 

First, for the Verilog version, when I added i2c_master_top.v, the Errors Analyzing found wrote: can&#39;t open Verilog Design File "i2c_master_defines.v", but this file is near i2c_master_top.v Why? 

 

Second, for the VHDL version is no errors, but I can&#39;t find "always0" in "Signal Type" column (in Interface to User Logic it was), but I can resolve this problem by type "external" and out of SOPC component tie to ground (it is good idea or not?). 

 

But what about two chipselects? In Interface To User Logic I can set two chipselects signal but in Component Editor I can&#39;t? What I have to do? 

Thank you for your advise
0 Kudos
Altera_Forum
Honored Contributor II
1,640 Views

Hi, If you get the document on the I2C core at opencores, it says you can just export the reset pin and tie it low. 

 

With the two chipselects, just ignore the error - SOPC just connects both to chipselect anyway (you can see this in the ptf) 

 

but, you will find it will not compile in quartus Because of the &#39;generic&#39; problem covered above. http://forum.niosforum.com/work2/style_emoticons/<#EMO_DIR#>/sad.gif  

 

If you repeat the process using the &#39;oc_i2c_master_top&#39; provided by FMousset above, you not only get a core that is easier to attach to the NIOS but it compiles and there is no need to mess about with the tristate buffers etc. 

 

So the way I made it work is as follows: 

 

1) I downloaded " i2c_master_bit_ctrl.vhd, i2c_master_byte_ctrl.vhd and i2c_master_top.vhd" from open cores 

 

2) I pasted FMoussets code into notepad and called it oc_i2c_master_top.vhd (NO CAPITAL LETTERS) Thanks to FMousset for the code! 

 

3) In SOPC builder I created a new component using the oc_i2c_master_top as the VHDL source file. No other changes are required, as all the signals are already set up http://forum.niosforum.com/work2/style_emoticons/<#EMO_DIR#>/smile.gif  

 

4) Put the newly created &#39;oc_i2c_master&#39; into your sopc and generate. 

 

5) Attach two bidir pins to the scl and sda outputs from the sopc and you are done! 

 

We are running it in a 2C35 with no problems (so far!) http://forum.niosforum.com/work2/style_emoticons/<#EMO_DIR#>/smile.gif  

 

 

Hope this helps
0 Kudos
Altera_Forum
Honored Contributor II
1,640 Views

 

--- Quote Start ---  

originally posted by tom@mrg@May 15 2006, 03:16 AM 

hi, if you get the document on the i2c core at opencores, it says you can just export the reset pin and tie it low. 

 

with the two chipselects, just ignore the error - sopc just connects both to chipselect anyway (you can see this in the ptf) 

 

But[/b], you will find it will not compile in quartus Because of the &#39;generic&#39; problem covered above. http://forum.niosforum.com/work2/style_emoticons/<#EMO_DIR#>/sad.gif  

 

If you repeat the process using the &#39;oc_i2c_master_top&#39; provided by FMousset above, you not only get a core that is easier to attach to the NIOS but it compiles and there is no need to mess about with the tristate buffers etc. 

 

So the way I made it work is as follows: 

 

1) I downloaded " i2c_master_bit_ctrl.vhd, i2c_master_byte_ctrl.vhd and i2c_master_top.vhd" from open cores 

 

2) I pasted FMoussets code into notepad and called it oc_i2c_master_top.vhd (NO CAPITAL LETTERS) Thanks to FMousset for the code! 

 

3) In SOPC builder I created a new component using the oc_i2c_master_top as the VHDL source file. No other changes are required, as all the signals are already set up http://forum.niosforum.com/work2/style_emoticons/<#EMO_DIR#>/smile.gif  

 

4) Put the newly created &#39;oc_i2c_master&#39; into your sopc and generate. 

 

5) Attach two bidir pins to the scl and sda outputs from the sopc and you are done! 

 

We are running it in a 2C35 with no problems (so far!) http://forum.niosforum.com/work2/style_emoticons/<#EMO_DIR#>/smile.gif  

 

 

Hope this helps 

<div align='right'><{post_snapback}> (index.php?act=findpost&pid=15374) 

--- Quote End ---  

[/b] 

--- Quote End ---  

 

 

http://via.fps-tech.org/svn/fpga/cores/i2c_master/trunk/ (http://via.fps-tech.org/svn/fpga/cores/i2c_master/trunk/

 

A ready made avalon component - no need to do all of this.
0 Kudos
Altera_Forum
Honored Contributor II
1,640 Views

Hi. Should you give the open cores i2c please? 

And where is possible to find the CODE on C language for that? I tried the one on Portable Reference Platform but it&#39;s not right. 

Many thanks
0 Kudos
Altera_Forum
Honored Contributor II
1,640 Views

 

--- Quote Start ---  

originally posted by tonnoplast@Jan 26 2007, 05:32 AM 

hi. should you give the open cores i2c please? 

and where is possible to find the code on c language for that? i tried the one on portable reference platform but it&#39;s not right. 

many thanks 

<div align='right'><{post_snapback}> (index.php?act=findpost&pid=20882) 

--- quote end ---  

 

--- Quote End ---  

 

I think using a hardware i2c core is over-killed to the simple problem. You can use pio to access i2c with a simple software approach. You can look at the i2c bus or chips spec. There are bitbanging pio drivers on Linux. Most PC motherboards use pio to access i2c/smbus, too.
0 Kudos
Altera_Forum
Honored Contributor II
1,640 Views

Hi. 

So you sugggest me to use a PIO for interfacing the couple of I2C\SCCB wires instead creating a HDL block? Do you mean that? Obviously i have to create drivers for I2C registers. 

I tried to use,as i said you, Port Ref Plat opencore i2c master and it doesn&#39;t function.Further i tried 3 different I2C software version whith that and again it didin&#39;t function. Probably you&#39;re right. 

Many thanks.
0 Kudos
Altera_Forum
Honored Contributor II
1,640 Views

Yes, I suggest using GPIO and software instead of hardware. Most i2c tasks are only initialization. They are not speed or performance critical. 

 

You will need to use a osc scope or siganl tap to monitor your io pins. Check pins toggles and senses. You may find a lot of software i2c drivers, some are for 8051. Once you understand the timing, you can make one easily.
0 Kudos
Altera_Forum
Honored Contributor II
1,640 Views

Many thanks hippo. 

At first,what&#39;s a GPIO? 

In my case,i must create a software interface for communicating with an Omnivision Camera(OV6620) which uses not just I2C but SCCB.I read that this difference it&#39;s only for respecting Philips&#39;s"copyright" . Do you know something about that? Are some radical differences between these interfaces or not? 

I&#39;m a beginner with Nios II and i thought that a software for an interface,for example for SCCB, was "global" for every kind of SCCB devices. Would possible to use ready made software? Can you help me ? 

Thanks again.
0 Kudos
Altera_Forum
Honored Contributor II
1,640 Views

Hi again hippo. 

if you can, please answer this question too. 

Always about PIO, i&#39;d like to know if i must edit altera_avalon_pio_regs.h. for adding SCCB\I2C registers. In some way i have to add these registers,am i wrong? Doing that, every PIOs i&#39;m using will have this new build? In other way how to access these registers and create this interface? 

Many thanks again
0 Kudos
Altera_Forum
Honored Contributor II
1,640 Views

OV&#39;s SCCB is I2C. GPIO is general prupose PIO. I think there are a lot of things you need to learn. FIrst you should study some PIO exercises, such as LED, button switch etc. Next you can find some application note on I2C from www.nxp.com. Then you can build your own I2C interface routines. Get some reading about interface and embeded programming books. You&#39;d learn from the bottom up. 

 

Sorry, I cannot help you step by step. I posted a i2c-gpio driver for uClinux, but I don&#39;t know if it help.
0 Kudos
Reply