mirror of
https://github.com/Polprzewodnikowy/SummerCart64.git
synced 2024-11-25 15:16:53 +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;
|
||||
|
||||
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
|
||||
|
@ -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
|
||||
|
@ -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 };
|
||||
|
@ -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);
|
||||
|
@ -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");
|
||||
|
@ -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;
|
||||
|
@ -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)
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user