sd dma fix

This commit is contained in:
Polprzewodnikowy 2021-02-06 19:30:06 +01:00
parent fb17b9c540
commit cb17198089
5 changed files with 17 additions and 18 deletions

View File

@ -4,8 +4,8 @@ module sd_dma (
input [3:0] i_dma_bank,
input [23:0] i_dma_address,
input [14:0] i_dma_length,
output [14:0] o_dma_left,
input [17:0] i_dma_length,
output [17:0] o_dma_left,
input i_dma_load_bank_address,
input i_dma_load_length,
input i_dma_direction,
@ -47,14 +47,14 @@ module sd_dma (
end
end
reg [14:0] r_remaining;
reg [17:0] r_remaining;
assign o_dma_left = r_remaining;
always @(posedge i_clk) begin
if (i_dma_load_length && !o_dma_busy) begin
r_remaining <= i_dma_length;
end else if (w_request_successful && r_remaining > 15'd0) begin
end else if (w_request_successful && r_remaining > 18'd0) begin
r_remaining <= r_remaining - 1'd1;
end
end
@ -66,7 +66,7 @@ module sd_dma (
if (i_dma_start && !o_dma_busy) begin
o_dma_busy <= 1'b1;
end
if (i_dma_stop || (w_request_successful && r_remaining == 15'd0)) begin
if (i_dma_stop || (w_request_successful && r_remaining == 18'd0)) begin
o_dma_busy <= 1'b0;
end
end

View File

@ -187,8 +187,8 @@ module sd_interface (
wire [3:0] w_dma_bank;
wire [23:0] w_dma_address;
wire [14:0] w_dma_length;
wire [14:0] w_dma_left;
wire [17:0] w_dma_length;
wire [17:0] w_dma_left;
wire w_dma_load_bank_address;
wire w_dma_load_length;
wire w_dma_direction;

View File

@ -38,10 +38,10 @@ module sd_regs (
output reg [3:0] o_dma_bank,
output reg [23:0] o_dma_address,
output reg [14:0] o_dma_length,
output reg [17:0] o_dma_length,
input [3:0] i_dma_bank,
input [23:0] i_dma_address,
input [14:0] i_dma_left,
input [17:0] i_dma_left,
output reg o_dma_load_bank_address,
output reg o_dma_load_length,
output reg o_dma_direction,
@ -73,7 +73,7 @@ module sd_regs (
always @(*) begin
o_dma_bank = i_data[31:28];
o_dma_address = i_data[25:2];
o_dma_length = i_data[14:0];
o_dma_length = i_data[17:0];
o_dma_load_bank_address = w_write_request && !i_address[3] && (i_address[2:0] == SD_REG_DMA_ADDR);
o_dma_load_length = w_write_request && !i_address[3] && (i_address[2:0] == SD_REG_DMA_LEN);
o_busy = 1'b0;
@ -210,7 +210,7 @@ module sd_regs (
end
SD_REG_DMA_LEN: begin
o_data <= {17'd0, i_dma_left};
o_data <= {14'd0, i_dma_left};
end
endcase
end else begin

View File

@ -165,8 +165,8 @@ typedef struct sc64_sd_registers_s {
#define SC64_SD_DMA_BANK_GET(addr) (((addr) >> 28) & 0xF)
#define SC64_SD_DMA_BANK_ADDR(b, a) ((((b) & 0xF) << 28) | ((a) & 0x3FFFFFC))
#define SC64_SD_DMA_LEN_GET(len) (((len) & 0x7FFF) * 4)
#define SC64_SD_DMA_LEN(l) ((((l) / 4) - 1) & 0x7FFF)
#define SC64_SD_DMA_LEN_GET(len) (((len) & 0x3FFFF) * 4)
#define SC64_SD_DMA_LEN(l) ((((l) / 4) - 1) & 0x3FFFF)
#endif

View File

@ -379,7 +379,6 @@ sc64_sd_err_t sc64_sd_read_sectors(uint32_t starting_sector, size_t count, void
}
sc64_sd_err_t sc64_sd_read_sectors_dma(uint32_t starting_sector, size_t count, uint8_t bank, uint32_t address) {
size_t num_transfers;
size_t sectors_left;
uint32_t current_sector;
uint32_t current_address;
@ -397,7 +396,6 @@ sc64_sd_err_t sc64_sd_read_sectors_dma(uint32_t starting_sector, size_t count, u
return E_PAR_ERROR;
}
num_transfers = (count / 2048) + 1;
sectors_left = count;
current_sector = starting_sector;
if (!sd_card_type_block) {
@ -405,7 +403,7 @@ sc64_sd_err_t sc64_sd_read_sectors_dma(uint32_t starting_sector, size_t count, u
}
current_address = address;
for (size_t i = 0; i < num_transfers; i++) {
do {
num_blocks = (sectors_left > 2048) ? 2048 : sectors_left;
platform_pi_io_write(&SC64_SD->DMA_ADDR, SC64_SD_DMA_BANK_ADDR(bank, current_address));
@ -450,9 +448,10 @@ sc64_sd_err_t sc64_sd_read_sectors_dma(uint32_t starting_sector, size_t count, u
while (platform_pi_io_read(&SC64_SD->DMA_SCR) & SC64_SD_DMA_SCR_BUSY);
current_sector += sd_card_type_block ? 1 : SD_BLOCK_SIZE;
sectors_left -= num_blocks;
current_sector += num_blocks * (sd_card_type_block ? 1 : SD_BLOCK_SIZE);
current_address += num_blocks * SD_BLOCK_SIZE;
}
} while (sectors_left > 0);
return E_OK;
}