-- SPI Read and Read modify Write Access example -- Revision 1.0 25th Oct '21 Author Miky -- -- This code receives reset, clk, rw, address(7-0),data(7-0), mask(7-0), en -- outputs ssn, mosi, scl -- gets data from miso -- and returns data rreg(7-0) -- The address (7-0) and en must be change their state before -- the rising edge of clk, and hold until the busy status returns to '0' -- While busy is high, toggling en is ignored. -- rw = '1' : Read/ rw = '0' : Read Modify Write library IEEE; use IEEE.std_logic_1164.all; use ieee.numeric_std.all; entity spi_rmw is port( clk :in std_logic; reset :in std_logic; rw :in std_logic; en :in std_logic; address,data,mask :in unsigned(7 downto 0); busy :inout std_logic; rreg :inout unsigned(7 downto 0); ssn, sck,mosi :out std_logic; miso :in std_logic ); end spi_rmw; architecture archspi of spi_rmw is signal en1, en2 :std_logic; signal count :unsigned(7 downto 0); signal sclen :std_logic; signal reg1 :unsigned(16 downto 0); signal wreg :unsigned(15 downto 0); begin spi01:process(clk, reset, rw, en, address, miso) begin if reset = '0' then count <= "00000000"; en1 <= '0'; en2 <= '0'; busy <= '0'; ssn <= '1'; sck <= '0'; sclen <= '0'; elsif (clk'event and clk = '1') then en1 <= en; en2 <= en1; if (en1 = '1' and en2 ='0' and busy = '0') then busy <= '1'; ssn<='0'; sclen <= '1'; mosi <= '1'; wreg(15 downto 8) <= address(7 downto 0); wreg(7 downto 0) <= X"FF"; end if; if(busy = '1') then count <= count + 1; else count <= "00000000"; end if; if (count = 33) then sclen <= '0'; end if; if (count = 34) then ssn <= '1'; end if; if (count = 63) then ssn <= '0'; sclen <= '1'; mosi <= '1'; end if; if (count = 97) then sclen <= '0'; end if; if (count = 98) then ssn <= '1'; end if; if (count = 127) then ssn <= '0'; sclen <= '1'; mosi <= '0'; end if; if (count = 161) then sclen <= '0'; end if; if (count = 162) then ssn <= '1'; end if; if (count = 125 and rw = '1') then busy <= '0'; end if; if (count = 191 and rw = '0') then busy <= '0'; end if; if(count(0) = '0' and sclen = '1') then sck <= '1'; else sck <= '0'; end if; if ( count(0)='1' and sclen = '1') then wreg(0) <= '1'; for i in 0 to 14 loop wreg(i + 1) <=wreg(i); end loop; mosi <= wreg(15); end if; if ( count(0)='0' and sclen = '1') then reg1(0) <=miso; for i in 0 to 15 loop reg1(i + 1) <=reg1(i); end loop; end if; if(count = 98) then rreg(7 downto 0) <= reg1(7 downto 0); end if; if(count = 100) then wreg(15 downto 8) <= address(7 downto 0); for i in 0 to 7 loop if( mask(i) = '0' ) then wreg(i) <= rreg(i); else wreg(i) <= data(i); end if; end loop; end if; end if; end process; end archspi;