type ram_t is array(0 to 15) of std_logic_vector(31 downto 0);
signal ram : ram_t;
- signal ram_addr : integer range 0 to 15;
+ signal ram_addr : integer range 0 to 31;
signal ram_data : std_logic_vector(31 downto 0);
signal ctrl_reg : std_logic_vector(31 downto 0);
signal start : std_logic;
signal time_count : integer range 0 to 7;
signal readback : std_logic_vector(31 downto 0);
- type fsm_t is (IDLE, WAIT_STATE, SET, FINISH);
+ type fsm_t is (IDLE, WAIT_STATE, SET, TOGGLE_CS, TOGGLE_CS_0, TOGGLE_CS_1, TOGGLE_CS_2, FINISH);
signal fsm_state : fsm_t;
begin
start <= '0';
if BUS_WRITE_IN = '1' then
- if BUS_ADDR_IN(4) = '0' then
- ram(addr) <= BUS_DATA_IN;
+ if fsm_state = IDLE then
BUS_ACK_OUT <= '1';
- elsif BUS_ADDR_IN(0) = '1' then
- if fsm_state = IDLE then
+ if BUS_ADDR_IN(4) = '0' then
+ ram(addr) <= BUS_DATA_IN;
+ elsif BUS_ADDR_IN(0) = '1' then
ctrl_reg <= BUS_DATA_IN;
- BUS_ACK_OUT <= '1';
start <= '1';
- else
- BUS_BUSY_OUT <= '1';
+ else --if BUS_ADDR_IN(0) = '0' then
+ chipselect_reg <= BUS_DATA_IN(15 downto 0);
end if;
- else --if BUS_ADDR_IN(1) = '0' then
- chipselect_reg <= BUS_DATA_IN(15 downto 0);
- BUS_ACK_OUT <= '1';
+ else
+ BUS_BUSY_OUT <= '1';
end if;
end if;
if start = '1' then
ram_addr <= 0;
- word_count <= to_integer(unsigned(ctrl_reg(3 downto 0)));
+ word_count <= to_integer(unsigned(ctrl_reg(4 downto 0)));
bit_count <= 31;
time_count <= 7;
fsm_state <= WAIT_STATE;
ram_addr <= ram_addr + 1;
bit_count <= 31;
if ram_addr /= word_count -1 then
- fsm_state <= WAIT_STATE;
+ if ctrl_reg(7) = '0' then --one CS phase
+ fsm_state <= WAIT_STATE;
+ else --one CS per word
+ fsm_state <= TOGGLE_CS;
+ end if;
else
fsm_state <= FINISH;
end if;
fsm_state <= WAIT_STATE;
readback <= readback(30 downto 0) & SPI_SDI_IN;
end if;
+ when TOGGLE_CS =>
+ if time_count = 0 and spi_sck = '0' then
+ time_count <= 7;
+ spi_sck <= not spi_sck;
+ readback <= readback(30 downto 0) & SPI_SDI_IN;
+ elsif time_count = 0 and spi_sck = '1' then
+ fsm_state <= TOGGLE_CS_0;
+ else
+ time_count <= time_count - 1;
+ end if;
+ when TOGGLE_CS_0 =>
+ time_count <= time_count - 1;
+ if time_count = 0 then
+ spi_cs <= x"ffff";
+ fsm_state <= TOGGLE_CS_1;
+ time_count <= 7;
+ end if;
+ when TOGGLE_CS_1 =>
+ time_count <= time_count - 1;
+ if time_count = 0 then
+ spi_cs <= not chipselect_reg;
+ bit_count <= 31;
+ fsm_state <= WAIT_STATE;
+ time_count <= 7;
+ end if;
+ when TOGGLE_CS_2 =>
+ time_count <= time_count - 1;
+ if time_count = 0 then
+ spi_sck <= not spi_sck;
+ fsm_state <= WAIT_STATE;
+ time_count <= 7;
+ end if;
when FINISH =>
if time_count = 0 and spi_sck = '0' then
time_count <= 7;