Commit a87bbfce authored by Theodor-Adrian Stana's avatar Theodor-Adrian Stana

i2c_slave with internal watchdog timer

parent 7dabd625
......@@ -79,9 +79,9 @@
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="1.979899"
inkscape:cx="291.59117"
inkscape:cy="7.3374424"
inkscape:zoom="1.4"
inkscape:cx="552.93329"
inkscape:cy="30.655415"
inkscape:document-units="px"
inkscape:current-layer="layer1"
showgrid="true"
......@@ -256,9 +256,10 @@
inkscape:connector-curvature="0" />
<path
style="fill:none;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;marker-end:url(#TriangleOutM)"
d="m 337.45736,333.07084 -63.77953,0 0,-21.25982"
d="m 337.45736,319.35754 -63.77953,0 0,-7.54652"
id="path4618"
inkscape:connector-curvature="0" />
inkscape:connector-curvature="0"
sodipodi:nodetypes="ccc" />
<path
style="fill:none;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;marker-end:url(#TriangleOutM)"
d="m 443.75659,333.53076 70.86613,0 0,-21.25984"
......@@ -483,5 +484,30 @@
x="567.77234"
id="tspan4935"
sodipodi:role="line">stat_o</tspan></text>
<rect
style="fill:#d9d9d9;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
id="rect3055"
width="53.149609"
height="35.433071"
x="124.85893"
y="326.44415" />
<text
xml:space="preserve"
style="font-size:10px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
x="124.01575"
y="322.44092"
id="text3057"
sodipodi:linespacing="125%"><tspan
style="font-weight:bold"
sodipodi:role="line"
id="tspan3059"
x="124.01575"
y="322.44092">watchdog</tspan></text>
<path
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#TriangleOutM)"
d="m 159.44882,178.08521 95.66929,0 0,-10.62992 60.23622,0"
id="path3061"
inkscape:connector-curvature="0"
transform="translate(18.559723,166.07548)" />
</g>
</svg>
......@@ -100,6 +100,7 @@ The main features of the \textit{i2c\_slave} module are:
\item standard (100~kHz) and fast (400~kHz) modes supported
\item no clock stretching, all information provided by the module should be handled
externally within the time span of an I$^2$C bit transfer
\item internal watchdog timer resets logic in case of bus error
\item architecture-independent, can be used with various FPGA types or ASICs
\end{itemize}
......@@ -369,6 +370,11 @@ are loaded and when they shift, and acknowledging to the address and bytes sent
master. Table~\ref{tbl:fsm} lists the states of the FSM and the operations performed
in each state.
An internal watchdog counter is implemented inside the \textit{i2c\_slave} module. This counter
counts up to 1 second and is reset at the start of each state of the FSM. If the FSM stops
in one of the states because of a bus error, the watchdog resets the FSM, thereby stopping the
communication.
\begin{longtable}{l p{.7\textwidth}}
\caption{The states of the \textit{i2c\_slave} FSM}
\label{tbl:fsm} \\
......
......@@ -60,7 +60,6 @@ use ieee.numeric_std.all;
use work.i2c_slave_pkg.all;
entity i2c_slave is
port
(
......@@ -176,6 +175,11 @@ architecture behav of i2c_slave is
-- Bit counter on RX & TX
signal bit_cnt : unsigned(2 downto 0);
-- Watchdog counter signals
signal watchdog_cnt : unsigned(26 downto 0);
signal watchdog_rst : std_logic;
signal rst_fr_watchdog : std_logic;
--==============================================================================
-- architecture begin
--==============================================================================
......@@ -271,16 +275,17 @@ begin
p_fsm: process (clk_i) is
begin
if rising_edge(clk_i) then
if (rst_n_i = '0') then
state <= ST_IDLE;
bit_cnt <= (others => '0');
rxsr <= (others => '0');
txsr <= (others => '0');
sda_o <= '0';
sda_en_o <= '0';
done_p_o <= '0';
op_o <= '0';
stat_o <= c_i2cs_idle;
if (rst_n_i = '0') or (rst_fr_watchdog = '1') then
state <= ST_IDLE;
watchdog_rst <= '1';
bit_cnt <= (others => '0');
rxsr <= (others => '0');
txsr <= (others => '0');
sda_o <= '0';
sda_en_o <= '0';
done_p_o <= '0';
op_o <= '0';
stat_o <= c_i2cs_idle;
-- I2C start condition
elsif (sda_falling = '1') and (scl_degl = '1') then
......@@ -300,11 +305,12 @@ begin
-- for a start condition.
---------------------------------------------------------------------
when ST_IDLE =>
bit_cnt <= (others => '0');
sda_o <= '0';
sda_en_o <= '0';
done_p_o <= '0';
stat_o <= c_i2cs_idle;
bit_cnt <= (others => '0');
sda_o <= '0';
sda_en_o <= '0';
done_p_o <= '0';
watchdog_rst <= '1';
stat_o <= c_i2cs_idle;
---------------------------------------------------------------------
-- ST_STA
......@@ -314,9 +320,11 @@ begin
-- SCL, we go into the address state.
---------------------------------------------------------------------
when ST_STA =>
bit_cnt <= (others => '0');
watchdog_rst <= '0';
bit_cnt <= (others => '0');
if (scl_falling = '1') then
state <= ST_ADDR;
watchdog_rst <= '1';
state <= ST_ADDR;
end if;
---------------------------------------------------------------------
......@@ -328,10 +336,14 @@ begin
-- ADDR_ACK state.
---------------------------------------------------------------------
when ST_ADDR =>
-- Clear watchdog reset
watchdog_rst <= '0';
-- Shifting in is done on falling edge of SCL
if (scl_falling = '1') then
rxsr <= rxsr(6 downto 0) & sda_degl;
bit_cnt <= bit_cnt + 1;
watchdog_rst <= '1';
rxsr <= rxsr(6 downto 0) & sda_degl;
bit_cnt <= bit_cnt + 1;
-- Shifted in 8 bits, go to ADDR_ACK. Check to see if received
-- address is ours and set op_o if so.
......@@ -353,6 +365,9 @@ begin
-- R/W bit received via I2C.
---------------------------------------------------------------------
when ST_ADDR_ACK =>
-- Clear watchdog reset
watchdog_rst <= '0';
-- Clear done pulse
done_p_o <= '0';
......@@ -365,6 +380,7 @@ begin
if (rxsr(7 downto 1) = i2c_addr_i) then
sda_o <= ack_n_i;
if (scl_falling = '1') then
watchdog_rst <= '1';
sda_en_o <= '0';
if (rxsr(0) = '0') then
state <= ST_RD;
......@@ -384,8 +400,12 @@ begin
-- Shift in bits sent by the master.
---------------------------------------------------------------------
when ST_RD =>
-- Clear watchdog reset
watchdog_rst <= '0';
-- Shifting occurs on falling edge of SCL
if (scl_falling = '1') then
watchdog_rst <= '1';
rxsr <= rxsr(6 downto 0) & sda_degl;
bit_cnt <= bit_cnt + 1;
......@@ -403,6 +423,9 @@ begin
-- Send ACK/NACK, as received from external command
---------------------------------------------------------------------
when ST_RD_ACK =>
-- Clear watchdog reset
watchdog_rst <= '0';
-- Clear done pulse
done_p_o <= '0';
......@@ -413,6 +436,7 @@ begin
-- based on the ACK received by external command, we read the next
-- bit (ACK) or go back to idle state (NACK)
if (scl_falling = '1') then
watchdog_rst <= '1';
sda_en_o <= '0';
if (ack_n_i = '0') then
state <= ST_RD;
......@@ -436,14 +460,17 @@ begin
-- Shift out the eight bits of TXSR.
---------------------------------------------------------------------
when ST_WR =>
watchdog_rst <= '0';
-- slave writes, so enable output
sda_en_o <= '1';
sda_o <= txsr(7);
sda_en_o <= '1';
sda_o <= txsr(7);
-- Shift TXSR on falling edge of SCL
if (scl_falling = '1') then
txsr <= txsr(6 downto 0) & '0';
bit_cnt <= bit_cnt + 1;
watchdog_rst <= '1';
txsr <= txsr(6 downto 0) & '0';
bit_cnt <= bit_cnt + 1;
-- Eight bits sent, disable SDA end go to WR_ACK
if (bit_cnt = 7) then
......@@ -464,8 +491,11 @@ begin
-- state.
---------------------------------------------------------------------
when ST_WR_ACK =>
watchdog_rst <= '0';
done_p_o <= '0';
if (scl_falling = '1') then
watchdog_rst <= '1';
if (sda_degl = '0') then
state <= ST_WR_LOAD_TXSR;
else
......@@ -484,6 +514,30 @@ begin
end if;
end process p_fsm;
--============================================================================
-- Watchdog counter process
-- Resets the FSM after one second. The watchdog_rst signal is controlled by
-- the FSM and resets the watchdog if the I2C master still controls the
-- slave, signaled by the SCL line going low. If for one second the master
-- does not toggle the SCL line, the FSM gets reset.
--============================================================================
p_watchdog: process(clk_i)
begin
if rising_edge(clk_i) then
if (rst_n_i = '0') or (watchdog_rst = '1') then
watchdog_cnt <= (others => '0');
rst_fr_watchdog <= '0';
else
watchdog_cnt <= watchdog_cnt + 1;
rst_fr_watchdog <= '0';
if (watchdog_cnt = 124999999) then
watchdog_cnt <= (others => '0');
rst_fr_watchdog <= '1';
end if;
end if;
end if;
end process p_watchdog;
end architecture behav;
--==============================================================================
-- architecture end
......
files = [
"ctb_pulse_gen_gp.vhd"
"pulse_gen_gp.vhd"
]
......@@ -3,8 +3,8 @@
# http://ohwr.org/projects/hdl-make/ #
########################################
PROJECT := conv_ttl_blo_v2.xise
ISE_CRAP := *.b conv_ttl_blo_v2_summary.html *.tcl conv_ttl_blo_v2.bld conv_ttl_blo_v2.cmd_log *.drc conv_ttl_blo_v2.lso *.ncd conv_ttl_blo_v2.ngc conv_ttl_blo_v2.ngd conv_ttl_blo_v2.ngr conv_ttl_blo_v2.pad conv_ttl_blo_v2.par conv_ttl_blo_v2.pcf conv_ttl_blo_v2.prj conv_ttl_blo_v2.ptwx conv_ttl_blo_v2.stx conv_ttl_blo_v2.syr conv_ttl_blo_v2.twr conv_ttl_blo_v2.twx conv_ttl_blo_v2.gise conv_ttl_blo_v2.unroutes conv_ttl_blo_v2.ut conv_ttl_blo_v2.xpi conv_ttl_blo_v2.xst conv_ttl_blo_v2_bitgen.xwbt conv_ttl_blo_v2_envsettings.html conv_ttl_blo_v2_guide.ncd conv_ttl_blo_v2_map.map conv_ttl_blo_v2_map.mrp conv_ttl_blo_v2_map.ncd conv_ttl_blo_v2_map.ngm conv_ttl_blo_v2_map.xrpt conv_ttl_blo_v2_ngdbuild.xrpt conv_ttl_blo_v2_pad.csv conv_ttl_blo_v2_pad.txt conv_ttl_blo_v2_par.xrpt conv_ttl_blo_v2_summary.xml conv_ttl_blo_v2_usage.xml conv_ttl_blo_v2_xst.xrpt usage_statistics_webtalk.html webtalk.log webtalk_pn.xml run.tcl
PROJECT := conv_ttl_blo.xise
ISE_CRAP := *.b conv_ttl_blo_summary.html *.tcl conv_ttl_blo.bld conv_ttl_blo.cmd_log *.drc conv_ttl_blo.lso *.ncd conv_ttl_blo.ngc conv_ttl_blo.ngd conv_ttl_blo.ngr conv_ttl_blo.pad conv_ttl_blo.par conv_ttl_blo.pcf conv_ttl_blo.prj conv_ttl_blo.ptwx conv_ttl_blo.stx conv_ttl_blo.syr conv_ttl_blo.twr conv_ttl_blo.twx conv_ttl_blo.gise conv_ttl_blo.unroutes conv_ttl_blo.ut conv_ttl_blo.xpi conv_ttl_blo.xst conv_ttl_blo_bitgen.xwbt conv_ttl_blo_envsettings.html conv_ttl_blo_guide.ncd conv_ttl_blo_map.map conv_ttl_blo_map.mrp conv_ttl_blo_map.ncd conv_ttl_blo_map.ngm conv_ttl_blo_map.xrpt conv_ttl_blo_ngdbuild.xrpt conv_ttl_blo_pad.csv conv_ttl_blo_pad.txt conv_ttl_blo_par.xrpt conv_ttl_blo_summary.xml conv_ttl_blo_usage.xml conv_ttl_blo_xst.xrpt usage_statistics_webtalk.html webtalk.log webtalk_pn.xml run.tcl
#target for performing local synthesis
local:
......@@ -24,7 +24,7 @@ mrproper:
USER:=$(HDLMAKE_USER)#take the value from the environment
SERVER:=$(HDLMAKE_SERVER)#take the value from the environment
R_NAME:=conv_ttl_blo_v2
R_NAME:=conv_ttl_blo
__test_for_remote_synthesis_variables:
ifeq (x$(USER),x)
......@@ -36,8 +36,8 @@ endif
CWD := $(shell pwd)
FILES := ../top/conv_ttl_blo_v2.ucf \
../top/conv_ttl_blo_v2.vhd \
FILES := ../top/conv_ttl_blo.ucf \
../top/conv_ttl_blo.vhd \
../rtl/conv_regs.vhd \
../../bicolor_led_ctrl/bicolor_led_ctrl_pkg.vhd \
../../bicolor_led_ctrl/bicolor_led_ctrl.vhd \
......@@ -141,7 +141,7 @@ FILES := ../top/conv_ttl_blo_v2.ucf \
../../../../ip_cores/general-cores/modules/wishbone/wb_spi/spi_defines.v \
../../../../ip_cores/general-cores/modules/wishbone/wb_spi/timescale.v \
run.tcl \
conv_ttl_blo_v2.xise
conv_ttl_blo.xise
#target for running simulation in the remote location
remote: __test_for_remote_synthesis_variables __send __do_synthesis __send_back
......
......@@ -3,8 +3,8 @@ action = "synthesis"
syn_device = "xc6slx45t"
syn_grade = "-3"
syn_package = "fgg484"
syn_top = "conv_ttl_blo_v2"
syn_project = "conv_ttl_blo_v2.xise"
syn_top = "conv_ttl_blo"
syn_project = "conv_ttl_blo.xise"
modules = {
"local" : [
......
project open conv_ttl_blo_v2.xise
project open conv_ttl_blo.xise
process run {Generate Programming File} -force rerun_all
files = [
"conv_ttl_blo_v2.ucf",
"conv_ttl_blo_v2.vhd"
"conv_ttl_blo.ucf",
"conv_ttl_blo.vhd"
]
modules = {
......
--------------------------------------------------------------------------------
-- CERN (BE-CO-HT)
-- Top level entity of CONV-TTL-BLO V1
-- http://www.ohwr.org/projects/conv-trig_a-blo
-- Top level entity of CONV-TTL-BLO V2
-- http://www.ohwr.org/projects/conv-ttl-blo
--------------------------------------------------------------------------------
--
-- unit name: conv_ttl_blo_v2.vhd
-- unit name: conv_ttl_blo.vhd
--
-- author: Theodor-Adrian Stana (t.stana@cern.ch)
--
......@@ -42,7 +42,7 @@ use work.bicolor_led_ctrl_pkg.all;
use work.wishbone_pkg.all;
use work.gencores_pkg.all;
entity conv_ttl_blo_v2 is
entity conv_ttl_blo is
generic
(
g_nr_ttl_chan : natural := 6;
......@@ -105,10 +105,10 @@ entity conv_ttl_blo_v2 is
fpga_rtmm_n_i : in std_logic_vector(2 downto 0);
fpga_rtmp_n_i : in std_logic_vector(2 downto 0)
);
end conv_ttl_blo_v2;
end conv_ttl_blo;
architecture behav of conv_ttl_blo_v2 is
architecture behav of conv_ttl_blo is
--============================================================================
-- Type declarations
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment