flashrom: Added wait-not-busy after write

This commit is contained in:
Markus Koch 2016-12-06 21:24:09 +01:00
parent 265d1a80e1
commit 054ae0e210

View File

@ -38,9 +38,10 @@ end entity flashrom_controller;
architecture RTL of flashrom_controller is architecture RTL of flashrom_controller is
constant spif_max_word_length : integer := 32; constant spif_max_word_length : integer := 32;
constant max_dummy_bits : integer := 63; constant max_dummy_bits : integer := 63;
constant bootup_delay : integer := 4000; 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 state : state_t;
signal spif_data_in_valid : std_logic; signal spif_data_in_valid : std_logic;
@ -83,6 +84,8 @@ begin
flashrom_controller_p : process(clk, rst) is flashrom_controller_p : process(clk, rst) is
variable write_cnt : integer range 0 to bootup_delay; variable write_cnt : integer range 0 to bootup_delay;
variable delay_cnt : integer range 0 to status_reg_poll_delay;
variable done : boolean; variable done : boolean;
procedure default_state is procedure default_state is
@ -107,6 +110,7 @@ begin
spif_data_out_dummy_bits <= 0; spif_data_out_dummy_bits <= 0;
write_cnt := 0; write_cnt := 0;
delay_cnt := 0;
end procedure reset_state; 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 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 case state is
when INIT => when INIT =>
words_sent <= 0; words_sent <= 0;
if write_cnt = bootup_delay then if delay_cnt = bootup_delay then
write_cnt := 0; delay_cnt := 0;
state <= GETINFO; state <= GETINFO;
else else
write_cnt := write_cnt + 1; delay_cnt := delay_cnt + 1;
end if; end if;
when GETINFO => -- TODO: In simulation I can only call this command once?! when GETINFO => -- TODO: In simulation I can only call this command once?!
run_command_single(8, 32, 8, 5, FLASHROM_COMMAND_MANUFACTURER_ID); run_command_single(8, 32, 8, 5, FLASHROM_COMMAND_MANUFACTURER_ID);
@ -155,6 +159,7 @@ begin
end if; end if;
when IDLE => when IDLE =>
write_cnt := 0; write_cnt := 0;
delay_cnt := 0;
if status_update_stb = '1' then if status_update_stb = '1' then
state <= GETSTATUS; state <= GETSTATUS;
end if; end if;
@ -169,6 +174,21 @@ begin
if done then if done then
status <= spif_data_out(7 downto 0); status <= spif_data_out(7 downto 0);
end if; 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 => when LOADPAGE =>
run_command_single(32, 8, 34, 258, FLASHROM_COMMAND_CONT_ARRAY_READ & page); run_command_single(32, 8, 34, 258, FLASHROM_COMMAND_CONT_ARRAY_READ & page);
if spif_data_next = '1' or command_is_latched then if spif_data_next = '1' or command_is_latched then
@ -186,6 +206,10 @@ begin
spif_data_in_length <= 8; spif_data_in_length <= 8;
spif_data_in <= data_in & padBits(spif_data_in, data_in); spif_data_in <= data_in & padBits(spif_data_in, data_in);
end if; end if;
if done then
delay_cnt := 0;
state <= WAIT_BUSY;
end if;
end case; end case;
end if; end if;
end if; end if;