Advertisement
hector88

svein

Mar 17th, 2020
565
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
VHDL 4.51 KB | None | 0 0
  1. -----------------------------------------------------------------------------
  2. -- I2C Master
  3. -----------------------------------------------------------------------------
  4. -- PA1 11 oct 2019 SvH  Initial empty version
  5. -- PA2 23 oct 2019 SvH  Corrected IO (removed ADR and added STOP)
  6. --                      Added alternative pad implementation for SDA
  7. -----------------------------------------------------------------------------
  8.  
  9. library ieee;
  10. use ieee.std_logic_1164.all;
  11. use ieee.numeric_std.all;
  12. use ieee.std_logic_unsigned.all;
  13.  
  14. -- I2C master
  15. entity I2C_MASTER is
  16. port(
  17. -- inputs
  18.    CLK         :in     std_logic;      -- System Clock
  19.    RST         :in     std_logic;      -- Sync reset active high
  20.    EN          :in     std_logic;      -- Enable
  21.    WR_N        :in     std_logic;      -- 0=Write, 1=Read
  22.    DELAY       :in     std_logic_vector(7 downto 0);  -- Delay configuration
  23.    STOP        :in     std_logic;      -- Generate STOP sequense after access
  24.    WR_BYTE     :in     std_logic_vector(7 downto 0);  -- write byte
  25.    -- I2C bus
  26.    SDA         :inout  std_logic;      -- I2C Data
  27.    SCL         :out    std_logic;      -- I2C Clock
  28. -- outputs
  29.    DONE        :out    std_logic;      -- I2C Master Done
  30.    IDLE        :out    std_logic;      -- I2C Master Idle
  31.    NO_ACK      :out    std_logic;      -- No Ack received from I2C Slave
  32.    RD_BYTE     :out    std_logic_vector(7 downto 0)  -- read byte
  33. );
  34. end I2C_MASTER;
  35.  
  36.  
  37. architecture RTL of I2C_MASTER is
  38.  
  39.    signal SDA_OE : std_logic;
  40.    signal SDA_OUT : std_logic;
  41.    signal SDA_IN : std_logic;
  42.  
  43.    type t_STATE is (s_IDLE, s_START1, s_START2, s_D_SU, s_D_HIGH, s_D_HOLD, s_A_SU, s_A_HIGH, s_A_HOLD, s_STOP1, s_STOP2);
  44.    signal STATE : t_STATE;
  45.  
  46.    signal DELAY_CNT : std_logic_vector(7 downto 0);
  47.    signal DELAY_DONE : std_logic;
  48.    signal BIT_CNT : integer range 0 to 7;
  49.  
  50. begin
  51.  
  52.   --delay counter
  53.   delay_proc : process(CLK)
  54.   begin
  55.     if rising_edge(CLK) then
  56.       if RST = '1' or DELAY_DONE = '1' or STATE = s_IDLE then
  57.         DELAY_CNT <= (others => '0');
  58.       end if;
  59.     else
  60.       DELAY_CNT <= DELAY_CNT + 1;
  61.     end if;
  62.   end process;
  63.  
  64.   DELAY_DONE <= '1' when DELAY_CNT = DELAY else '0';
  65.  
  66.   --bit counter
  67.   bit_counter : process(CLK)
  68.   begin
  69.     if rising_edge(CLK) then
  70.       if RST = '1' or STATE = s_IDLE then
  71.         BIT_CNT <= 7;
  72.       elsif STATE = s_D_HOLD and DELAY_DONE = '1' then
  73.         BIT_CNT <= BIT_CNT - 1;
  74.       end if;
  75.     end if;
  76.   end process;
  77.  
  78.   --control FSM
  79.   fsm_proc : process(CLK)
  80.   begin
  81.     if rising_edge(CLK) then
  82.       if RST = '1' then
  83.         STATE <= s_IDLE;
  84.       end if;
  85.     else
  86.       case STATE is
  87.         when s_IDLE =>
  88.           if EN = '1' then
  89.             SDA_OUT <= '1';
  90.             SCL <= '1';
  91.             STATE <= s_START1;
  92.           end if;
  93.  
  94.         when s_START1 =>
  95.           if DELAY_DONE = '1' then
  96.             SDA_OE <= '1';
  97.             SDA_OUT <= '0';
  98.             SCL <= '1';
  99.             STATE <= s_START2;
  100.           end if;
  101.  
  102.         when s_START2 =>
  103.           if DELAY_DONE = '1' then
  104.             SDA_OUT <= '0';
  105.             SCL <= '1';
  106.             STATE <= s_D_SU;
  107.           end if;
  108.  
  109.         when s_D_SU =>
  110.           if DELAY_DONE = '1' then
  111.             STATE <= s_D_HIGH;
  112.           end if;
  113.  
  114.         when s_D_HIGH =>
  115.           if DELAY_DONE = '1' then
  116.             STATE <= s_D_HOLD;
  117.           end if;
  118.  
  119.         when s_D_HOLD =>
  120.           if DELAY_DONE = '1' then
  121.             if BIT_CNT = 0 then
  122.               STATE <= s_A_SU;
  123.             else
  124.               STATE <= s_D_SU;
  125.             end if;
  126.           end if;
  127.  
  128.         when s_A_SU =>
  129.           if DELAY_DONE = '1' then
  130.             STATE <= s_A_HIGH;
  131.           end if;
  132.  
  133.         when s_A_HIGH =>
  134.           if DELAY_DONE = '1' then
  135.             STATE <= s_A_HOLD;
  136.           end if;
  137.  
  138.         when s_A_HOLD =>
  139.           if DELAY_DONE = '1' then
  140.             STATE <= s_STOP1;
  141.           end if;
  142.  
  143.         when s_STOP1 =>
  144.           if DELAY_DONE = '1' then
  145.             STATE <= s_STOP2;
  146.           end if;
  147.  
  148.         when s_STOP2 =>
  149.           if DELAY_DONE = '1' then
  150.             STATE <= s_IDLE;
  151.           end if;
  152.  
  153.         end case;
  154.     end if;
  155.   end process;
  156.  
  157. -- Her kommer ditt design :-)
  158.  
  159. -- Bidirectional Pad
  160. SDA_IN <= SDA;
  161.  
  162. -- implementation with active drive (less confusing)
  163. SDA <= SDA_OUT when SDA_OE = '1' else 'Z';
  164.  
  165. -- implementation with no drive to high level (pullup)
  166. --SDA <= '0' when SDA_OE = '1' and SDA_OUT = '0' else 'Z';
  167.  
  168. end RTL;
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement