diff --git a/fw/rtl/sd/sd_dma.v b/fw/rtl/sd/sd_dma.v index 3a4e29c..64167ad 100644 --- a/fw/rtl/sd/sd_dma.v +++ b/fw/rtl/sd/sd_dma.v @@ -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 diff --git a/fw/rtl/sd/sd_interface.v b/fw/rtl/sd/sd_interface.v index 80709d6..ac2d622 100644 --- a/fw/rtl/sd/sd_interface.v +++ b/fw/rtl/sd/sd_interface.v @@ -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; diff --git a/fw/rtl/sd/sd_regs.v b/fw/rtl/sd/sd_regs.v index 0ef8629..4ae4434 100644 --- a/fw/rtl/sd/sd_regs.v +++ b/fw/rtl/sd/sd_regs.v @@ -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 diff --git a/sw/bootloader/src/sc64/sc64_regs.h b/sw/bootloader/src/sc64/sc64_regs.h index 10a5094..399bb64 100644 --- a/sw/bootloader/src/sc64/sc64_regs.h +++ b/sw/bootloader/src/sc64/sc64_regs.h @@ -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 diff --git a/sw/bootloader/src/sc64/sc64_sd.c b/sw/bootloader/src/sc64/sc64_sd.c index c51a7f3..a8ae0ca 100644 --- a/sw/bootloader/src/sc64/sc64_sd.c +++ b/sw/bootloader/src/sc64/sc64_sd.c @@ -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; }