Working muxing with I2C slave interface. TO DO: protection from SIM attach to several modems
This commit is contained in:
parent
86c7da5075
commit
d82a0ab464
|
|
@ -30,6 +30,10 @@ entity sim_switcher_top is
|
||||||
cpu_trstn_o : out std_logic;
|
cpu_trstn_o : out std_logic;
|
||||||
cpu_jtag_rstn_o : out std_logic;
|
cpu_jtag_rstn_o : out std_logic;
|
||||||
|
|
||||||
|
-- I2C slave interface
|
||||||
|
i2c_scl_io : inout std_logic;
|
||||||
|
i2c_sda_io : inout std_logic;
|
||||||
|
|
||||||
-- SIM signals
|
-- SIM signals
|
||||||
sim_detect_i : in std_logic_vector(7 downto 0);
|
sim_detect_i : in std_logic_vector(7 downto 0);
|
||||||
sim_pwron_o : out std_logic_vector(7 downto 0);
|
sim_pwron_o : out std_logic_vector(7 downto 0);
|
||||||
|
|
@ -70,6 +74,8 @@ architecture rtl of sim_switcher_top is
|
||||||
|
|
||||||
constant DEBOUNCING_WAIT_CYCLES : natural := 3; -- Number of debouncing wait cycles
|
constant DEBOUNCING_WAIT_CYCLES : natural := 3; -- Number of debouncing wait cycles
|
||||||
|
|
||||||
|
constant I2C_MAX_WAIT : natural := 2_500_000; -- 25_000_000 = 1sec
|
||||||
|
|
||||||
signal s_clk_i : std_logic; -- clock buffer
|
signal s_clk_i : std_logic; -- clock buffer
|
||||||
signal s_rstn_i : std_logic; -- reset signal
|
signal s_rstn_i : std_logic; -- reset signal
|
||||||
signal s_rst_i : std_logic; -- reset signal
|
signal s_rst_i : std_logic; -- reset signal
|
||||||
|
|
@ -95,10 +101,9 @@ architecture rtl of sim_switcher_top is
|
||||||
type i2c_fsm_t is (ready, receive_byte, wait_while_sent);
|
type i2c_fsm_t is (ready, receive_byte, wait_while_sent);
|
||||||
signal i2c_slv_state : i2c_fsm_t := ready;
|
signal i2c_slv_state : i2c_fsm_t := ready;
|
||||||
|
|
||||||
-- signal reg_sim_sel : sim_mux_addr_t(3 downto 0);
|
signal reg_sim_pwr : std_logic_vector(15 downto 0);
|
||||||
-- signal reg_sim_pwr : std_logic_vector(15 downto 0);
|
signal reg_sim_det : std_logic_vector(15 downto 0);
|
||||||
-- signal reg_sim_det : std_logic_vector(15 downto 0);
|
signal s_reg_to_write : std_logic_vector(7 downto 0);
|
||||||
-- signal s_reg_to_write : std_logic_vector(7 downto 0);
|
|
||||||
|
|
||||||
-- SIM data signals
|
-- SIM data signals
|
||||||
signal s_sim_data_i, sdb_sim_data_i, sdb_sim_data_prev, s_sim_data_o: std_logic_vector(15 downto 0);
|
signal s_sim_data_i, sdb_sim_data_i, sdb_sim_data_prev, s_sim_data_o: std_logic_vector(15 downto 0);
|
||||||
|
|
@ -122,18 +127,21 @@ begin
|
||||||
s_sim_data_i(15 downto 8) <= (others => '1');
|
s_sim_data_i(15 downto 8) <= (others => '1');
|
||||||
sdb_sim_data_i(15 downto 8) <= (others => '1');
|
sdb_sim_data_i(15 downto 8) <= (others => '1');
|
||||||
|
|
||||||
reg_sim_modemnum <= (
|
reg_sim_det(7 downto 0) <= sim_detect_i;
|
||||||
0 => 7,
|
reg_sim_det(15 downto 8) <= (others => '0');
|
||||||
1 => 6,
|
|
||||||
2 => 5,
|
|
||||||
3 => 4,
|
|
||||||
4 => 3,
|
|
||||||
5 => 2,
|
|
||||||
6 => 1,
|
|
||||||
7 => 0
|
|
||||||
);
|
|
||||||
|
|
||||||
reg_sim_change_irq <= (others => '0');
|
-- reg_sim_modemnum <= (
|
||||||
|
-- 0 => 7,
|
||||||
|
-- 1 => 6,
|
||||||
|
-- 2 => 5,
|
||||||
|
-- 3 => 4,
|
||||||
|
-- 4 => 3,
|
||||||
|
-- 5 => 2,
|
||||||
|
-- 6 => 1,
|
||||||
|
-- 7 => 0
|
||||||
|
-- );
|
||||||
|
|
||||||
|
-- reg_sim_change_irq <= (others => '0');
|
||||||
|
|
||||||
----------------------------------
|
----------------------------------
|
||||||
-- Power-On FPGA IP-cores reset --
|
-- Power-On FPGA IP-cores reset --
|
||||||
|
|
@ -233,159 +241,185 @@ begin
|
||||||
--------------------------------
|
--------------------------------
|
||||||
-- I2C slave interface to CPU --
|
-- I2C slave interface to CPU --
|
||||||
--------------------------------
|
--------------------------------
|
||||||
-- inst_i2c_slave: i2c_slave
|
inst_i2c_slave: i2c_slave
|
||||||
-- generic map (
|
generic map (
|
||||||
-- SLAVE_ADDR => I2C_SLAVE_ADDR
|
SLAVE_ADDR => I2C_SLAVE_ADDR
|
||||||
-- )
|
)
|
||||||
-- port map(
|
port map(
|
||||||
-- scl => i2c_scl_io,
|
scl => i2c_scl_io,
|
||||||
-- sda => i2c_sda_io,
|
sda => i2c_sda_io,
|
||||||
-- clk => clk25_i,
|
clk => clk25_i,
|
||||||
-- rst => s_rst_i,
|
rst => s_rst_i,
|
||||||
-- read_req => i2c_read_req,
|
read_req => i2c_read_req,
|
||||||
-- data_to_master => i2c_data_to_master,
|
data_to_master => i2c_data_to_master,
|
||||||
-- data_valid => i2c_data_valid,
|
data_valid => i2c_data_valid,
|
||||||
-- data_from_master => i2c_data_from_master
|
data_from_master => i2c_data_from_master
|
||||||
-- );
|
);
|
||||||
|
|
||||||
-- i2c_slv_process : process (clk25_i, s_rstn_i)
|
i2c_slv_process : process (clk25_i, s_rstn_i)
|
||||||
-- variable wait_cnt : natural := 0;
|
variable wait_cnt : natural := 0;
|
||||||
-- begin
|
begin
|
||||||
-- if (s_rstn_i = '0') then
|
if (s_rstn_i = '0') then
|
||||||
-- i2c_data_to_master <= (others => '0');
|
i2c_data_to_master <= (others => '0');
|
||||||
-- wait_cnt := 0;
|
wait_cnt := 0;
|
||||||
|
|
||||||
-- -- SIM select reset: default is SIM#1
|
-- SIM attach reset assigment: default is 1-to-1 SIM to MODEM connection
|
||||||
-- reg_sim_sel <= (others => (others => '0'));
|
reg_sim_modemnum <= (
|
||||||
|
0 => 0,
|
||||||
|
1 => 1,
|
||||||
|
2 => 2,
|
||||||
|
3 => 3,
|
||||||
|
4 => 4,
|
||||||
|
5 => 5,
|
||||||
|
6 => 6,
|
||||||
|
7 => 7
|
||||||
|
);
|
||||||
|
-- SIM change IRQ register reset
|
||||||
|
reg_sim_change_irq <= (others => '0');
|
||||||
|
|
||||||
-- -- Turn on all SIM cards
|
-- Turn on all SIM cards
|
||||||
-- reg_sim_pwr <= (others => '1');
|
reg_sim_pwr(7 downto 0) <= (others => '1');
|
||||||
|
reg_sim_pwr(15 downto 8) <= (others => '0');
|
||||||
|
|
||||||
-- -- Only first SIMs are powered on upon reset
|
elsif (rising_edge(clk25_i)) then
|
||||||
-- -- reg_sim_pwr(0) <= '1';
|
case i2c_slv_state is
|
||||||
-- -- reg_sim_pwr(3 downto 1) <= (others => '0');
|
when ready =>
|
||||||
-- --
|
wait_cnt := 0;
|
||||||
-- -- reg_sim_pwr(4) <= '1';
|
i2c_data_to_master <= (others => '0');
|
||||||
-- -- reg_sim_pwr(7 downto 5) <= (others => '0');
|
if (i2c_data_valid = '1') then -- master sent a register addr byte
|
||||||
-- --
|
-- Save register address for later use in write procedure
|
||||||
-- -- reg_sim_pwr(8) <= '1';
|
s_reg_to_write <= i2c_data_from_master;
|
||||||
-- -- reg_sim_pwr(11 downto 9) <= (others => '0');
|
|
||||||
-- --
|
|
||||||
-- -- reg_sim_pwr(12) <= '1';
|
|
||||||
-- -- reg_sim_pwr(15 downto 13) <= (others => '0');
|
|
||||||
--
|
|
||||||
-- reg_sim_change_irq <= (others => '0');
|
|
||||||
--
|
|
||||||
-- elsif (rising_edge(clk25_i)) then
|
|
||||||
-- case i2c_slv_state is
|
|
||||||
-- when ready =>
|
|
||||||
-- wait_cnt := 0;
|
|
||||||
-- i2c_data_to_master <= (others => '0');
|
|
||||||
-- if (i2c_data_valid = '1') then -- master sent a register addr byte
|
|
||||||
-- -- Save register address for later use in write procedure
|
|
||||||
-- s_reg_to_write <= i2c_data_from_master;
|
|
||||||
|
|
||||||
-- case i2c_data_from_master is
|
case i2c_data_from_master is
|
||||||
-- when x"10" => -- Read ID byte
|
when x"10" => -- Read ID byte
|
||||||
-- i2c_data_to_master <= x"18";
|
i2c_data_to_master <= x"18";
|
||||||
-- i2c_slv_state <= wait_while_sent;
|
i2c_slv_state <= wait_while_sent;
|
||||||
|
|
||||||
-- when x"11" => -- Read SW Version byte (v1.0=0x18, v1.1=0x19)
|
when x"11" => -- Read SW Version byte (v1.0=0x18, v1.1=0x19, v2.0=0x28)
|
||||||
-- i2c_data_to_master <= x"19";
|
i2c_data_to_master <= x"20";
|
||||||
-- i2c_slv_state <= wait_while_sent;
|
i2c_slv_state <= wait_while_sent;
|
||||||
|
|
||||||
-- when x"0A" => -- Read SIMs detect register (LSB)
|
when x"0A" => -- Read SIMs detect register (LSB)
|
||||||
-- i2c_data_to_master <= reg_sim_det(7 downto 0);
|
i2c_data_to_master <= reg_sim_det(7 downto 0);
|
||||||
-- i2c_slv_state <= wait_while_sent;
|
i2c_slv_state <= wait_while_sent;
|
||||||
-- when x"0B" => -- Read SIMs detect register (MSB)
|
-- when x"0B" => -- Read SIMs detect register (MSB)
|
||||||
-- i2c_data_to_master <= reg_sim_det(15 downto 8);
|
-- i2c_data_to_master <= reg_sim_det(15 downto 8);
|
||||||
-- i2c_slv_state <= wait_while_sent;
|
-- i2c_slv_state <= wait_while_sent;
|
||||||
-- when x"0C" => -- Read SIMs power register (LSB)
|
when x"0C" => -- Read SIMs power register (LSB)
|
||||||
-- i2c_data_to_master <= reg_sim_pwr(7 downto 0);
|
i2c_data_to_master <= reg_sim_pwr(7 downto 0);
|
||||||
-- i2c_slv_state <= wait_while_sent;
|
i2c_slv_state <= wait_while_sent;
|
||||||
-- when x"0D" => -- Read SIMs power register (MSB)
|
-- when x"0D" => -- Read SIMs power register (MSB)
|
||||||
-- i2c_data_to_master <= reg_sim_pwr(15 downto 8);
|
-- i2c_data_to_master <= reg_sim_pwr(15 downto 8);
|
||||||
-- i2c_slv_state <= wait_while_sent;
|
-- i2c_slv_state <= wait_while_sent;
|
||||||
|
|
||||||
-- when x"1A" => -- Read M1 SIM select register
|
when x"20" => -- Read SIM1 modem register
|
||||||
-- i2c_data_to_master <= "000000" & reg_sim_sel(0);
|
i2c_data_to_master <= "0000" & std_logic_vector(to_unsigned(reg_sim_modemnum(0),4));
|
||||||
-- i2c_slv_state <= wait_while_sent;
|
i2c_slv_state <= wait_while_sent;
|
||||||
-- when x"1B" => -- Read M2 SIM select register
|
when x"21" => -- Read SIM2 modem register
|
||||||
-- i2c_data_to_master <= "000000" & reg_sim_sel(1);
|
i2c_data_to_master <= "0000" & std_logic_vector(to_unsigned(reg_sim_modemnum(1),4));
|
||||||
-- i2c_slv_state <= wait_while_sent;
|
i2c_slv_state <= wait_while_sent;
|
||||||
-- when x"1C" => -- Read M3 SIM select register
|
when x"22" => -- Read SIM3 modem register
|
||||||
-- i2c_data_to_master <= "000000" & reg_sim_sel(2);
|
i2c_data_to_master <= "0000" & std_logic_vector(to_unsigned(reg_sim_modemnum(2),4));
|
||||||
-- i2c_slv_state <= wait_while_sent;
|
i2c_slv_state <= wait_while_sent;
|
||||||
-- when x"1D" => -- Read M4 SIM select register
|
when x"23" => -- Read SIM4 modem register
|
||||||
-- i2c_data_to_master <= "000000" & reg_sim_sel(3);
|
i2c_data_to_master <= "0000" & std_logic_vector(to_unsigned(reg_sim_modemnum(3),4));
|
||||||
-- i2c_slv_state <= wait_while_sent;
|
i2c_slv_state <= wait_while_sent;
|
||||||
|
when x"24" => -- Read SIM5 modem register
|
||||||
|
i2c_data_to_master <= "0000" & std_logic_vector(to_unsigned(reg_sim_modemnum(4),4));
|
||||||
|
i2c_slv_state <= wait_while_sent;
|
||||||
|
when x"25" => -- Read SIM6 modem register
|
||||||
|
i2c_data_to_master <= "0000" & std_logic_vector(to_unsigned(reg_sim_modemnum(5),4));
|
||||||
|
i2c_slv_state <= wait_while_sent;
|
||||||
|
when x"26" => -- Read SIM7 modem register
|
||||||
|
i2c_data_to_master <= "0000" & std_logic_vector(to_unsigned(reg_sim_modemnum(6),4));
|
||||||
|
i2c_slv_state <= wait_while_sent;
|
||||||
|
when x"27" => -- Read SIM8 modem register
|
||||||
|
i2c_data_to_master <= "0000" & std_logic_vector(to_unsigned(reg_sim_modemnum(7),4));
|
||||||
|
i2c_slv_state <= wait_while_sent;
|
||||||
|
|
||||||
-- when x"8C" => -- Write SIMs power register (LSB)
|
when x"8C" => -- Write SIMs power register (LSB)
|
||||||
-- i2c_slv_state <= receive_byte;
|
i2c_slv_state <= receive_byte;
|
||||||
-- when x"8D" => -- Write SIMs power register (MSB)
|
-- when x"8D" => -- Write SIMs power register (MSB)
|
||||||
-- i2c_slv_state <= receive_byte;
|
-- i2c_slv_state <= receive_byte;
|
||||||
|
|
||||||
-- when x"9A" => -- Write M1 select register
|
when x"A0" => -- Write SIM1 modem register
|
||||||
-- i2c_slv_state <= receive_byte;
|
i2c_slv_state <= receive_byte;
|
||||||
-- when x"9B" => -- Write M2 select register
|
when x"A1" => -- Write SIM2 modem register
|
||||||
-- i2c_slv_state <= receive_byte;
|
i2c_slv_state <= receive_byte;
|
||||||
-- when x"9C" => -- Write M3 select register
|
when x"A2" => -- Write SIM3 modem register
|
||||||
-- i2c_slv_state <= receive_byte;
|
i2c_slv_state <= receive_byte;
|
||||||
-- when x"9D" => -- Write M4 select register
|
when x"A3" => -- Write SIM4 modem register
|
||||||
-- i2c_slv_state <= receive_byte;
|
i2c_slv_state <= receive_byte;
|
||||||
|
when x"A4" => -- Write SIM5 modem register
|
||||||
|
i2c_slv_state <= receive_byte;
|
||||||
|
when x"A5" => -- Write SIM6 modem register
|
||||||
|
i2c_slv_state <= receive_byte;
|
||||||
|
when x"A6" => -- Write SIM7 modem register
|
||||||
|
i2c_slv_state <= receive_byte;
|
||||||
|
when x"A7" => -- Write SIM8 modem register
|
||||||
|
i2c_slv_state <= receive_byte;
|
||||||
|
|
||||||
-- when others =>
|
when others =>
|
||||||
-- i2c_slv_state <= ready;
|
i2c_slv_state <= ready;
|
||||||
-- end case;
|
end case;
|
||||||
-- end if;
|
end if;
|
||||||
|
|
||||||
-- when receive_byte =>
|
when receive_byte =>
|
||||||
-- if (i2c_data_valid = '1') then
|
if (i2c_data_valid = '1') then
|
||||||
-- case s_reg_to_write is
|
case s_reg_to_write is
|
||||||
-- when x"8C" => -- Write SIMs power register (LSB)
|
when x"8C" => -- Write SIMs power register (LSB)
|
||||||
-- reg_sim_pwr(7 downto 0) <= i2c_data_from_master(7 downto 0);
|
reg_sim_pwr(7 downto 0) <= i2c_data_from_master(7 downto 0);
|
||||||
-- when x"8D" => -- Write SIMs power register (MSB)
|
-- when x"8D" => -- Write SIMs power register (MSB)
|
||||||
-- reg_sim_pwr(15 downto 8) <= i2c_data_from_master(7 downto 0);
|
-- reg_sim_pwr(15 downto 8) <= i2c_data_from_master(7 downto 0);
|
||||||
|
|
||||||
-- when x"9A" => -- Write M1 select register
|
when x"A0" => -- Write SIM1 modem register
|
||||||
-- reg_sim_sel(0) <= i2c_data_from_master(1 downto 0);
|
reg_sim_modemnum(0) <= to_integer(unsigned(i2c_data_from_master(3 downto 0)));
|
||||||
-- when x"9B" => -- Write M2 select register
|
when x"A1" => -- Write SIM2 modem register
|
||||||
-- reg_sim_sel(1) <= i2c_data_from_master(1 downto 0);
|
reg_sim_modemnum(1) <= to_integer(unsigned(i2c_data_from_master(3 downto 0)));
|
||||||
-- when x"9C" => -- Write M3 select register
|
when x"A2" => -- Write SIM3 modem register
|
||||||
-- reg_sim_sel(2) <= i2c_data_from_master(1 downto 0);
|
reg_sim_modemnum(2) <= to_integer(unsigned(i2c_data_from_master(3 downto 0)));
|
||||||
-- when x"9D" => -- Write M4 select register
|
when x"A3" => -- Write SIM4 modem register
|
||||||
-- reg_sim_sel(3) <= i2c_data_from_master(1 downto 0);
|
reg_sim_modemnum(3) <= to_integer(unsigned(i2c_data_from_master(3 downto 0)));
|
||||||
-- when others =>
|
when x"A4" => -- Write SIM1 modem register
|
||||||
-- null;
|
reg_sim_modemnum(4) <= to_integer(unsigned(i2c_data_from_master(3 downto 0)));
|
||||||
-- end case;
|
when x"A5" => -- Write SIM2 modem register
|
||||||
-- i2c_slv_state <= ready;
|
reg_sim_modemnum(5) <= to_integer(unsigned(i2c_data_from_master(3 downto 0)));
|
||||||
-- else
|
when x"A6" => -- Write SIM3 modem register
|
||||||
-- -- Wait timer to prevent freeze in waiting state
|
reg_sim_modemnum(6) <= to_integer(unsigned(i2c_data_from_master(3 downto 0)));
|
||||||
-- if (wait_cnt > I2C_MAX_WAIT) then
|
when x"A7" => -- Write SIM4 modem register
|
||||||
-- i2c_slv_state <= ready;
|
reg_sim_modemnum(7) <= to_integer(unsigned(i2c_data_from_master(3 downto 0)));
|
||||||
-- else
|
|
||||||
-- wait_cnt := wait_cnt + 1;
|
|
||||||
-- end if;
|
|
||||||
-- end if;
|
|
||||||
|
|
||||||
-- when wait_while_sent =>
|
when others =>
|
||||||
-- if (i2c_read_req = '1') then
|
null;
|
||||||
-- i2c_slv_state <= ready;
|
end case;
|
||||||
-- else
|
i2c_slv_state <= ready;
|
||||||
-- -- Wait timer to prevent freeze in waiting state
|
else
|
||||||
-- if (wait_cnt > I2C_MAX_WAIT) then
|
-- Wait timer to prevent freeze in waiting state
|
||||||
-- i2c_slv_state <= ready;
|
if (wait_cnt > I2C_MAX_WAIT) then
|
||||||
-- else
|
i2c_slv_state <= ready;
|
||||||
-- wait_cnt := wait_cnt + 1;
|
else
|
||||||
-- end if;
|
wait_cnt := wait_cnt + 1;
|
||||||
-- end if;
|
end if;
|
||||||
|
end if;
|
||||||
|
|
||||||
-- when others =>
|
when wait_while_sent =>
|
||||||
-- i2c_slv_state <= ready;
|
if (i2c_read_req = '1') then
|
||||||
|
i2c_slv_state <= ready;
|
||||||
|
else
|
||||||
|
-- Wait timer to prevent freeze in waiting state
|
||||||
|
if (wait_cnt > I2C_MAX_WAIT) then
|
||||||
|
i2c_slv_state <= ready;
|
||||||
|
else
|
||||||
|
wait_cnt := wait_cnt + 1;
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
|
||||||
-- end case;
|
when others =>
|
||||||
-- end if;
|
i2c_slv_state <= ready;
|
||||||
-- end process i2c_slv_process;
|
|
||||||
|
end case;
|
||||||
|
end if;
|
||||||
|
end process i2c_slv_process;
|
||||||
|
|
||||||
-------------------------------
|
-------------------------------
|
||||||
--- SIM card emulation test ---
|
--- SIM card emulation test ---
|
||||||
|
|
@ -577,7 +611,7 @@ begin
|
||||||
else 'Z';
|
else 'Z';
|
||||||
|
|
||||||
-- Route one-way signals from mod to SIM
|
-- Route one-way signals from mod to SIM
|
||||||
sim_pwron_o <= (others => '1');--mod_pwron_i;
|
sim_pwron_o <= reg_sim_pwr(7 downto 0);--(others => '1');--mod_pwron_i;
|
||||||
--mod_detect_o(3 downto 0) <= sim_detect_i(3 downto 0); --!! Switching
|
--mod_detect_o(3 downto 0) <= sim_detect_i(3 downto 0); --!! Switching
|
||||||
|
|
||||||
-- Bidir sinals routing
|
-- Bidir sinals routing
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue