mirror of
https://github.com/Polprzewodnikowy/SummerCart64.git
synced 2024-11-25 23:24:15 +01:00
[SC64][FW][SW] SD card byte swap on reads support
This commit is contained in:
parent
8c7f97b433
commit
647aa5cfc9
@ -364,6 +364,7 @@ module mcu_top (
|
|||||||
logic bootloader_skip;
|
logic bootloader_skip;
|
||||||
|
|
||||||
assign n64_scb.cfg_identifier = 32'h53437632;
|
assign n64_scb.cfg_identifier = 32'h53437632;
|
||||||
|
assign usb_dma_scb.byte_swap = 1'b0;
|
||||||
|
|
||||||
logic dd_bm_ack;
|
logic dd_bm_ack;
|
||||||
|
|
||||||
@ -577,7 +578,8 @@ module mcu_top (
|
|||||||
|
|
||||||
REG_SD_DMA_SCR: begin
|
REG_SD_DMA_SCR: begin
|
||||||
reg_rdata <= {
|
reg_rdata <= {
|
||||||
28'd0,
|
27'd0,
|
||||||
|
sd_dma_scb.byte_swap,
|
||||||
sd_dma_scb.busy,
|
sd_dma_scb.busy,
|
||||||
sd_dma_scb.direction,
|
sd_dma_scb.direction,
|
||||||
2'b00
|
2'b00
|
||||||
@ -855,11 +857,10 @@ module mcu_top (
|
|||||||
end
|
end
|
||||||
|
|
||||||
REG_SD_DMA_SCR: begin
|
REG_SD_DMA_SCR: begin
|
||||||
{
|
sd_dma_scb.byte_swap <= reg_wdata[4];
|
||||||
sd_dma_scb.direction,
|
sd_dma_scb.direction <= reg_wdata[2];
|
||||||
sd_dma_scb.stop,
|
sd_dma_scb.stop <= reg_wdata[1];
|
||||||
sd_dma_scb.start
|
sd_dma_scb.start <= reg_wdata[0];
|
||||||
} <= reg_wdata[2:0];
|
|
||||||
end
|
end
|
||||||
|
|
||||||
REG_DD_SCR: begin
|
REG_DD_SCR: begin
|
||||||
|
@ -4,6 +4,7 @@ interface dma_scb ();
|
|||||||
logic stop;
|
logic stop;
|
||||||
logic busy;
|
logic busy;
|
||||||
logic direction;
|
logic direction;
|
||||||
|
logic byte_swap;
|
||||||
logic [26:0] starting_address;
|
logic [26:0] starting_address;
|
||||||
logic [26:0] transfer_length;
|
logic [26:0] transfer_length;
|
||||||
|
|
||||||
@ -12,6 +13,7 @@ interface dma_scb ();
|
|||||||
output stop,
|
output stop,
|
||||||
input busy,
|
input busy,
|
||||||
output direction,
|
output direction,
|
||||||
|
output byte_swap,
|
||||||
output starting_address,
|
output starting_address,
|
||||||
output transfer_length
|
output transfer_length
|
||||||
);
|
);
|
||||||
@ -21,6 +23,7 @@ interface dma_scb ();
|
|||||||
input stop,
|
input stop,
|
||||||
output busy,
|
output busy,
|
||||||
input direction,
|
input direction,
|
||||||
|
input byte_swap,
|
||||||
input starting_address,
|
input starting_address,
|
||||||
input transfer_length
|
input transfer_length
|
||||||
);
|
);
|
||||||
@ -209,7 +212,11 @@ module memory_dma (
|
|||||||
if (mem_bus.write) begin
|
if (mem_bus.write) begin
|
||||||
if (rx_buffer_valid) begin
|
if (rx_buffer_valid) begin
|
||||||
mem_bus.request <= 1'b1;
|
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
|
||||||
end else begin
|
end else begin
|
||||||
if (tx_buffer_ready) begin
|
if (tx_buffer_ready) begin
|
||||||
|
@ -52,6 +52,8 @@ typedef enum {
|
|||||||
SD_CARD_OP_INIT = 1,
|
SD_CARD_OP_INIT = 1,
|
||||||
SD_CARD_OP_GET_STATUS = 2,
|
SD_CARD_OP_GET_STATUS = 2,
|
||||||
SD_CARD_OP_GET_INFO = 3,
|
SD_CARD_OP_GET_INFO = 3,
|
||||||
|
SD_CARD_OP_BYTE_SWAP_ON = 4,
|
||||||
|
SD_CARD_OP_BYTE_SWAP_OFF = 5,
|
||||||
} sd_card_op_t;
|
} sd_card_op_t;
|
||||||
|
|
||||||
|
|
||||||
@ -235,6 +237,14 @@ bool sc64_sd_card_get_info (void *address) {
|
|||||||
return false;
|
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) {
|
bool sc64_sd_read_sectors (void *address, uint32_t sector, uint32_t count) {
|
||||||
uint32_t sector_set_args[2] = { sector, 0 };
|
uint32_t sector_set_args[2] = { sector, 0 };
|
||||||
uint32_t read_args[2] = { (uint32_t) (address), count };
|
uint32_t read_args[2] = { (uint32_t) (address), count };
|
||||||
|
@ -86,6 +86,7 @@ typedef enum {
|
|||||||
SD_CARD_STATUS_INITIALIZED = (1 << 1),
|
SD_CARD_STATUS_INITIALIZED = (1 << 1),
|
||||||
SD_CARD_STATUS_TYPE_BLOCK = (1 << 2),
|
SD_CARD_STATUS_TYPE_BLOCK = (1 << 2),
|
||||||
SD_CARD_STATUS_50MHZ_MODE = (1 << 3),
|
SD_CARD_STATUS_50MHZ_MODE = (1 << 3),
|
||||||
|
SD_CARD_STATUS_BYTE_SWAP = (1 << 4),
|
||||||
} sc64_sd_card_status_t;
|
} sc64_sd_card_status_t;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
@ -143,6 +144,7 @@ bool sc64_sd_card_init (void);
|
|||||||
bool sc64_sd_card_deinit (void);
|
bool sc64_sd_card_deinit (void);
|
||||||
sc64_sd_card_status_t sc64_sd_card_get_status (void);
|
sc64_sd_card_status_t sc64_sd_card_get_status (void);
|
||||||
bool sc64_sd_card_get_info (void *address);
|
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_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_sd_read_sectors (void *address, uint32_t sector, uint32_t count);
|
||||||
bool sc64_dd_set_sd_disk_info (void *address, uint32_t length);
|
bool sc64_dd_set_sd_disk_info (void *address, uint32_t length);
|
||||||
|
@ -57,6 +57,9 @@ static void test_sd_card (void) {
|
|||||||
if (card_status & SD_CARD_STATUS_50MHZ_MODE) {
|
if (card_status & SD_CARD_STATUS_50MHZ_MODE) {
|
||||||
display_printf("SD card runs at 50 MHz clock speed\n");
|
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))) {
|
if (sc64_sd_card_get_info((uint32_t *) (SC64_BUFFERS->BUFFER))) {
|
||||||
display_printf("SD card get info error!\n");
|
display_printf("SD card get info error!\n");
|
||||||
|
@ -79,6 +79,8 @@ typedef enum {
|
|||||||
SD_CARD_OP_INIT = 1,
|
SD_CARD_OP_INIT = 1,
|
||||||
SD_CARD_OP_GET_STATUS = 2,
|
SD_CARD_OP_GET_STATUS = 2,
|
||||||
SD_CARD_OP_GET_INFO = 3,
|
SD_CARD_OP_GET_INFO = 3,
|
||||||
|
SD_CARD_OP_BYTE_SWAP_ON = 4,
|
||||||
|
SD_CARD_OP_BYTE_SWAP_OFF = 5,
|
||||||
} sd_card_op_t;
|
} sd_card_op_t;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
@ -575,6 +577,18 @@ void cfg_process (void) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
break;
|
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:
|
default:
|
||||||
cfg_set_error(CFG_ERROR_BAD_ARGUMENT);
|
cfg_set_error(CFG_ERROR_BAD_ARGUMENT);
|
||||||
return;
|
return;
|
||||||
|
@ -92,6 +92,7 @@ typedef enum {
|
|||||||
#define DMA_SCR_STOP (1 << 1)
|
#define DMA_SCR_STOP (1 << 1)
|
||||||
#define DMA_SCR_DIRECTION (1 << 2)
|
#define DMA_SCR_DIRECTION (1 << 2)
|
||||||
#define DMA_SCR_BUSY (1 << 3)
|
#define DMA_SCR_BUSY (1 << 3)
|
||||||
|
#define DMA_SCR_BYTE_SWAP (1 << 4)
|
||||||
|
|
||||||
#define CFG_SCR_BOOTLOADER_ENABLED (1 << 0)
|
#define CFG_SCR_BOOTLOADER_ENABLED (1 << 0)
|
||||||
#define CFG_SCR_BOOTLOADER_SKIP (1 << 1)
|
#define CFG_SCR_BOOTLOADER_SKIP (1 << 1)
|
||||||
|
@ -7,6 +7,7 @@
|
|||||||
|
|
||||||
|
|
||||||
#define SD_INIT_BUFFER_ADDRESS (0x05002800UL)
|
#define SD_INIT_BUFFER_ADDRESS (0x05002800UL)
|
||||||
|
#define BYTE_SWAP_ADDRESS_END (0x05000000UL)
|
||||||
|
|
||||||
#define CMD6_ARG_CHECK_HS (0x00FFFFF1UL)
|
#define CMD6_ARG_CHECK_HS (0x00FFFFF1UL)
|
||||||
#define CMD6_ARG_SWITCH_HS (0x80FFFFF1UL)
|
#define CMD6_ARG_SWITCH_HS (0x80FFFFF1UL)
|
||||||
@ -67,6 +68,7 @@ struct process {
|
|||||||
uint8_t csd[16];
|
uint8_t csd[16];
|
||||||
uint8_t cid[16];
|
uint8_t cid[16];
|
||||||
volatile bool timeout;
|
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) {
|
if (mode == DAT_READ) {
|
||||||
sd_dat |= SD_DAT_START_READ;
|
sd_dat |= SD_DAT_START_READ;
|
||||||
sd_dma_scr |= DMA_SCR_DIRECTION;
|
sd_dma_scr |= DMA_SCR_DIRECTION;
|
||||||
|
if (p.byte_swap && (address < BYTE_SWAP_ADDRESS_END)) {
|
||||||
|
sd_dma_scr |= DMA_SCR_BYTE_SWAP;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
sd_dat |= SD_DAT_START_WRITE;
|
sd_dat |= SD_DAT_START_WRITE;
|
||||||
}
|
}
|
||||||
@ -217,6 +222,8 @@ bool sd_card_init (void) {
|
|||||||
uint32_t rsp;
|
uint32_t rsp;
|
||||||
uint16_t tmp;
|
uint16_t tmp;
|
||||||
|
|
||||||
|
p.byte_swap = false;
|
||||||
|
|
||||||
if (p.card_initialized) {
|
if (p.card_initialized) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -336,6 +343,7 @@ bool sd_card_init (void) {
|
|||||||
void sd_card_deinit (void) {
|
void sd_card_deinit (void) {
|
||||||
if (p.card_initialized) {
|
if (p.card_initialized) {
|
||||||
p.card_initialized = false;
|
p.card_initialized = false;
|
||||||
|
p.byte_swap = false;
|
||||||
sd_set_clock(CLOCK_400KHZ);
|
sd_set_clock(CLOCK_400KHZ);
|
||||||
sd_cmd(0, 0, RSP_NONE, NULL);
|
sd_cmd(0, 0, RSP_NONE, NULL);
|
||||||
sd_set_clock(CLOCK_STOP);
|
sd_set_clock(CLOCK_STOP);
|
||||||
@ -348,11 +356,13 @@ bool sd_card_is_inserted (void) {
|
|||||||
|
|
||||||
uint32_t sd_card_get_status (void) {
|
uint32_t sd_card_get_status (void) {
|
||||||
uint32_t scr = fpga_reg_get(REG_SD_SCR);
|
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 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_type_block = p.card_type_block ? 1 : 0;
|
||||||
uint32_t card_initialized = p.card_initialized ? 1 : 0;
|
uint32_t card_initialized = p.card_initialized ? 1 : 0;
|
||||||
uint32_t card_inserted = (scr & SD_SCR_CARD_INSERTED) ? 1 : 0;
|
uint32_t card_inserted = (scr & SD_SCR_CARD_INSERTED) ? 1 : 0;
|
||||||
return (
|
return (
|
||||||
|
(byte_swap << 4) |
|
||||||
(clock_mode_50mhz << 3) |
|
(clock_mode_50mhz << 3) |
|
||||||
(card_type_block << 2) |
|
(card_type_block << 2) |
|
||||||
(card_initialized << 1) |
|
(card_initialized << 1) |
|
||||||
@ -371,6 +381,14 @@ bool sd_card_get_info (uint32_t address) {
|
|||||||
return false;
|
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) {
|
bool sd_write_sectors (uint32_t address, uint32_t sector, uint32_t count) {
|
||||||
if (!p.card_initialized || (count == 0)) {
|
if (!p.card_initialized || (count == 0)) {
|
||||||
return true;
|
return true;
|
||||||
@ -463,11 +481,12 @@ bool sd_optimize_sectors (uint32_t address, uint32_t *sector_table, uint32_t cou
|
|||||||
|
|
||||||
void sd_init (void) {
|
void sd_init (void) {
|
||||||
p.card_initialized = false;
|
p.card_initialized = false;
|
||||||
|
p.byte_swap = false;
|
||||||
sd_set_clock(CLOCK_STOP);
|
sd_set_clock(CLOCK_STOP);
|
||||||
}
|
}
|
||||||
|
|
||||||
void sd_process (void) {
|
void sd_process (void) {
|
||||||
if (!sd_card_is_inserted()) {
|
if (p.card_initialized && !sd_card_is_inserted()) {
|
||||||
sd_card_deinit();
|
sd_card_deinit();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -17,6 +17,7 @@ void sd_card_deinit (void);
|
|||||||
bool sd_card_is_inserted (void);
|
bool sd_card_is_inserted (void);
|
||||||
uint32_t sd_card_get_status (void);
|
uint32_t sd_card_get_status (void);
|
||||||
bool sd_card_get_info (uint32_t address);
|
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_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_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);
|
bool sd_optimize_sectors (uint32_t address, uint32_t *sector_table, uint32_t count, sd_process_sectors_t sd_process_sectors);
|
||||||
|
Loading…
Reference in New Issue
Block a user