From 647aa5cfc9b3b840c738ae2397bee4f38ae61590 Mon Sep 17 00:00:00 2001 From: Mateusz Faderewski Date: Mon, 1 May 2023 16:33:25 +0200 Subject: [PATCH] [SC64][FW][SW] SD card byte swap on reads support --- fw/rtl/mcu/mcu_top.sv | 13 +++++++------ fw/rtl/memory/memory_dma.sv | 9 ++++++++- sw/bootloader/src/sc64.c | 10 ++++++++++ sw/bootloader/src/sc64.h | 2 ++ sw/bootloader/src/test.c | 3 +++ sw/controller/src/cfg.c | 14 ++++++++++++++ sw/controller/src/fpga.h | 1 + sw/controller/src/sd.c | 21 ++++++++++++++++++++- sw/controller/src/sd.h | 1 + 9 files changed, 66 insertions(+), 8 deletions(-) diff --git a/fw/rtl/mcu/mcu_top.sv b/fw/rtl/mcu/mcu_top.sv index 3b80958..e55c36c 100644 --- a/fw/rtl/mcu/mcu_top.sv +++ b/fw/rtl/mcu/mcu_top.sv @@ -364,6 +364,7 @@ module mcu_top ( logic bootloader_skip; assign n64_scb.cfg_identifier = 32'h53437632; + assign usb_dma_scb.byte_swap = 1'b0; logic dd_bm_ack; @@ -577,7 +578,8 @@ module mcu_top ( REG_SD_DMA_SCR: begin reg_rdata <= { - 28'd0, + 27'd0, + sd_dma_scb.byte_swap, sd_dma_scb.busy, sd_dma_scb.direction, 2'b00 @@ -855,11 +857,10 @@ module mcu_top ( end REG_SD_DMA_SCR: begin - { - sd_dma_scb.direction, - sd_dma_scb.stop, - sd_dma_scb.start - } <= reg_wdata[2:0]; + sd_dma_scb.byte_swap <= reg_wdata[4]; + sd_dma_scb.direction <= reg_wdata[2]; + sd_dma_scb.stop <= reg_wdata[1]; + sd_dma_scb.start <= reg_wdata[0]; end REG_DD_SCR: begin diff --git a/fw/rtl/memory/memory_dma.sv b/fw/rtl/memory/memory_dma.sv index fcba0bd..2d372c5 100644 --- a/fw/rtl/memory/memory_dma.sv +++ b/fw/rtl/memory/memory_dma.sv @@ -4,6 +4,7 @@ interface dma_scb (); logic stop; logic busy; logic direction; + logic byte_swap; logic [26:0] starting_address; logic [26:0] transfer_length; @@ -12,6 +13,7 @@ interface dma_scb (); output stop, input busy, output direction, + output byte_swap, output starting_address, output transfer_length ); @@ -21,6 +23,7 @@ interface dma_scb (); input stop, output busy, input direction, + input byte_swap, input starting_address, input transfer_length ); @@ -209,7 +212,11 @@ module memory_dma ( if (mem_bus.write) begin if (rx_buffer_valid) begin mem_bus.request <= 1'b1; - mem_bus.wdata <= rx_buffer; + if (dma_scb.byte_swap) begin + mem_bus.wdata <= {rx_buffer[7:0], rx_buffer[15:8]}; + end else begin + mem_bus.wdata <= rx_buffer; + end end end else begin if (tx_buffer_ready) begin diff --git a/sw/bootloader/src/sc64.c b/sw/bootloader/src/sc64.c index c36fab3..e8387bf 100644 --- a/sw/bootloader/src/sc64.c +++ b/sw/bootloader/src/sc64.c @@ -52,6 +52,8 @@ typedef enum { SD_CARD_OP_INIT = 1, SD_CARD_OP_GET_STATUS = 2, SD_CARD_OP_GET_INFO = 3, + SD_CARD_OP_BYTE_SWAP_ON = 4, + SD_CARD_OP_BYTE_SWAP_OFF = 5, } sd_card_op_t; @@ -235,6 +237,14 @@ bool sc64_sd_card_get_info (void *address) { return false; } +bool sc64_sd_set_byte_swap (bool enabled) { + uint32_t args[2] = { (uint32_t) (NULL), enabled ? SD_CARD_OP_BYTE_SWAP_ON : SD_CARD_OP_BYTE_SWAP_OFF }; + if (sc64_execute_cmd(SC64_CMD_SD_CARD_OP, args, NULL)) { + return true; + } + return false; +} + bool sc64_sd_read_sectors (void *address, uint32_t sector, uint32_t count) { uint32_t sector_set_args[2] = { sector, 0 }; uint32_t read_args[2] = { (uint32_t) (address), count }; diff --git a/sw/bootloader/src/sc64.h b/sw/bootloader/src/sc64.h index 030f43d..e77cff6 100644 --- a/sw/bootloader/src/sc64.h +++ b/sw/bootloader/src/sc64.h @@ -86,6 +86,7 @@ typedef enum { SD_CARD_STATUS_INITIALIZED = (1 << 1), SD_CARD_STATUS_TYPE_BLOCK = (1 << 2), SD_CARD_STATUS_50MHZ_MODE = (1 << 3), + SD_CARD_STATUS_BYTE_SWAP = (1 << 4), } sc64_sd_card_status_t; typedef struct { @@ -143,6 +144,7 @@ bool sc64_sd_card_init (void); bool sc64_sd_card_deinit (void); sc64_sd_card_status_t sc64_sd_card_get_status (void); bool sc64_sd_card_get_info (void *address); +bool sc64_sd_set_byte_swap (bool enabled); bool sc64_sd_write_sectors (void *address, uint32_t sector, uint32_t count); bool sc64_sd_read_sectors (void *address, uint32_t sector, uint32_t count); bool sc64_dd_set_sd_disk_info (void *address, uint32_t length); diff --git a/sw/bootloader/src/test.c b/sw/bootloader/src/test.c index 392c860..8aa194d 100644 --- a/sw/bootloader/src/test.c +++ b/sw/bootloader/src/test.c @@ -57,6 +57,9 @@ static void test_sd_card (void) { if (card_status & SD_CARD_STATUS_50MHZ_MODE) { display_printf("SD card runs at 50 MHz clock speed\n"); } + if (card_status & SD_CARD_STATUS_BYTE_SWAP) { + display_printf("SD card read byte swap is enabled\n"); + } if (sc64_sd_card_get_info((uint32_t *) (SC64_BUFFERS->BUFFER))) { display_printf("SD card get info error!\n"); diff --git a/sw/controller/src/cfg.c b/sw/controller/src/cfg.c index 1ff6a66..7264817 100644 --- a/sw/controller/src/cfg.c +++ b/sw/controller/src/cfg.c @@ -79,6 +79,8 @@ typedef enum { SD_CARD_OP_INIT = 1, SD_CARD_OP_GET_STATUS = 2, SD_CARD_OP_GET_INFO = 3, + SD_CARD_OP_BYTE_SWAP_ON = 4, + SD_CARD_OP_BYTE_SWAP_OFF = 5, } sd_card_op_t; typedef enum { @@ -575,6 +577,18 @@ void cfg_process (void) { return; } break; + case SD_CARD_OP_BYTE_SWAP_ON: + if (sd_set_byte_swap(true)) { + cfg_set_error(CFG_ERROR_SD_CARD); + return; + } + break; + case SD_CARD_OP_BYTE_SWAP_OFF: + if (sd_set_byte_swap(false)) { + cfg_set_error(CFG_ERROR_SD_CARD); + return; + } + break; default: cfg_set_error(CFG_ERROR_BAD_ARGUMENT); return; diff --git a/sw/controller/src/fpga.h b/sw/controller/src/fpga.h index 84521a5..69e9b5e 100644 --- a/sw/controller/src/fpga.h +++ b/sw/controller/src/fpga.h @@ -92,6 +92,7 @@ typedef enum { #define DMA_SCR_STOP (1 << 1) #define DMA_SCR_DIRECTION (1 << 2) #define DMA_SCR_BUSY (1 << 3) +#define DMA_SCR_BYTE_SWAP (1 << 4) #define CFG_SCR_BOOTLOADER_ENABLED (1 << 0) #define CFG_SCR_BOOTLOADER_SKIP (1 << 1) diff --git a/sw/controller/src/sd.c b/sw/controller/src/sd.c index f25df99..3a2f516 100644 --- a/sw/controller/src/sd.c +++ b/sw/controller/src/sd.c @@ -7,6 +7,7 @@ #define SD_INIT_BUFFER_ADDRESS (0x05002800UL) +#define BYTE_SWAP_ADDRESS_END (0x05000000UL) #define CMD6_ARG_CHECK_HS (0x00FFFFF1UL) #define CMD6_ARG_SWITCH_HS (0x80FFFFF1UL) @@ -67,6 +68,7 @@ struct process { uint8_t csd[16]; uint8_t cid[16]; volatile bool timeout; + bool byte_swap; }; @@ -178,6 +180,9 @@ static void sd_dat_prepare (uint32_t address, uint32_t count, dat_mode_t mode) { if (mode == DAT_READ) { sd_dat |= SD_DAT_START_READ; sd_dma_scr |= DMA_SCR_DIRECTION; + if (p.byte_swap && (address < BYTE_SWAP_ADDRESS_END)) { + sd_dma_scr |= DMA_SCR_BYTE_SWAP; + } } else { sd_dat |= SD_DAT_START_WRITE; } @@ -217,6 +222,8 @@ bool sd_card_init (void) { uint32_t rsp; uint16_t tmp; + p.byte_swap = false; + if (p.card_initialized) { return false; } @@ -336,6 +343,7 @@ bool sd_card_init (void) { void sd_card_deinit (void) { if (p.card_initialized) { p.card_initialized = false; + p.byte_swap = false; sd_set_clock(CLOCK_400KHZ); sd_cmd(0, 0, RSP_NONE, NULL); sd_set_clock(CLOCK_STOP); @@ -348,11 +356,13 @@ bool sd_card_is_inserted (void) { uint32_t sd_card_get_status (void) { uint32_t scr = fpga_reg_get(REG_SD_SCR); + uint32_t byte_swap = p.byte_swap ? 1 : 0; uint32_t clock_mode_50mhz = ((scr & SD_SCR_CLOCK_MODE_MASK) == SD_SCR_CLOCK_MODE_50MHZ) ? 1 : 0; uint32_t card_type_block = p.card_type_block ? 1 : 0; uint32_t card_initialized = p.card_initialized ? 1 : 0; uint32_t card_inserted = (scr & SD_SCR_CARD_INSERTED) ? 1 : 0; return ( + (byte_swap << 4) | (clock_mode_50mhz << 3) | (card_type_block << 2) | (card_initialized << 1) | @@ -371,6 +381,14 @@ bool sd_card_get_info (uint32_t address) { return false; } +bool sd_set_byte_swap (bool enabled) { + if (!p.card_initialized) { + return true; + } + p.byte_swap = enabled; + return false; +} + bool sd_write_sectors (uint32_t address, uint32_t sector, uint32_t count) { if (!p.card_initialized || (count == 0)) { return true; @@ -463,11 +481,12 @@ bool sd_optimize_sectors (uint32_t address, uint32_t *sector_table, uint32_t cou void sd_init (void) { p.card_initialized = false; + p.byte_swap = false; sd_set_clock(CLOCK_STOP); } void sd_process (void) { - if (!sd_card_is_inserted()) { + if (p.card_initialized && !sd_card_is_inserted()) { sd_card_deinit(); } } diff --git a/sw/controller/src/sd.h b/sw/controller/src/sd.h index 690905b..9094df4 100644 --- a/sw/controller/src/sd.h +++ b/sw/controller/src/sd.h @@ -17,6 +17,7 @@ void sd_card_deinit (void); bool sd_card_is_inserted (void); uint32_t sd_card_get_status (void); bool sd_card_get_info (uint32_t address); +bool sd_set_byte_swap (bool enabled); bool sd_write_sectors (uint32_t address, uint32_t sector, uint32_t count); bool sd_read_sectors (uint32_t address, uint32_t sector, uint32_t count); bool sd_optimize_sectors (uint32_t address, uint32_t *sector_table, uint32_t count, sd_process_sectors_t sd_process_sectors);