axi_dac_interpolate: Fix low sampling rate issues

Intermittently DAC channel data is 0 after multiple new buffers.
Due to the low sampling rate and DMA flushing, it happens that the
transfer SM gets stuck in flushing mode right before the transmission
should start.

Another frequent issue happens when a new transmission is started.
A buffer must be pushed independently for each channel because of
separate DMAs.
After the first buffer is pushed the Linux driver deactivates the
start_sync flag. Not knowing if the other channel/buffer will be
active/pushed. The start_sync will be re-enabled with the second buffer.
The issue was that the SM of the first buffer went one step further
before the push if the second buffer,not being stopped by the
start_sync.

Signed-off-by: AndreiGrozav <andrei.grozav@analog.com>
main
AndreiGrozav 2024-04-09 19:41:13 +03:00 committed by AndreiGrozav
parent 4fc6922688
commit faf88adf85
2 changed files with 8 additions and 7 deletions

View File

@ -85,12 +85,10 @@ module axi_dac_interpolate_filter #(
reg cic_change_rate;
reg [31:0] interpolation_counter;
reg dma_data_valid = 1'b0;
reg dma_data_valid_adjacent = 1'b0;
reg filter_enable = 1'b0;
reg [15:0] dma_valid_m = 16'd0;
reg stop_transfer = 1'd0;
reg clear_stop_flag = 1'd0;
reg transfer = 1'd0;
reg [ 1:0] transfer_sm = 2'd0;
@ -196,11 +194,12 @@ module axi_dac_interpolate_filter #(
assign transfer_ready = start_sync_channels ?
dma_valid & dma_valid_adjacent :
dma_valid;
assign transfer_start = !(en_start_trigger ^ trigger) & transfer_ready;
assign transfer_start = !(en_start_trigger ^ trigger) &
transfer_ready & !dma_transfer_suspend;
always @(posedge dac_clk) begin
stop_transfer <= transfer_sm == IDLE ? 1'b0 :
stop_transfer |
(stop_transfer & !clear_stop_flag) |
dma_transfer_suspend |
(en_stop_trigger & trigger) |
(sync_stop_channels & dma_valid & dma_valid_adjacent);
@ -211,17 +210,19 @@ module axi_dac_interpolate_filter #(
case (transfer_sm)
IDLE: begin
transfer <= 1'b0;
if (dac_int_ready) begin
if (dac_int_ready & !dma_transfer_suspend) begin
transfer_sm_next <= WAIT;
end
end
WAIT: begin
transfer <= 1'b0;
if (transfer_start) begin
clear_stop_flag <= 1'b1;
transfer_sm_next <= TRANSFER;
end
end
TRANSFER: begin
clear_stop_flag <= 1'b0;
transfer <= 1'b1;
if (stop_transfer) begin
if (flush_dma_in) begin

View File

@ -72,7 +72,7 @@ module axi_dac_interpolate_reg(
// internal registers
reg [31:0] up_version = {16'h0002, /* MAJOR */
8'h03, /* MINOR */
8'h04, /* MINOR */
8'h00}; /* PATCH */
reg [31:0] up_scratch = 32'h0;