Fix operation of FSI master in error recovery paths

Invert FSI data in signal to match electrical interface specification
parent d66efb75
......@@ -102,7 +102,7 @@ module fsi_master_interface(
reg ipoll_error_reg = 0;
assign fsi_clock_out = peripheral_clock; // Clock is allowed to always run
assign fsi_data_out = ~fsi_data_reg; // FSI data line is electrically inverted
assign fsi_data_in_internal = fsi_data_in;
assign fsi_data_in_internal = ~fsi_data_in;
assign fsi_data_direction = fsi_data_direction_reg;
assign cycle_complete = cycle_complete_reg;
assign cycle_error = cycle_error_reg;
......@@ -122,6 +122,7 @@ module fsi_master_interface(
reg [20:0] last_address = 0;
reg last_address_valid = 0;
reg [7:0] fsi_command_code = 0;
reg [7:0] fsi_command_code_length = 0;
reg fsi_command_code_set = 0;
reg crc_protected_bits_transmitting = 0;
reg crc_protected_bits_receiving = 0;
......@@ -152,7 +153,7 @@ module fsi_master_interface(
case (control_state)
FSI_INITIALIZE_STATE_01: begin
// Set up BREAK command
cycle_counter <= 256;
cycle_counter <= FSI_CODEWORD_TX_MSG_BREAK_LEN;
control_state <= FSI_INITIALIZE_STATE_02;
end
FSI_INITIALIZE_STATE_02: begin
......@@ -208,12 +209,14 @@ module fsi_master_interface(
end else if (enable_ipoll && ((ipoll_start_timer > FSI_IPOLL_IDLE_START_CYCLES)
|| (commands_since_last_ipoll >= FSI_IPOLL_MAX_SEQ_STD_COMMANDS))) begin
// Send I_POLL
//
// NOTE: IPOLL requests can override any other incoming command requests.
// if no IPOLL has been issued for the past FSI_IPOLL_MAX_SEQ_STD_COMMANDS
// number of command requests. This is to ensure that interrupts are not
// lost under heavy I/O load.
if (enable_ipoll) begin
fsi_command_code <= FSI_CODEWORD_TX_MSG_I_POLL_DAT;
fsi_command_code_length <= FSI_CODEWORD_TX_MSG_I_POLL_LEN;
cycle_counter <= FSI_CODEWORD_TX_MSG_I_POLL_LEN;
fsi_command_code_set <= 1;
ipoll_in_process <= 1;
......@@ -253,9 +256,11 @@ module fsi_master_interface(
if (!fsi_command_code_set) begin
if (last_address_valid && (last_address[20:2] == address_reg[20:2])) begin
fsi_command_code <= FSI_CODEWORD_TX_MSG_SAME_ADR_DAT;
fsi_command_code_length <= FSI_CODEWORD_TX_MSG_SAME_ADR_LEN;
cycle_counter <= FSI_CODEWORD_TX_MSG_SAME_ADR_LEN;
end else if (last_address_valid && (last_address[20:8] == address_reg[20:8])) begin
fsi_command_code <= FSI_CODEWORD_TX_MSG_REL_ADR_DAT;
fsi_command_code_length <= FSI_CODEWORD_TX_MSG_REL_ADR_LEN;
cycle_counter <= FSI_CODEWORD_TX_MSG_REL_ADR_LEN;
if (address_reg < last_address) begin
fsi_rel_address_delta_negative <= 1;
......@@ -266,6 +271,7 @@ module fsi_master_interface(
end
end else begin
fsi_command_code <= FSI_CODEWORD_TX_MSG_ABS_ADR_DAT;
fsi_command_code_length <= FSI_CODEWORD_TX_MSG_ABS_ADR_LEN;
cycle_counter <= FSI_CODEWORD_TX_MSG_ABS_ADR_LEN;
end
fsi_command_code_set <= 1;
......@@ -280,10 +286,10 @@ module fsi_master_interface(
fsi_data_reg_internal = fsi_command_code[cycle_counter-1];
cycle_counter <= cycle_counter - 1;
if (cycle_counter == 1) begin
if ((fsi_command_code == FSI_CODEWORD_TX_MSG_D_POLL_DAT)
|| (fsi_command_code == FSI_CODEWORD_TX_MSG_E_POLL_DAT)
|| (fsi_command_code == FSI_CODEWORD_TX_MSG_I_POLL_DAT)
|| (fsi_command_code == FSI_CODEWORD_TX_MSG_TERM_DAT)) begin
if (((fsi_command_code == FSI_CODEWORD_TX_MSG_D_POLL_DAT) && (fsi_command_code_length == FSI_CODEWORD_TX_MSG_D_POLL_LEN))
|| ((fsi_command_code == FSI_CODEWORD_TX_MSG_E_POLL_DAT) && (fsi_command_code_length == FSI_CODEWORD_TX_MSG_E_POLL_LEN))
|| ((fsi_command_code == FSI_CODEWORD_TX_MSG_I_POLL_DAT) && (fsi_command_code_length == FSI_CODEWORD_TX_MSG_I_POLL_LEN))
|| ((fsi_command_code == FSI_CODEWORD_TX_MSG_TERM_DAT) && (fsi_command_code_length == FSI_CODEWORD_TX_MSG_TERM_LEN))) begin
cycle_counter <= 4;
control_state <= FSI_TRANSFER_STATE_TX09;
end else begin
......@@ -302,10 +308,10 @@ module fsi_master_interface(
crc_protected_bits_transmitting = 1;
fsi_data_reg_internal = ~data_direction_reg;
control_state <= FSI_TRANSFER_STATE_TX06;
if (fsi_command_code == FSI_CODEWORD_TX_MSG_SAME_ADR_DAT) begin
if ((fsi_command_code == FSI_CODEWORD_TX_MSG_SAME_ADR_DAT) && (fsi_command_code_length == FSI_CODEWORD_TX_MSG_SAME_ADR_LEN)) begin
address_tx_reg <= address_reg;
cycle_counter <= 2;
end else if (fsi_command_code == FSI_CODEWORD_TX_MSG_REL_ADR_DAT) begin
end else if ((fsi_command_code == FSI_CODEWORD_TX_MSG_REL_ADR_DAT) && (fsi_command_code_length == FSI_CODEWORD_TX_MSG_REL_ADR_LEN)) begin
// Set up bit 8 of the address as the sign bit per the specification.
//
// NOTE: The specification is unclear about the meaning of the sign bit,
......@@ -524,7 +530,8 @@ module fsi_master_interface(
if (enhanced_error_recovery_reg[0] && (slave_error_recovery_state == 0)) begin
// Configure state machine to resend command message
slave_error_recovery_state <= 1;
control_state <= FSI_TRANSFER_STATE_TR01;
cycle_counter <= 4;
control_state <= FSI_TRANSFER_STATE_RX06;
end else begin
// Master does not support enhanced error recovery or error recovery fauled
if (ipoll_in_process) begin
......@@ -632,6 +639,7 @@ module fsi_master_interface(
end else if (master_error_recovery_state == 1) begin
// Send E_POLL
fsi_command_code <= FSI_CODEWORD_TX_MSG_E_POLL_DAT;
fsi_command_code_length <= FSI_CODEWORD_TX_MSG_E_POLL_LEN;
cycle_counter <= FSI_CODEWORD_TX_MSG_E_POLL_LEN;
fsi_command_code_set <= 1;
crc_data <= 0;
......@@ -642,6 +650,7 @@ module fsi_master_interface(
if (fsi_master_timeout_counter < FSI_MASTER_TIMEOUT_CYCLES) begin
// Send D_POLL
fsi_command_code <= FSI_CODEWORD_TX_MSG_D_POLL_DAT;
fsi_command_code_length <= FSI_CODEWORD_TX_MSG_D_POLL_LEN;
cycle_counter <= FSI_CODEWORD_TX_MSG_D_POLL_LEN;
fsi_command_code_set <= 1;
crc_data <= 0;
......@@ -649,6 +658,7 @@ module fsi_master_interface(
end else begin
// Send TERM
fsi_command_code <= FSI_CODEWORD_TX_MSG_TERM_DAT;
fsi_command_code_length <= FSI_CODEWORD_TX_MSG_TERM_LEN;
cycle_counter <= FSI_CODEWORD_TX_MSG_TERM_LEN;
if (ipoll_in_process) begin
ipoll_error_reg <= 1;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment