EmbDev.net

Forum: FPGA, VHDL & Verilog Can Someone Help Me Write an I2C Controller


von Joe D. (paparit432)


Rate this post
useful
not useful
It should be a an I2C Controller than can perform a single byte write. 
Compensation may be considered

von PittyJ (Guest)


Rate this post
useful
not useful
Tell us, what you already know and have.
How far are you with your current code?
What is the problem in detail?

von Martin (Guest)


Rate this post
useful
not useful
Do you have to write it on your own?
Otherwise have a look at: http://opencores.org/project,i2c

von Lothar M. (Company: Titel) (lkmiller) (Moderator)


Rate this post
useful
not useful
Joe Daddy wrote:
> It should be a an I2C Controller than can perform a single byte write.
I have one written in Assembler, runing on a NEC uPD78017663A.
Will that be ok?

von Joe D. (paparit432)


Rate this post
useful
not useful
1
LIBRARY ieee;
2
USE ieee.std_logic_1164.all;
3
USE ieee.std_logic_unsigned.all;
4
5
ENTITY i2c_master IS
6
  GENERIC(
7
    input_clk : INTEGER := 50_000_000; --input clock speed from user logic in Hz
8
    bus_clk   : INTEGER := 400_000);   --speed the i2c bus (scl) will run at in Hz
9
  PORT(
10
    clk       : IN     STD_LOGIC;                    --system clock
11
    reset_n   : IN     STD_LOGIC;                    --active low reset
12
    ena       : IN     STD_LOGIC;                    --latch in command
13
    addr      : IN     STD_LOGIC_VECTOR(6 DOWNTO 0); --address of target slave
14
    rw        : IN     STD_LOGIC;                    --'0' is write, '1' is read
15
    data_wr   : IN     STD_LOGIC_VECTOR(7 DOWNTO 0); --data to write to slave
16
    busy      : OUT    STD_LOGIC;                    --indicates transaction in progress
17
    data_rd   : OUT    STD_LOGIC_VECTOR(7 DOWNTO 0); --data read from slave
18
    ack_error : BUFFER STD_LOGIC;                    --flag if improper acknowledge from slave
19
    sda       : INOUT  STD_LOGIC;                    --serial data output of i2c bus
20
    scl       : INOUT  STD_LOGIC);                   --serial clock output of i2c bus
21
END i2c_master;
22
23
ARCHITECTURE logic OF i2c_master IS
24
  CONSTANT divider  :  INTEGER := (input_clk/bus_clk)/4; --number of clocks in 1/4 cycle of scl
25
  TYPE machine IS(ready, start, command, slv_ack1, wr, rd, slv_ack2, mstr_ack, stop); --needed states
26
  SIGNAL  state     :  machine;                          --state machine
27
  SIGNAL  data_clk  :  STD_LOGIC;                        --clock edges for sda
28
  SIGNAL  scl_clk   :  STD_LOGIC;                        --constantly running internal scl
29
  SIGNAL  scl_ena   :  STD_LOGIC := '0';                 --enables internal scl to output
30
  SIGNAL  sda_int   :  STD_LOGIC := '1';                 --internal sda
31
  SIGNAL  sda_ena_n :  STD_LOGIC;                        --enables internal sda to output
32
  SIGNAL  addr_rw   :  STD_LOGIC_VECTOR(7 DOWNTO 0);     --latched in address and read/write
33
  SIGNAL  data_tx   :  STD_LOGIC_VECTOR(7 DOWNTO 0);     --latched in data to write to slave
34
  SIGNAL  data_rx   :  STD_LOGIC_VECTOR(7 DOWNTO 0);     --data received from slave
35
  SIGNAL  bit_cnt   :  INTEGER RANGE 0 TO 7 := 7;        --tracks bit number in transaction
36
  SIGNAL  stretch   :  STD_LOGIC := '0';                 --identifies if slave is stretching scl
37
BEGIN
38
39
  --generate the timing for the bus clock (scl_clk) and the data clock (data_clk)
40
  PROCESS(clk, reset_n)
41
    VARIABLE count : INTEGER RANGE 0 TO divider*4; --timing for clock generation
42
  BEGIN
43
    IF(reset_n = '0') THEN               --reset asserted
44
      stretch <= '0';
45
      count := 0;
