Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix for SSI and BiSS encoder modules to correctly detect encoder loss #194

Merged
merged 1 commit into from
Oct 7, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion common/hdl/encoders/biss_sniffer.vhd
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,7 @@ begin
if (reset = '1') then
biss_fsm <= IDLE;
biss_frame <= '0';
link_up_o <= '0';
else
-- Unidirectional point-to-point BiSS communication
case biss_fsm is
Expand Down Expand Up @@ -165,6 +166,7 @@ begin
-- Set active biss frame flag for link disconnection
if (biss_fsm = IDLE and serial_clock = '0') then
biss_frame <= '1';
link_up_o <= '1';
elsif (biss_fsm = TIMEOUT) then
biss_frame <= '0';
end if;
Expand Down Expand Up @@ -322,7 +324,6 @@ end process;
-- link_down
-- Encoder CRC error
--------------------------------------------------------------------------
link_up_o <= link_up;
health_o <= health_biss_sniffer;
error_o <= crc_strobe when (crc /= crc_calc or nError(1) = '0') else '0';

Expand Down
36 changes: 25 additions & 11 deletions common/hdl/encoders/encoders.vhd
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,9 @@ signal homed_qdec : std_logic_vector(31 downto 0);
signal linkup_incr : std_logic;
signal linkup_incr_std32 : std_logic_vector(31 downto 0);
signal linkup_ssi : std_logic;
signal ssi_frame : std_logic;
signal ssi_frame_sniffer : std_logic;
signal ssi_frame_master : std_logic;
signal linkup_biss_sniffer : std_logic;
signal health_biss_sniffer : std_logic_vector(31 downto 0);
signal linkup_biss_master : std_logic;
Expand Down Expand Up @@ -307,7 +310,8 @@ port map (
ssi_sck_o => clk_out_encoder_ssi,
ssi_dat_i => DATA_IN,
posn_o => posn_ssi,
posn_valid_o => open
posn_valid_o => open,
ssi_frame_o => ssi_frame_master
);

-- SSI Sniffer
Expand All @@ -317,11 +321,23 @@ port map (
reset_i => reset_i,
ENCODING => INENC_ENCODING_i,
BITS => INENC_BITS_i,
link_up_o => linkup_ssi,
error_o => open,
ssi_sck_i => CLK_IN,
ssi_dat_i => DATA_IN,
posn_o => posn_ssi_sniffer
posn_o => posn_ssi_sniffer,
ssi_frame_o => ssi_frame_sniffer
);

ssi_frame <= ssi_frame_sniffer when DCARD_MODE_i(3 downto 1) = DCARD_MONITOR
else ssi_frame_master;

-- Frame checker for SSI
ssi_err_det_inst: entity work.ssi_error_detect
port map (
clk_i => clk_i,
serial_dat_i => DATA_IN,
ssi_frame_i => ssi_frame,
link_up_o => linkup_ssi
);

--------------------------------------------------------------------------
Expand Down Expand Up @@ -384,18 +400,16 @@ begin
when "001" => -- SSI & Loopback
if (DCARD_MODE_i(3 downto 1) = DCARD_MONITOR) then
posn <= posn_ssi_sniffer;
STATUS_o(0) <= linkup_ssi;
if (linkup_ssi = '0') then
INENC_HEALTH_o <= TO_SVECTOR(2,32);
else
INENC_HEALTH_o <= (others => '0');
end if;
else -- DCARD_CONTROL
posn <= posn_ssi;
STATUS_o <= (others => '0');
INENC_HEALTH_o <= (others=>'0');
end if;
HOMED_o <= TO_SVECTOR(1,32);
STATUS_o(0) <= linkup_ssi;
if (linkup_ssi = '0') then
INENC_HEALTH_o <= TO_SVECTOR(2,32);
else
INENC_HEALTH_o <= (others => '0');
end if;

when "010" => -- BISS & Loopback
if (DCARD_MODE_i(3 downto 1) = DCARD_MONITOR) then
Expand Down
58 changes: 58 additions & 0 deletions common/hdl/encoders/ssi_error_detect.vhd
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

use work.support.all;

entity ssi_error_detect is
port (
clk_i : in std_logic;
serial_dat_i : in std_logic;
ssi_frame_i : in std_logic;
link_up_o : out std_logic
);
end ssi_error_detect;

architecture rtl of ssi_error_detect is

constant ENCODER_TIMEOUT : natural := 125 * 10; -- 10usec (Minimum timeout/2)

signal ssi_frame_prev : std_logic;
signal timeout_cnt_en : std_logic;
signal timeout_ctr : unsigned(LOG2(ENCODER_TIMEOUT-1) downto 0);
signal frame_start : std_logic;
signal frame_end : std_logic;

begin

frame_err_det: process(clk_i)
begin
if rising_edge(clk_i) then

ssi_frame_prev <= ssi_frame_i;

