From aa7483151174b0a137753cfa559969627ab22568 Mon Sep 17 00:00:00 2001 From: Polprzewodnikowy Date: Fri, 19 Feb 2021 01:36:57 +0100 Subject: [PATCH] save writeback on reset fully working --- fw/SummerCart64.qsf | 8 +- fw/constraints.sdc | 7 +- fw/rtl/sd/sd_dat.v | 23 ++- fw/rtl/sd/sd_interface.v | 3 + fw/rtl/sd/sd_regs.v | 4 +- fw/rtl/top.v | 2 +- sw/bootloader/src/fatfs/diskio.c | 14 +- sw/bootloader/src/loader/loader.c | 18 --- sw/bootloader/src/loader/loader.h | 1 - sw/bootloader/src/sc64/sc64_regs.h | 4 + sw/bootloader/src/sc64/sc64_sd.c | 229 +++++++++++++++++----------- sw/bootloader/src/sc64/sc64_sd.h | 4 +- sw/bootloader/src/sc64/sc64_sd_fs.c | 8 +- 13 files changed, 194 insertions(+), 131 deletions(-) diff --git a/fw/SummerCart64.qsf b/fw/SummerCart64.qsf index ef2aaa0..3c41e7a 100644 --- a/fw/SummerCart64.qsf +++ b/fw/SummerCart64.qsf @@ -19,7 +19,7 @@ # # Quartus Prime # Version 20.1.1 Build 720 11/11/2020 SJ Lite Edition -# Date created = 00:33:20 February 17, 2021 +# Date created = 01:35:54 February 19, 2021 # # -------------------------------------------------------------------------- # # @@ -77,6 +77,7 @@ set_global_assignment -name VERILOG_FILE rtl/top.v set_global_assignment -name VERILOG_FILE rtl/usb/usb_ftdi_fsi.v set_global_assignment -name VERILOG_FILE rtl/usb/usb_pc.v set_global_assignment -name VERILOG_INCLUDE_FILE rtl/constants.vh +set_global_assignment -name SLD_FILE db/signal_tap_logic_analyzer_auto_stripped.stp # Pin & Location Assignments # ========================== @@ -272,11 +273,10 @@ set_global_assignment -name OUTPUT_IO_TIMING_FAR_END_VMEAS "HALF SIGNAL SWING" - set_global_assignment -name PARTITION_NETLIST_TYPE SOURCE -section_id Top set_global_assignment -name PARTITION_FITTER_PRESERVATION_LEVEL PLACEMENT_AND_ROUTING -section_id Top set_global_assignment -name PARTITION_COLOR 16764057 -section_id Top + set_instance_assignment -name PARTITION_HIERARCHY root_partition -to | -section_id Top # end DESIGN_PARTITION(Top) # ------------------------- # end ENTITY(top) -# --------------- -set_global_assignment -name SLD_FILE db/signal_tap_logic_analyzer_auto_stripped.stp -set_instance_assignment -name PARTITION_HIERARCHY root_partition -to | -section_id Top \ No newline at end of file +# --------------- \ No newline at end of file diff --git a/fw/constraints.sdc b/fw/constraints.sdc index 9485af5..1c52faa 100644 --- a/fw/constraints.sdc +++ b/fw/constraints.sdc @@ -43,14 +43,13 @@ set_false_path -from [get_ports {i_ftdi_so i_ftdi_cts}] set_output_delay -clock [get_clocks {sd_clk}] -max 6.0 [get_ports {io_sd_cmd io_sd_dat[*]}] set_output_delay -clock [get_clocks {sd_clk}] -min -2.0 [get_ports {io_sd_cmd io_sd_dat[*]}] -set_input_delay -clock [get_clocks {sd_clk}] -max 14.0 [get_ports {io_sd_cmd io_sd_dat[*]}] -set_input_delay -clock [get_clocks {sd_clk}] -min 2.5 [get_ports {io_sd_cmd io_sd_dat[*]}] +set_input_delay -clock [get_clocks {sd_clk}] -max 15.0 [get_ports {io_sd_cmd io_sd_dat[*]}] +set_input_delay -clock [get_clocks {sd_clk}] -min 6.5 [get_ports {io_sd_cmd io_sd_dat[*]}] -set_multicycle_path -setup -start 1 -from [get_clocks $sys_clk] -to [get_clocks {sd_clk}] set_multicycle_path -hold -start 1 -from [get_clocks $sys_clk] -to [get_clocks {sd_clk}] set_multicycle_path -setup -end 3 -from [get_clocks {sd_clk}] -to [get_clocks $sys_clk] -set_multicycle_path -hold -end 2 -from [get_clocks {sd_clk}] -to [get_clocks $sys_clk] +set_multicycle_path -hold -end 1 -from [get_clocks {sd_clk}] -to [get_clocks $sys_clk] # N64, PI and SI timings diff --git a/fw/rtl/sd/sd_dat.v b/fw/rtl/sd/sd_dat.v index 10c0863..7d4bd1c 100644 --- a/fw/rtl/sd/sd_dat.v +++ b/fw/rtl/sd/sd_dat.v @@ -17,6 +17,7 @@ module sd_dat ( output o_dat_write_busy, output reg o_dat_crc_error, output reg o_dat_write_error, + output reg o_dat_write_ok, input i_rx_fifo_overrun, output reg o_rx_fifo_push, @@ -41,7 +42,7 @@ module sd_dat ( reg [6:0] r_state; assign o_dat_busy = !r_state[STATE_IDLE]; - assign o_dat_write_busy = r_state[STATE_SENDING] || r_state[STATE_STATUS] || r_state[STATE_BUSY]; + assign o_dat_write_busy = !io_sd_dat[0]; // Bit counter logic @@ -50,13 +51,13 @@ module sd_dat ( reg r_bit_counter_done; wire w_read_start = r_state[STATE_READ_WAIT] && !io_sd_dat[0] && i_sd_clk_strobe_rising; - wire w_write_start = r_state[STATE_WRITE_WAIT] && (i_tx_fifo_items == ({1'b0, i_dat_block_size} + 1)) && i_sd_clk_strobe_falling; + wire w_write_start = r_state[STATE_WRITE_WAIT] && (i_tx_fifo_items >= ({1'b0, i_dat_block_size} + 1)) && i_sd_clk_strobe_falling; wire w_status_start = r_state[STATE_SENDING] && r_bit_counter_done; wire w_status_done = r_state[STATE_STATUS] && r_bit_counter_done; wire w_block_read_done = r_state[STATE_RECEIVING] && r_bit_counter_done; wire w_block_write_done = r_state[STATE_SENDING] && r_bit_counter_done; - wire w_block_done = w_block_read_done || w_block_write_done; wire w_block_write_busy_done = r_state[STATE_BUSY] && io_sd_dat[0]; + wire w_block_done = w_block_read_done || w_block_write_busy_done; wire [12:0] w_block_bit_length = i_dat_width ? ({2'b00, {1'b0, i_dat_block_size} + 1'd1, 3'b000}) : ({{1'b0, i_dat_block_size} + 1'd1, 5'b00000}); @@ -138,12 +139,14 @@ module sd_dat ( reg [4:0] r_status; + wire w_no_write_error = r_status == STATUS_NO_ERROR; wire w_crc_write_error = r_status == STATUS_CRC_ERROR; wire w_data_write_error = r_status == STATUS_WRITE_ERROR; always @(posedge i_clk) begin - if (i_reset) begin + if (i_reset || w_block_start) begin o_dat_crc_error <= 1'b0; + o_dat_write_error <= 1'b0; end else begin if (w_block_read_done) begin o_dat_crc_error <= w_crc_read_error; @@ -151,6 +154,7 @@ module sd_dat ( if (w_status_done) begin o_dat_crc_error <= w_crc_write_error; o_dat_write_error <= w_data_write_error; + o_dat_write_ok <= w_no_write_error; end end end @@ -230,7 +234,7 @@ module sd_dat ( r_state[STATE_BUSY]: begin if (w_block_write_busy_done) begin - if (w_block_stop) begin + if (w_block_stop || !w_no_write_error) begin r_state[STATE_IDLE] <= 1'b1; end else begin r_state[STATE_WRITE_WAIT] <= 1'b1; @@ -274,7 +278,7 @@ module sd_dat ( wire w_tx_latch = r_state[STATE_SENDING] && i_sd_clk_strobe_falling; wire w_tx_data_phase = r_bit_counter >= 13'd17; wire w_tx_crc_phase = r_bit_counter >= 13'd1; - wire w_tx_fifo_pop = i_dat_width ? (r_bit_counter[2:0] == 3'd0) : (r_bit_counter[4:0] == 5'd16); + wire w_tx_fifo_pop = i_dat_width ? (r_bit_counter[2:0] == 3'd0) : (r_bit_counter[4:0] == 5'd17); wire w_tx_shift_load = r_bit_counter[2:0] == 3'd0; reg [7:0] r_tx_shift [0:3]; @@ -309,7 +313,12 @@ module sd_dat ( end end end else begin - r_tx_shift[0] <= i_tx_fifo_data[{3'b000, r_bit_counter[4:3]} +: 8]; + case (r_bit_counter[4:3]) + 2'b10: r_tx_shift[0] <= i_tx_fifo_data[31:24]; + 2'b01: r_tx_shift[0] <= i_tx_fifo_data[23:16]; + 2'b00: r_tx_shift[0] <= i_tx_fifo_data[15:8]; + 2'b11: r_tx_shift[0] <= i_tx_fifo_data[7:0]; + endcase end end end else if (w_tx_crc_phase) begin diff --git a/fw/rtl/sd/sd_interface.v b/fw/rtl/sd/sd_interface.v index 222495f..27ea16a 100644 --- a/fw/rtl/sd/sd_interface.v +++ b/fw/rtl/sd/sd_interface.v @@ -159,6 +159,7 @@ module sd_interface ( wire w_dat_write_busy; wire w_dat_crc_error; wire w_dat_write_error; + wire w_dat_write_ok; sd_dat sd_dat_inst ( .i_clk(i_clk), @@ -179,6 +180,7 @@ module sd_interface ( .o_dat_write_busy(w_dat_write_busy), .o_dat_crc_error(w_dat_crc_error), .o_dat_write_error(w_dat_write_error), + .o_dat_write_ok(w_dat_write_ok), .i_rx_fifo_overrun(w_rx_fifo_overrun), .o_rx_fifo_push(w_rx_fifo_push), @@ -267,6 +269,7 @@ module sd_interface ( .i_dat_write_busy(w_dat_write_busy), .i_dat_crc_error(w_dat_crc_error), .i_dat_write_error(w_dat_write_error), + .i_dat_write_ok(w_dat_write_ok), .o_rx_fifo_flush(w_rx_fifo_flush), .o_rx_fifo_pop(w_rx_fifo_regs_pop), diff --git a/fw/rtl/sd/sd_regs.v b/fw/rtl/sd/sd_regs.v index 02afded..d8a7339 100644 --- a/fw/rtl/sd/sd_regs.v +++ b/fw/rtl/sd/sd_regs.v @@ -25,6 +25,7 @@ module sd_regs ( input i_dat_write_busy, input i_dat_crc_error, input i_dat_write_error, + input i_dat_write_ok, output reg o_rx_fifo_flush, output reg o_rx_fifo_pop, @@ -204,7 +205,8 @@ module sd_regs ( SD_REG_DAT: begin o_data <= { - 4'd0, + 3'd0, + i_dat_write_ok, i_dat_write_error, i_dat_write_busy, i_tx_fifo_items, diff --git a/fw/rtl/top.v b/fw/rtl/top.v index 634c801..4860aee 100644 --- a/fw/rtl/top.v +++ b/fw/rtl/top.v @@ -539,7 +539,7 @@ module top ( // LED - wire w_led_trigger = (w_n64_request && !w_n64_busy) || (w_pc_request && !w_pc_busy); + wire w_led_trigger = (w_n64_request && !w_n64_busy) || (w_pc_request && !w_pc_busy) || (w_sd_dma_request && !w_sd_dma_busy); cart_led cart_led_inst ( .i_clk(w_sys_clk), diff --git a/sw/bootloader/src/fatfs/diskio.c b/sw/bootloader/src/fatfs/diskio.c index b4479c3..95e0805 100644 --- a/sw/bootloader/src/fatfs/diskio.c +++ b/sw/bootloader/src/fatfs/diskio.c @@ -53,7 +53,7 @@ DRESULT disk_read(BYTE pdrv, BYTE *buff, LBA_t sector, UINT count) { #if !FF_FS_READONLY -DRESULT disk_write (BYTE pdrv, const BYTE* buff, LBA_t sector, UINT count) { +DRESULT disk_write(BYTE pdrv, const BYTE* buff, LBA_t sector, UINT count) { sc64_sd_err_t error; if (pdrv > 0) { @@ -79,5 +79,15 @@ DRESULT disk_write (BYTE pdrv, const BYTE* buff, LBA_t sector, UINT count) { #endif DRESULT disk_ioctl(BYTE pdrv, BYTE cmd, void *buff) { - return RES_PARERR; + switch (cmd) { + case CTRL_SYNC: { + sc64_sd_err_t error = sc64_sd_dat_busy_wait(); + if (error != E_OK) { + return RES_ERROR; + } + break; + } + } + + return RES_OK; } diff --git a/sw/bootloader/src/loader/loader.c b/sw/bootloader/src/loader/loader.c index 91b3fbd..77e2a20 100644 --- a/sw/bootloader/src/loader/loader.c +++ b/sw/bootloader/src/loader/loader.c @@ -97,24 +97,6 @@ void loader_display_logo(void) { display_show(display); } -void loader_display_message(const char *message) { - if (!loader_initialized) { - loader_init(); - } - - display_context_t display; - - display = loader_get_display(true); - - graphics_fill_screen(display, 0); - - loader_draw_version_and_logo(display); - - graphics_draw_text(display, x_offset, y_offset, message); - - display_show(display); -} - void loader_display_error_and_halt(menu_load_error_t error, const char *message) { if (!loader_initialized) { loader_init(); diff --git a/sw/bootloader/src/loader/loader.h b/sw/bootloader/src/loader/loader.h index 9cb5e90..eafe5aa 100644 --- a/sw/bootloader/src/loader/loader.h +++ b/sw/bootloader/src/loader/loader.h @@ -7,7 +7,6 @@ void loader_cleanup(void); void loader_display_logo(void); -void loader_display_message(const char *message); void loader_display_error_and_halt(menu_load_error_t error, const char *message); diff --git a/sw/bootloader/src/sc64/sc64_regs.h b/sw/bootloader/src/sc64/sc64_regs.h index 03d7d53..06c543e 100644 --- a/sw/bootloader/src/sc64/sc64_regs.h +++ b/sw/bootloader/src/sc64/sc64_regs.h @@ -146,6 +146,9 @@ typedef struct sc64_sd_registers_s { #define SC64_SD_CMD_INDEX(i) ((i) & 0x3F) +#define SC64_SD_DAT_WRITE_OK (1 << 28) +#define SC64_SD_DAT_WRITE_ERROR (1 << 27) +#define SC64_SD_DAT_WRITE_BUSY (1 << 26) #define SC64_SD_DAT_TX_FIFO_ITEMS_GET(dat) (((dat) >> 17) & 0x1FF) #define SC64_SD_DAT_TX_FIFO_BYTES_GET(dat) (SC64_SD_DAT_TX_FIFO_ITEMS_GET(dat) * 4) #define SC64_SD_DAT_TX_FIFO_FULL (1 << 16) @@ -184,6 +187,7 @@ typedef struct sc64_sd_registers_s { #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) diff --git a/sw/bootloader/src/sc64/sc64_sd.c b/sw/bootloader/src/sc64/sc64_sd.c index 5c413d6..742feae 100644 --- a/sw/bootloader/src/sc64/sc64_sd.c +++ b/sw/bootloader/src/sc64/sc64_sd.c @@ -157,20 +157,24 @@ static sc64_sd_err_t sc64_sd_cmd_send(uint8_t index, uint32_t arg, sc64_sd_cmd_f } static void sc64_sd_dat_prepare(size_t num_blocks, size_t block_size, sc64_sd_dat_direction_t direction) { - platform_pi_io_write(&SC64_SD->DAT, ( + uint32_t reg = ( SC64_SD_DAT_NUM_BLOCKS(num_blocks) | SC64_SD_DAT_BLOCK_SIZE(block_size) | ((direction == DAT_DIR_TX) ? SC64_SD_DAT_DIRECTION : 0) | SC64_SD_DAT_START - )); + ); + + platform_pi_io_write(&SC64_SD->DAT, reg); } static void sc64_sd_dat_abort(void) { - platform_pi_io_write(&SC64_SD->DAT, ( + uint32_t reg = ( SC64_SD_DAT_TX_FIFO_FLUSH | SC64_SD_DAT_RX_FIFO_FLUSH | SC64_SD_DAT_STOP - )); + ); + + platform_pi_io_write(&SC64_SD->DAT, reg); } static sc64_sd_err_t sc64_sd_dat_read(size_t block_size, void *buffer) { @@ -212,7 +216,7 @@ static sc64_sd_err_t sc64_sd_dat_read(size_t block_size, void *buffer) { static sc64_sd_err_t sc64_sd_dat_write(size_t block_size, void *buffer) { int timeout; uint32_t reg; - + timeout = 1000000; do { reg = platform_pi_io_read(&SC64_SD->DAT); @@ -221,11 +225,21 @@ static sc64_sd_err_t sc64_sd_dat_write(size_t block_size, void *buffer) { } } while ((reg & SC64_SD_DAT_BUSY) && (--timeout)); + if (timeout == 0) { + sc64_sd_dat_abort(); + + return E_TIMEOUT; + } + if (!(reg & SC64_SD_DAT_BUSY)) { if (reg & SC64_SD_DAT_CRC_ERROR) { return E_CRC_ERROR; } + if (reg & SC64_SD_DAT_WRITE_ERROR) { + return E_WRITE_ERROR; + } + if (reg & SC64_SD_DAT_TX_FIFO_UNDERRUN) { platform_pi_io_write(&SC64_SD->DAT, SC64_SD_DAT_TX_FIFO_FLUSH); @@ -233,14 +247,8 @@ static sc64_sd_err_t sc64_sd_dat_write(size_t block_size, void *buffer) { } } - if (timeout == 0) { - sc64_sd_dat_abort(); - - return E_TIMEOUT; - } - + platform_cache_writeback(buffer, block_size); platform_pi_dma_write(buffer, &SC64_SD->FIFO, block_size); - platform_cache_invalidate(buffer, block_size); return E_OK; } @@ -420,8 +428,11 @@ sc64_sd_err_t sc64_sd_sectors_read(uint32_t starting_sector, size_t count, uint8 sc64_sd_err_t sc64_sd_sectors_write(uint32_t starting_sector, size_t count, uint8_t *buffer) { sc64_sd_err_t error; + sc64_sd_err_t write_error; uint32_t response; uint32_t current_sector; + size_t sectors_remaining; + size_t num_blocks; error = sc64_sd_sectors_parameters_check(count, buffer, true); if (error != E_OK) { @@ -433,23 +444,51 @@ sc64_sd_err_t sc64_sd_sectors_write(uint32_t starting_sector, size_t count, uint current_sector *= SD_BLOCK_SIZE; } - for (size_t i = 0; i < count; i++) { - sc64_sd_dat_prepare(1, SD_BLOCK_SIZE, DAT_DIR_TX); + sectors_remaining = count; - error = sc64_sd_cmd_send(24, current_sector, NO_FLAGS, &response); + while (sectors_remaining) { + num_blocks = (sectors_remaining > SC64_SD_DAT_NUM_BLOCKS_MAX) ? SC64_SD_DAT_NUM_BLOCKS_MAX : sectors_remaining; + + sc64_sd_dat_prepare(num_blocks, SD_BLOCK_SIZE, DAT_DIR_TX); + + error = sc64_sd_cmd_send(25, current_sector, NO_FLAGS, &response); if (error != E_OK) { sc64_sd_dat_abort(); return error; } - error = sc64_sd_dat_write(SD_BLOCK_SIZE, buffer); + for (size_t i = 0; i < num_blocks; i++) { + write_error = sc64_sd_dat_write(SD_BLOCK_SIZE, buffer); + if (write_error != E_OK) { + break; + } + + buffer += SD_BLOCK_SIZE; + } + + error = sc64_sd_dat_busy_wait(); + if (error != E_OK) { + sc64_sd_dat_abort(); + return error; + } + + error = sc64_sd_cmd_send(12, 0, NO_FLAGS, &response); if (error != E_OK) { return error; } - buffer += SD_BLOCK_SIZE; - current_sector += sd_card_type_block ? 1 : SD_BLOCK_SIZE; + error = sc64_sd_dat_busy_wait(); + if (error != E_OK) { + return error; + } + + if (write_error != E_OK) { + return write_error; + } + + current_sector += num_blocks * (sd_card_type_block ? 1 : SD_BLOCK_SIZE); + sectors_remaining -= num_blocks; } return E_OK; @@ -534,79 +573,95 @@ sc64_sd_err_t sc64_sd_sectors_read_dma(uint32_t starting_sector, size_t count, u return E_OK; } -sc64_sd_err_t sc64_sd_sectors_write_dma(uint32_t starting_sector, size_t count, uint8_t bank, uint32_t address) { - size_t sectors_left; - uint32_t current_sector; - uint32_t current_address; - uint32_t num_blocks; - uint32_t reg; - sc64_sd_err_t error; - uint32_t response; +// sc64_sd_err_t sc64_sd_sectors_write_dma(uint32_t starting_sector, size_t count, uint8_t bank, uint32_t address) { +// size_t sectors_left; +// uint32_t current_sector; +// uint32_t current_address; +// uint32_t num_blocks; +// uint32_t reg; +// sc64_sd_err_t error; +// uint32_t response; +// int timeout; + +// error = sc64_sd_sectors_parameters_check(count, NULL, false); +// if (error != E_OK) { +// return error; +// } + +// sectors_left = count; +// current_sector = starting_sector; +// if (!sd_card_type_block) { +// current_sector *= SD_BLOCK_SIZE; +// } +// current_address = address; + +// do { +// num_blocks = (sectors_left > SC64_SD_DAT_NUM_BLOCKS_MAX) ? SC64_SD_DAT_NUM_BLOCKS_MAX : sectors_left; + +// sc64_sd_dat_prepare(num_blocks, SD_BLOCK_SIZE, DAT_DIR_TX); +// sc64_sd_dma_prepare(num_blocks, SD_BLOCK_SIZE, DMA_DIR_CARD, bank, current_address); + +// error = sc64_sd_cmd_send(25, current_sector, NO_FLAGS, &response); +// if (error != E_OK) { +// sc64_sd_dma_abort(); +// sc64_sd_dat_abort(); + +// return error; +// } + +// timeout = 1000000; +// do { +// reg = platform_pi_io_read(&SC64_SD->DAT); +// } while ((reg & SC64_SD_DAT_BUSY) && (--timeout)); + +// error = sc64_sd_cmd_send(12, 0, NO_FLAGS, &response); +// if (error != E_OK) { +// sc64_sd_dma_abort(); +// sc64_sd_dat_abort(); + +// return error; +// } + +// if (reg & SC64_SD_DAT_CRC_ERROR) { +// sc64_sd_dma_abort(); + +// return E_CRC_ERROR; +// } + +// if (reg & SC64_SD_DAT_TX_FIFO_UNDERRUN) { +// sc64_sd_dma_abort(); +// platform_pi_io_write(&SC64_SD->DAT, SC64_SD_DAT_TX_FIFO_FLUSH); + +// return E_FIFO_ERROR; +// } + +// if (timeout == 0) { +// sc64_sd_dma_abort(); +// sc64_sd_dat_abort(); + +// return E_TIMEOUT; +// } + +// 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; +// } + +sc64_sd_err_t sc64_sd_dat_busy_wait(void) { int timeout; + uint32_t reg; - error = sc64_sd_sectors_parameters_check(count, NULL, false); - if (error != E_OK) { - return error; - } - - sectors_left = count; - current_sector = starting_sector; - if (!sd_card_type_block) { - current_sector *= SD_BLOCK_SIZE; - } - current_address = address; - + timeout = 1000000; do { - num_blocks = (sectors_left > SC64_SD_DAT_NUM_BLOCKS_MAX) ? SC64_SD_DAT_NUM_BLOCKS_MAX : sectors_left; + reg = platform_pi_io_read(&SC64_SD->DAT); + } while ((reg & (SC64_SD_DAT_WRITE_BUSY | SC64_SD_DAT_BUSY)) && (--timeout)); - sc64_sd_dat_prepare(num_blocks, SD_BLOCK_SIZE, DAT_DIR_TX); - sc64_sd_dma_prepare(num_blocks, SD_BLOCK_SIZE, DMA_DIR_CARD, bank, current_address); - - error = sc64_sd_cmd_send(25, current_sector, NO_FLAGS, &response); - if (error != E_OK) { - sc64_sd_dma_abort(); - sc64_sd_dat_abort(); - - return error; - } - - timeout = 1000000; - do { - reg = platform_pi_io_read(&SC64_SD->DAT); - } while ((reg & SC64_SD_DAT_BUSY) && (--timeout)); - - error = sc64_sd_cmd_send(12, 0, NO_FLAGS, &response); - if (error != E_OK) { - sc64_sd_dma_abort(); - sc64_sd_dat_abort(); - - return error; - } - - if (reg & SC64_SD_DAT_CRC_ERROR) { - sc64_sd_dma_abort(); - - return E_CRC_ERROR; - } - - if (reg & SC64_SD_DAT_TX_FIFO_UNDERRUN) { - sc64_sd_dma_abort(); - platform_pi_io_write(&SC64_SD->DAT, SC64_SD_DAT_TX_FIFO_FLUSH); - - return E_FIFO_ERROR; - } - - if (timeout == 0) { - sc64_sd_dma_abort(); - sc64_sd_dat_abort(); - - return E_TIMEOUT; - } - - 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); + if (timeout == 0) { + return E_TIMEOUT; + } return E_OK; } diff --git a/sw/bootloader/src/sc64/sc64_sd.h b/sw/bootloader/src/sc64/sc64_sd.h index ece6052..395746b 100644 --- a/sw/bootloader/src/sc64/sc64_sd.h +++ b/sw/bootloader/src/sc64/sc64_sd.h @@ -12,6 +12,7 @@ typedef enum sc64_sd_err_e { E_BAD_INDEX, E_PAR_ERROR, E_FIFO_ERROR, + E_WRITE_ERROR, E_NO_INIT, } sc64_sd_err_t; @@ -22,7 +23,8 @@ bool sc64_sd_status_get(void); sc64_sd_err_t sc64_sd_sectors_read(uint32_t starting_sector, size_t count, uint8_t *buffer); sc64_sd_err_t sc64_sd_sectors_write(uint32_t starting_sector, size_t count, uint8_t *buffer); sc64_sd_err_t sc64_sd_sectors_read_dma(uint32_t starting_sector, size_t count, uint8_t bank, uint32_t address); -sc64_sd_err_t sc64_sd_sectors_write_dma(uint32_t starting_sector, size_t count, uint8_t bank, uint32_t address); +// sc64_sd_err_t sc64_sd_sectors_write_dma(uint32_t starting_sector, size_t count, uint8_t bank, uint32_t address); +sc64_sd_err_t sc64_sd_dat_busy_wait(void); #endif diff --git a/sw/bootloader/src/sc64/sc64_sd_fs.c b/sw/bootloader/src/sc64/sc64_sd_fs.c index e4fc0e3..3a274ae 100644 --- a/sw/bootloader/src/sc64/sc64_sd_fs.c +++ b/sw/bootloader/src/sc64/sc64_sd_fs.c @@ -12,6 +12,8 @@ static uint8_t current_bank = SC64_BANK_INVALID; static uint32_t current_offset = 0; static uint8_t save_buffer[128 * 1024] __attribute__((aligned(16))); +static bool fs_initialized = false; +static FATFS fatfs; static DRESULT sc64_sd_fs_load_with_dma(BYTE pdrv, FSIZE_t offset, LBA_t sector, UINT count) { @@ -38,13 +40,9 @@ static DRESULT sc64_sd_fs_load_with_dma(BYTE pdrv, FSIZE_t offset, LBA_t sector, } -static bool fs_initialized = false; -static FATFS fatfs; - - sc64_sd_fs_error_t sc64_sd_fs_init(void) { FRESULT fresult; - + fresult = f_mount(&fatfs, "", 1); if (fresult != FR_OK) { switch (fresult) {