I2C core with Zpuino


andyfive

Recommended Posts

Hello everyone,

I came across this page the other day describing how to add an I2C core to the Zpuino. Unfortunately, I am very new to FPGAs and VHDL and really have no idea how to put this to use. Could someone point me in the correct direction? As I understand it, I must add the 3 vhdl files to my zpuino project, edit papilio_top.vhdl and add a component called 'i2c_master_top', add the i2c_master_top to one of the wishbone slots, and then finally add the pps stuff at the end? Is this correct? Sorry for the lack of proper terms, as I said I am very new to this.  Thanks in advance for any help that anyone can offer. 

 

-AndyFive  :)

Link to comment
Share on other sites

I2C cannot work with PPS, due to the required tri-state mode of operation, so you have to assign fixed pins to it.

 

Which board are you using ?

 

See this for an example: https://github.com/alvieboy/ZPUino-HDL/tree/work-0200/zpu/hdl/zpuino/boards/papilio-pro/S6LX9/variants/rgbctrl

  component i2c_master_top is    generic(            ARST_LVL : std_logic := '0'                   -- asynchronous reset level    );    port   (            -- wishbone signals            wb_clk_i      : in  std_logic;                    -- master clock input            wb_rst_i      : in  std_logic := '0';             -- synchronous active high reset            arst_i        : in  std_logic := not ARST_LVL;    -- asynchronous reset            wb_adr_i      : in  std_logic_vector(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            id            : out slot_id;            -- 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;                    -- i2c clock line input  signal scl_pad_o     : std_logic;                    -- i2c clock line output  signal scl_padoen_o  : std_logic;                    -- i2c clock line output enable, active low  signal sda_pad_i     : std_logic;                    -- i2c data line input  signal sda_pad_o     : std_logic;                    -- i2c data line output  signal sda_padoen_o  : std_logic;                    -- i2c data line output enable, active low

Pin connections: A0->SCL, A1->SDA

--  pin00: IOPAD port map(I => gpio_o(0),O => gpio_i(0),T => gpio_t(0),C => sysclk,PAD => WING_A(0) );--  pin01: IOPAD port map(I => gpio_o(1),O => gpio_i(1),T => gpio_t(1),C => sysclk,PAD => WING_A(1) );  pin00: IOBUF port map(I => scl_pad_o, O => scl_pad_i, T => scl_padoen_o, IO => WING_A(0) );  pin01: IOBUF port map(I => sda_pad_o, O => sda_pad_i, T => sda_padoen_o, IO => WING_A(1) );

And instantiation:

  slot13: i2c_master_top  port map (    wb_clk_i      => wb_clk_i,    wb_rst_i      => wb_rst_i,    wb_dat_o      => slot_read(13)(7 downto 0),    wb_dat_i      => slot_write(13)(7 downto 0),    wb_adr_i      => slot_address(13)(4 downto 2),    wb_we_i       => slot_we(13),    wb_cyc_i      => slot_cyc(13),    wb_stb_i      => slot_stb(13),    wb_ack_o      => slot_ack(13),    wb_inta_o     => slot_interrupt(13),    scl_pad_i     => scl_pad_i,    scl_pad_o     => scl_pad_o,                    -- i2c clock line output    scl_padoen_o  => scl_padoen_o,                    -- i2c clock line output enable, active low    sda_pad_i     => sda_pad_i,                    -- i2c data line input    sda_pad_o     => sda_pad_o,                    -- i2c data line output    sda_padoen_o  => sda_padoen_o                     -- i2c data line output enable, active low  );  slot_read(13)(31 downto 8)<=(others => '0');
Link to comment
Share on other sites

Hello Alvie,

Thanks for your reply! I am using a papilio pro, but I've also got a papilio one. The link that I posted above took care of the tri state problem by assigning 4 pins to pps, and then used a couple resistors to tie them together as 'sda' and 'scl'. That being said, no pps is not a deal breaker for me. I don't mind at all just choosing 2 pins and have them permanently set. I played around with trying to get everything to work last night, however I was not successful. Tonight after work, I'll give it another try with the information that you provided. Thanks so much!  :)

 

-AndyFive

Link to comment
Share on other sites

Wow, this is so incredibly frustrating. I looked at the example that you provided, and tried to implement it myself. I think that I understand what I've gotta do, but no matter what I try, I keep getting random errors. I address said errors, only to be presented with more nonsensical errors. As I said earlier, I am new to this however I am very technically minded, and a fast learner. How are people supposed to learn this stuff? Unfortunately, the only documentation that I've been able to find seems to be geared at those who are FPGA experts. Please forgive my negativity, but I'm ready to give up on FPGAs in general.  :( I've wasted hours trying to get this to work. It shouldn't be this difficult.

Link to comment
Share on other sites

Hey AndyFive,

 

It might be easier if you download the latest version of the ZAP IDE and use the schematic editor to build your system with I2C. There is an I2C symbol under the .Papilio Untested category.

 

I made a quick video to get you started:

 

I haven't looked too closely at the I2C symbol yet, I'll see if I can try to setup an example using the Wii Chuck soon.

 

Jack.

Link to comment
Share on other sites

Hello again Gentlemen,

Thank you both for your replies. Using the example that Alvie posted, I was able to get I2C up and running on the papilio one. However, when I try to use the same code, but build for the papilio pro, I get all kinds of errors. I will post these errors as soon as I get a chance, and hopefully one of you FPGA gurus can point me in the right direction. Meanwhile, without seeing the specific errors, is there any particular reason that this wouldnt work for the pro? I started with the vanilla zpuino in both cases, but only the one will work?  :)

Jack: I really love the idea of the schematic library! I played around with it a bit earlier, however I don't know how/where to connect the various pins of the i2c core. Actually, Other than adding a wing schematic to the sketch, I am not actually sure how to connect any core pins to the gpio. Is there a video or tutorial available for this? I would really like to produce a series of videos when I am proficient enough, as I believe that the biggest hurdle to a beginner is finding tutorials and documentation geared towards the beginner.

Alvie: Is there any plans to include I2C by default with the next zpuino release? I have been meaning to check out the 2.0 beta, but haven't had a chance yet.

Anyway gentlemen, thank you both again for your replies! Having experts who are willing to answer questions from a noob like myself is really priceless! Here's to hoping that the Papilio specifically, and FPGAs in general grow to be as popular as the arduino!  :D

 

-AndyFive

Link to comment
Share on other sites

Archived

This topic is now archived and is closed to further replies.