if ssi_frame_i = '1' and ssi_frame_prev = '0' then -- rising edge
-- Encoder must drive the line high when IDLE
frame_start <= serial_dat_i;
timeout_cnt_en <= '0';
elsif ssi_frame_i = '0' and ssi_frame_prev = '1' then --falling edge
timeout_cnt_en <= '1';
timeout_ctr <= (others => '0');
elsif timeout_cnt_en = '1' then
if timeout_ctr = ENCODER_TIMEOUT-1 then
-- Encoder must drive the line low during TIMEOUT dwell time
frame_end <= serial_dat_i;
timeout_ctr <= (others => '0');
timeout_cnt_en <= '0';
else
timeout_ctr <= timeout_ctr + 1;
end if;
end if;

-- Link is up when line is high during IDLE and low during TIMEOUT
link_up_o <= frame_start and not frame_end;
end if;
end process;

end rtl;

16 changes: 15 additions & 1 deletion common/hdl/encoders/ssi_master.vhd
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,8 @@ port (
ssi_sck_o : out std_logic;
ssi_dat_i : in std_logic;
posn_o : out std_logic_vector(31 downto 0);
posn_valid_o : out std_logic
posn_valid_o : out std_logic;
ssi_frame_o : out std_logic
);
end entity;

Expand All @@ -50,10 +51,12 @@ architecture rtl of ssi_master is
signal frame_pulse : std_logic;
signal serial_clock : std_logic;
signal serial_clock_prev : std_logic;
signal shift_enable_prev : std_logic;
signal shift_enable : std_logic;
signal shift_clock : std_logic;
signal shift_data : std_logic;
signal shift_in : std_logic_vector(31 downto 0);
signal ssi_frame : std_logic;

-- Shift length in integer
signal intBITS : natural range 0 to 2**BITS'length-1;
Expand All @@ -62,6 +65,7 @@ begin

-- Connect outputs
ssi_sck_o <= serial_clock;
ssi_frame_o <= ssi_frame;

-- Generate Internal SSI Frame from system clock
frame_presc : entity work.prescaler
Expand Down Expand Up @@ -93,8 +97,18 @@ begin
if rising_edge(clk_i) then
if reset_i = '1' then
serial_clock_prev <= '0';
shift_enable_prev <= '0';
ssi_frame <= '0';
else
serial_clock_prev <= serial_clock;
shift_enable_prev <= shift_enable;
-- Check for initial falling edge of serial clock for start of frame
if shift_clock = '1' and ssi_frame = '0' then
ssi_frame <= '1';
-- check for falling edge of shift_enable to reset ssi_frame
elsif shift_enable = '0' and shift_enable_prev = '1' then
ssi_frame <= '0';
end if;
end if;
end if;
end process;
Expand Down
22 changes: 6 additions & 16 deletions common/hdl/encoders/ssi_sniffer.vhd
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,13 @@ port (
-- Configuration interface
ENCODING : in std_logic_vector(1 downto 0);
BITS : in std_logic_vector(7 downto 0);
link_up_o : out std_logic;
error_o : out std_logic;
error_o : out std_logic := '0';
-- Physical SSI interface
ssi_sck_i : in std_logic;
ssi_dat_i : in std_logic;
-- Block outputs
posn_o : out std_logic_vector(31 downto 0)
posn_o : out std_logic_vector(31 downto 0);
ssi_frame_o : out std_logic
);
end ssi_sniffer;

Expand All @@ -44,8 +44,6 @@ signal uBITS : unsigned(7 downto 0);
signal intBITS : natural range 0 to 2**BITS'length-1;

signal reset : std_logic;
signal serial_data_prev : std_logic;
signal serial_data_rise : std_logic;
signal serial_clock : std_logic;
signal serial_clock_prev : std_logic;
signal link_up : std_logic;
Expand All @@ -58,9 +56,10 @@ signal serial_clock_rise : std_logic;
signal shift_counter : unsigned(7 downto 0);
signal shift_enabled : std_logic;


begin

ssi_frame_o <= ssi_frame;

--------------------------------------------------------------------------
-- Internal signal assignments
--------------------------------------------------------------------------
Expand All @@ -76,14 +75,12 @@ process (clk_i)
begin
if (rising_edge(clk_i)) then
serial_clock_prev <= serial_clock;
serial_data_prev <= serial_data;
end if;
end process;

-- Shift source synchronous data on the Falling egde of clock
serial_clock_fall <= not serial_clock and serial_clock_prev;
serial_clock_rise <= serial_clock and not serial_clock_prev;
serial_data_rise <= serial_data and not serial_data_prev;

--------------------------------------------------------------------------
-- Detect link if clock is asserted for > 5us.
Expand Down Expand Up @@ -178,12 +175,5 @@ begin
end if;
end process;

--------------------------------------------------------------------------
-- Module status outputs
-- link_down
-- Encoder CRC error
--------------------------------------------------------------------------
link_up_o <= link_up;
error_o <= '0'; -- n/a

end rtl;

2 changes: 1 addition & 1 deletion modules/inenc/inenc.block.ini
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ type: read enum
description: Table status
0: OK
1: Linkup error (=not CONN)
2: Timeout error (for BISS, monitor SSI)
2: Timeout error (for BISS, SSI)
3: CRC error (for BISS)
4: Error bit active (for BISS)
5: ENDAT not implemented
Expand Down
Loading