46
    ELSIF(clk'EVENT AND clk = '1') THEN
47
      IF(count = divider*4-1) THEN       --end of timing cycle
48
        count := 0;                      --reset timer
49
      ELSIF(stretch = '0') THEN          --clock stretching from slave not detected
50
        count := count + 1;              --continue clock generation timing
51
      END IF;
52
      CASE count IS
53
        WHEN 0 TO divider-1 =>           --first 1/4 cycle of clocking
54
          scl_clk <= '0';
55
          data_clk <= '0';
56
        WHEN divider TO divider*2-1 =>   --second 1/4 cycle of clocking
57
          scl_clk <= '0';
58
          data_clk <= '1';
59
        WHEN divider*2 TO divider*3-1 => --third 1/4 cycle of clocking
60
          scl_clk <= 'Z';                --release scl
61
          IF(scl = '0') THEN             --detect if slave is stretching clock
62
            stretch <= '1';
63
          ELSE
64
            stretch <= '0';
65
          END IF;
66
          data_clk <= '1';
67
        WHEN OTHERS =>                   --last 1/4 cycle of clocking
68
          scl_clk <= 'Z';
69
          data_clk <= '0';
70
      END CASE;
71
    END IF;
72
  END PROCESS;

von Joe D. (paparit432)


Rate this post
useful
not useful
The above code is what I have so far. I know it is incomplete, but I 
need the I2c to perform a single byte write and a single byte read. At 
this point I am confused on where to go from here.

von Duke Scarring (Guest)


Rate this post
useful
not useful
Do you have a testbench?
Without testbench simulation is not possible. Test on hardware Without 
simulation is like Russian roulette...

Duke

von Manni (Guest)


Rate this post
useful
not useful
>Russian roulette...
You mean, we all can die from a bad coding?

I have a question about this subject: Does anybody know about I2C 
patents a license issues? I recently was told I2C was under protection 
and has to b licensed for commercial use.

von Max (Guest)


Rate this post
useful
not useful
Atmel showed how to bypass the License, just call it twi :-)

von Joe D. (paparit432)


Rate this post
useful
not useful
I am willing to compensate anyone who is willing to assist me

von Tom (Guest)


Rate this post
useful
not useful
Do you have a requirement SPEC?
Hourly Rates for such projects are around €60,-

von Fitzebutze (Guest)


Rate this post
useful
not useful
Hi,

I've got an i2c single master-only engine ready, but it kinda requires a 
soft CPU to be useful. Basically it is a module of a System on Chip 
design.

Example access (from the soft CPU core firmware):
1
int i2c_write16(unsigned int addr, unsigned int data)
2
{
3
  MMR(I2C_Ctrl)      = 1-1; // One byte per transaction
4
  MMR(I2C_SlaveAddr) = (addr >> 15) & ~1; // Write address
5
  MMR(I2C_WData)     = (addr >> 8) & 0xff;
6
  wait_ready();
7
  MMR(I2C_WData)     = addr & 0xff;
8
  wait_ready();
9
  MMR(I2C_WData)     = data >> 8;
10
  wait_ready();
11
  MMR(I2C_WData)     = data;
12
  wait_ready();
13
14
  while ((MMR(I2C_Stat) & INACK)); // wait until stop phase reached
15
  if (MMR(I2C_Stat) & NAK) return -1; 
16
17
  return 0;
18
}

In order to draft some pecuniary house numbers of the support expenses, 
you might have to post more about the requirements (what HW it should 
support, what soft core you'd be using, etc. )
BTW: No need to worry about any licensing issues, the patent has expired 
a while ago.

Greetings,

Butze

von Joe D. (paparit432)


Rate this post
useful
not useful
To Fitzebutze,

Can you send me an email to paparit432@yahoo.com? I wanna discuss the 
I2C controller further in depth and I also want to send you additional 
documents regarding this as well?

von Joe D. (paparit432)


Rate this post
useful
not useful
Tom wrote:
> Do you have a requirement SPEC?
> Hourly Rates for such projects are around €60,-

Yes.

Send me a personal message @ paparit432@yahoo.com and we can talk 
further.

von fpgaengineer (Guest)


Rate this post
useful
not useful
is this project still open? i could provide you with a working scalable 
iwc controller offering a dynamic number of inputs and outputs 
configurable by genererics, data is stored in brams

it comes complete with testbench and implementation example for both 
xilinx and altera devices

von Joe D. (paparit432)


Rate this post
useful
not useful
fpgaengineer wrote:
> is this project still open? i could provide you with a working scalable
> iwc controller offering a dynamic number of inputs and outputs
> configurable by genererics, data is stored in brams
>
> it comes complete with testbench and implementation example for both
> xilinx and altera devices

Please email me at paparit432@yahoo.com

von Wayne Gretzky (Guest)


Rate this post
useful
not useful
You want to pay for a simple i2C?  For a fex lines of code?
Why not using OS?

von Anush Kompally (Guest)


Rate this post
useful
not useful
Hello there,

Can you tell me why the divider in the code is set to 
"(input_clk/bus_clk)/4".

von anynomous (Guest)


Rate this post
useful
not useful
because it takes various operarion frequencies into account

Please log in before posting. Registration is free and takes only a minute.
Existing account
Do you have a Google/GoogleMail account? No registration required!
Log in with Google account
No account? Register here.