1 ------------------------------------------------------------------------------ 2 -- This file is a part of the GRLIB VHDL IP LIBRARY 3 -- Copyright (C) 2003 - 2008, Gaisler Research 4 -- Copyright (C) 2008 - 2012, Aeroflex Gaisler 6 -- This program is free software; you can redistribute it and/or modify 7 -- it under the terms of the GNU General Public License as published by 8 -- the Free Software Foundation; either version 2 of the License, or 9 -- (at your option) any later version. 11 -- This program is distributed in the hope that it will be useful, 12 -- but WITHOUT ANY WARRANTY; without even the implied warranty of 13 -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 -- GNU General Public License for more details. 16 -- You should have received a copy of the GNU General Public License 17 -- along with this program; if not, write to the Free Software 18 -- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 ------------------------------------------------------------------------------- 21 -- File: I2cMaster.vhd 22 -- Author: Jan Andersson - Gaisler Research 23 -- Contact: support@gaisler.com 26 -- Generic interface to OpenCores I2C-master. This is a wrapper 27 -- that instantiates the byte- and bit-controller of the OpenCores I2C 28 -- master (OC core developed by Richard Herveille, richard@asics.ws). 31 -- 10/2012 - Ben Reese <bareese@slac.stanford.edu> 32 -- Removed AMBA bus register based interfaced and replaced with generic 33 -- IO interface for use anywhere within a firmware design. 34 -- Interface based on transactions consisting of a i2c device address 35 -- followed by up to 4 byte-reads or 4 byte-writes. 37 -- Dynamic filter and bus speed adjustment have been left in as features, 38 -- though they will probably be rarely used. 41 use ieee.std_logic_1164.
all;
47 --! @ingroup protocols_i2c 50 TPD_G : := 1 ns;
-- Simulated propagation delay 52 FILTER_G : range 2 to 512 := 126;
-- filter bit size 69 ----------------------------------------------------------------------------- 71 ----------------------------------------------------------------------------- 73 ----------------------------------------------------------------------------- 75 ----------------------------------------------------------------------------- 76 -- i2c_master_byte_ctrl IO 77 type ByteCtrlInType is record 83 din : slv(7 downto 0);
86 type ByteCtrlOutType is record 91 dout : slv(7 downto 0);
94 type StateType is (WAIT_TXN_REQ_S, 103 type RegType is record 104 byteCtrlIn : ByteCtrlInType;
110 constant REG_INIT_C : RegType := ( 117 din => (others => '0')), 118 state => WAIT_TXN_REQ_S, 125 rdData => (others => '0')));
128 -------------------------------------------------------------------------------------------------- 130 -------------------------------------------------------------------------------------------------- 131 -- Register interface 132 signal r : RegType := REG_INIT_C;
133 signal rin : RegType;
135 -- Outputs from byte_ctrl block 136 signal byteCtrlOut : ByteCtrlOutType;
137 signal iSclOEn : sl;
-- Internal SCL output enable 138 signal iSdaOEn : sl;
-- Internal SDA output enablee 146 -- Byte Controller from OpenCores I2C master, 147 -- by Richard Herveille (richard@asics.ws). The asynchronous 148 -- reset is tied to '1'. Only the synchronous reset is used. 149 -- OC I2C logic has active high reset. 158 ena => i2cMasterIn.enable,
159 clk_cnt => i2cMasterIn.prescale,
160 start => r.byteCtrlIn.start,
161 stop => r.byteCtrlIn.stop,
162 read => r.byteCtrlIn.read,
163 write => r.byteCtrlIn.write,
164 ack_in => r.byteCtrlIn.ackIn,
165 din => r.byteCtrlIn.din,
171 dout => byteCtrlOut.dout,
181 -- Fix output enable polarity 185 end generate soepol0;
189 end generate soepol1;
195 variable v : RegType;
196 variable indexVar : ;
197 begin -- process comb 200 -- byteCtrl commands default to zero 201 -- unless overridden in a state below 202 v.byteCtrlIn.start := '0';
203 v.byteCtrlIn.stop := '0';
204 v.byteCtrlIn.read := '0';
205 v.byteCtrlIn.write := '0';
206 v.byteCtrlIn.ackIn := '0';
217 when WAIT_TXN_REQ_S => 218 -- Reset front end outputs 220 -- If new request and any previous rdData has been acked. 227 v.byteCtrlIn.start := '1';
228 v.byteCtrlIn.write := '1';
231 -- Send normal 7 bit address 235 -- Send second half of 10 bit address 239 -- Send first half of 10 bit address 240 v.byteCtrlIn.din(7 downto 3) := "00000";
244 v.state := WAIT_ADDR_ACK_S;
247 when WAIT_ADDR_ACK_S => 248 if (byteCtrlOut.cmdAck = '1') then -- Master sent the command 249 if (byteCtrlOut.ackOut = '0') then -- Slave ack'd the transfer 250 if (r.tenbit = '1') then -- Must send second half of addr if tenbit set 254 -- Do read or write depending on op 262 -- Slave did not ack the transfer, fail the txn 266 v.state := WAIT_TXN_REQ_S;
270 v.state := WAIT_TXN_REQ_S;
277 v.byteCtrlIn.read := '1';
278 -- If last byte of txn send nack. 279 -- Send stop on last byte if enabled (else repeated start will occur on next txn). 282 v.state := WAIT_READ_DATA_S;
286 when WAIT_READ_DATA_S => 287 v.byteCtrlIn.stop := r.byteCtrlIn.stop;
-- Hold stop or it wont get seen 288 v.byteCtrlIn.ackIn := r.byteCtrlIn.ackIn;
-- This too 289 if (byteCtrlOut.cmdAck = '1') then -- Master sent the command 290 v.byteCtrlIn.stop := '0';
-- Drop stop asap or it will be repeated 291 v.byteCtrlIn.ackIn := '0';
296 v.state := WAIT_TXN_REQ_S;
298 -- If not last byte, read another. 304 -- Write the next byte 306 v.byteCtrlIn.write := '1';
307 -- Send stop on last byte if enabled (else repeated start will occur on next txn). 310 v.state := WAIT_WRITE_ACK_S;
313 when WAIT_WRITE_ACK_S => 314 v.byteCtrlIn.stop := r.byteCtrlIn.stop;
315 if (byteCtrlOut.cmdAck = '1') then -- Master sent the command 316 if (byteCtrlOut.ackOut = '0') then -- Slave ack'd the transfer 317 v.byteCtrlIn.stop := '0';
321 v.state := WAIT_TXN_REQ_S;
323 -- If not last byte, write nother 327 -- Slave did not ack the transfer, fail the txn 331 v.state := WAIT_TXN_REQ_S;
335 when others => v.state := WAIT_TXN_REQ_S;
338 -- Must always monitor for arbitration loss 339 if (byteCtrlOut.al = '1') then 340 -- Retry the entire TXN. Nothing done has been valid if arbitration is lost. 341 -- Should probably have a retry limit. 342 v.state := WAIT_TXN_REQ_S;
348 ------------------------------------------------------------------------------------------------ 350 ------------------------------------------------------------------------------------------------ 355 ------------------------------------------------------------------------------------------------ 356 -- Signal Assignments 357 ------------------------------------------------------------------------------------------------ 370 r <= REG_INIT_C after TPD_G;
371 elsif rising_edge(clk) then 372 r <= rin after TPD_G;
377 end architecture rtl;
in filtstd_logic_vector(( filter- 1)* dynfilt downto 0)
in clk_cntstd_logic_vector( 15 downto 0)
OUTPUT_EN_POLARITY_Ginteger range 0 to 1:= 0
slv( 7 downto 0) := X"01" I2C_INVALID_ADDR_ERROR_C
DYNAMIC_FILTER_Ginteger range 0 to 1:= 0
FILTER_Ginteger range 2 to 512:= 126
in i2cMasterInI2cMasterInType
slv( 7 downto 0) := X"02" I2C_WRITE_ACK_ERROR_C
i2c_master_byte_ctrl byte_ctrlbyte_ctrl
out doutstd_logic_vector( 7 downto 0)
in dinstd_logic_vector( 7 downto 0)
slv( 7 downto 0) := X"03" I2C_ARBITRATION_LOST_ERROR_C
out i2cMasterOutI2cMasterOutType