@@ 62,7 62,6 @@ architecture a1 of spi_master_ctrl is
signal curr_counter : natural;
signal next_counter : natural;
- signal zero : std_logic;
signal set_lost_rx_data : std_logic;
@@ 72,6 71,7 @@ architecture a1 of spi_master_ctrl is
signal transmission_done : std_logic;
signal shifting_length : integer range 0 to MAX_SIZE;
+ signal clear_lost_rx_data : std_logic;
begin -- architecture a1
registers: process (clk_i) is
begin -- process registers
@@ 98,12 98,20 @@ begin -- architecture a1
next_state <= state;
next_counter <= counter;
end procedure switch_to;
+
+ variable zero : std_logic;
begin -- process state_sel
next_counter <= curr_counter;
if curr_counter /= 0 and clock_rising_i = '1' then
next_counter <= curr_counter - 1;
end if;
+ if curr_counter = 0 then
+ zero := '1';
+ else
+ zero := '0';
+ end if;
+
transmission_done <= '0';
next_state <= curr_state;
@@ 136,7 144,6 @@ begin -- architecture a1
sck_mask_o <= '1';
if zero = '1' then
- sck_mask_o <= '1';
transmission_done <= '1';
if pulse_csn_i = '1' then
switch_to(CSN_PULSE, CSN_PULSE_CYCLES);
@@ 145,26 152,21 @@ begin -- architecture a1
end if;
end if;
when NEXT_DATA =>
- next_state <= CSN_RISING;
csn_o <= '0';
+ sck_mask_o <= '0';
- if zero = '1' then
- if tx_got_data = '1' then
- if curr_counter = 0 then
- switch_to(SHIFTING, shifting_length);
- ack_tx_got_data <= '1';
- end if;
- else
- csn_o <= '1';
- switch_to(IDLE, 0);
- end if;
+ if tx_got_data = '1' then
+ sck_mask_o <= '1';
+ switch_to(SHIFTING, shifting_length - 1);
+ ack_tx_got_data <= '1';
+ else
+ switch_to(IDLE, 0);
end if;
-
when CSN_PULSE =>
csn_o <= '1';
if zero = '1' then
- switch_to(NEXT_DATA, 1);
+ switch_to(NEXT_DATA, 0);
end if;
when others =>
next_state <= RESET;
@@ 181,6 183,7 @@ begin -- architecture a1
latch_tx_data_o <= '0';
tx_got_data <= '0';
+ tx_ready_o <= '0';
case curr_tx_state is
when IDLE =>
@@ 189,7 192,6 @@ begin -- architecture a1
tx_ready_o <= '1';
if tx_valid_i = '1' then
- tx_got_data <= '1';
latch_tx_data_o <= '1';
next_tx_state <= TX_LATCHED;
@@ 205,7 207,13 @@ begin -- architecture a1
end if;
when TX_WAITING =>
if transmission_done = '1' and rx_block = '0' then
+ tx_ready_o <= '1';
next_tx_state <= TX_LATCHING_DATA;
+
+ if tx_valid_i = '1' then
+ next_tx_state <= TX_LATCHED;
+ latch_tx_data_o <= '1';
+ end if;
end if;
when others =>
next_tx_state <= IDLE;
@@ 267,12 275,12 @@ begin -- architecture a1
error_rx_lost : entity work.rs_latch
port map (
set_i => set_lost_rx_data,
- reset_i => clear_lost_rx_data_i,
+ reset_i => clear_lost_rx_data,
q_o => err_lost_rx_data_o);
-- Internal
+ clear_lost_rx_data <= '1' when clear_lost_rx_data_i = '1' or curr_state = RESET else '0';
shifting_length <= SIZES(to_integer(unsigned(size_sel_i)));
- zero <= '1' when curr_counter = 0 else '0';
-- Enable Outputs
miso_en_o <= '0';
@@ 221,7 221,9 @@ begin -- architecture a1
sd_i => rx_serial_data,
sd_o => open);
- tx_input_data <= rx_data_o(selected_size - 1) when selected_size > 0 else 'X';
+ tx_input_data <= tx_data_i(selected_size - 1) when latch_new_tx_data = '1' and latch_change_data_out = '1' else
+ rx_data_o(selected_size - 1) when selected_size > 0 else
+ 'X';
mosi_reg : entity work.reg
generic map (