diff --git a/cores/flashrom-wb/flashrom_controller.vhd b/cores/flashrom-wb/flashrom_controller.vhd index 23b0fc1..fa322d8 100644 --- a/cores/flashrom-wb/flashrom_controller.vhd +++ b/cores/flashrom-wb/flashrom_controller.vhd @@ -36,11 +36,12 @@ entity flashrom_controller is end entity flashrom_controller; architecture RTL of flashrom_controller is - constant spif_max_word_length : integer := 32; - constant max_dummy_bits : integer := 63; - constant bootup_delay : integer := 4000; + constant spif_max_word_length : integer := 32; + constant max_dummy_bits : integer := 63; + constant bootup_delay : integer := 4000; -- TODO: These times need to be dependent on f_clk! + constant status_reg_poll_delay : integer := 100000; -- TODO: These times need to be dependent on f_clk! - type state_t is (INIT, GETINFO, GETSTATUS, LOADPAGE, WRITEPAGE, IDLE); + type state_t is (INIT, GETINFO, GETSTATUS, LOADPAGE, WRITEPAGE, WAIT_BUSY, IDLE); signal state : state_t; signal spif_data_in_valid : std_logic; @@ -83,7 +84,9 @@ begin flashrom_controller_p : process(clk, rst) is variable write_cnt : integer range 0 to bootup_delay; - variable done : boolean; + variable delay_cnt : integer range 0 to status_reg_poll_delay; + + variable done : boolean; procedure default_state is begin @@ -107,6 +110,7 @@ begin spif_data_out_dummy_bits <= 0; write_cnt := 0; + delay_cnt := 0; end procedure reset_state; procedure run_command_single(constant data_in_length : integer; constant data_out_length : integer; constant data_out_dummy_bits : integer; constant nTxWords : integer; constant data_in : std_logic_vector) is @@ -142,11 +146,11 @@ begin case state is when INIT => words_sent <= 0; - if write_cnt = bootup_delay then - write_cnt := 0; + if delay_cnt = bootup_delay then + delay_cnt := 0; state <= GETINFO; else - write_cnt := write_cnt + 1; + delay_cnt := delay_cnt + 1; end if; when GETINFO => -- TODO: In simulation I can only call this command once?! run_command_single(8, 32, 8, 5, FLASHROM_COMMAND_MANUFACTURER_ID); @@ -155,6 +159,7 @@ begin end if; when IDLE => write_cnt := 0; + delay_cnt := 0; if status_update_stb = '1' then state <= GETSTATUS; end if; @@ -169,6 +174,21 @@ begin if done then status <= spif_data_out(7 downto 0); end if; + when WAIT_BUSY => + if delay_cnt = status_reg_poll_delay then + run_command_single(8, 8, 16, 3, FLASHROM_COMMAND_GET_STATUS); + if done then + status <= spif_data_out(7 downto 0); + delay_cnt := 0; + if spif_data_out(7) = '1' then + state <= IDLE; + else + state <= WAIT_BUSY; + end if; + end if; + else + delay_cnt := delay_cnt + 1; + end if; when LOADPAGE => run_command_single(32, 8, 34, 258, FLASHROM_COMMAND_CONT_ARRAY_READ & page); if spif_data_next = '1' or command_is_latched then @@ -186,6 +206,10 @@ begin spif_data_in_length <= 8; spif_data_in <= data_in & padBits(spif_data_in, data_in); end if; + if done then + delay_cnt := 0; + state <= WAIT_BUSY; + end if; end case; end if; end if;