dd basics

This commit is contained in:
Polprzewodnikowy 2022-07-22 12:43:53 +02:00
parent 4812b0d59d
commit 47633e3f36
10 changed files with 519 additions and 251 deletions

View File

@ -2,11 +2,12 @@ module mcu_top (
input clk, input clk,
input reset, input reset,
n64_scb.controller n64_scb,
dd_scb.controller dd_scb,
usb_scb.controller usb_scb, usb_scb.controller usb_scb,
dma_scb.controller usb_dma_scb, dma_scb.controller usb_dma_scb,
sd_scb.controller sd_scb, sd_scb.controller sd_scb,
dma_scb.controller sd_dma_scb, dma_scb.controller sd_dma_scb,
n64_scb.controller n64_scb,
flash_scb.controller flash_scb, flash_scb.controller flash_scb,
fifo_bus.controller fifo_bus, fifo_bus.controller fifo_bus,
@ -347,13 +348,20 @@ module mcu_top (
REG_SD_DAT, REG_SD_DAT,
REG_SD_DMA_ADDRESS, REG_SD_DMA_ADDRESS,
REG_SD_DMA_LENGTH, REG_SD_DMA_LENGTH,
REG_SD_DMA_SCR REG_SD_DMA_SCR,
REG_DD_SCR,
REG_DD_CMD_DATA,
REG_DD_HEAD_TRACK,
REG_DD_SECTOR_INFO,
REG_DD_DRIVE_ID
} reg_address_e; } reg_address_e;
logic bootloader_skip; logic bootloader_skip;
assign n64_scb.cfg_version = 32'h53437632; assign n64_scb.cfg_version = 32'h53437632;
logic dd_bm_ack;
// Register read logic // Register read logic
@ -529,6 +537,47 @@ module mcu_top (
2'b00 2'b00
}; };
end end
REG_DD_SCR: begin
reg_rdata <= {
14'd0,
dd_bm_ack,
dd_scb.bm_micro_error,
dd_scb.bm_transfer_c2,
dd_scb.bm_transfer_data,
dd_scb.bm_transfer_blocks,
dd_scb.bm_transfer_mode,
1'b0,
dd_scb.bm_stop_pending,
1'b0,
dd_scb.bm_start_pending,
dd_scb.disk_changed,
dd_scb.disk_inserted,
1'b0,
dd_scb.bm_pending,
1'b0,
dd_scb.cmd_pending,
1'b0,
dd_scb.hard_reset
};
end
REG_DD_CMD_DATA: begin
reg_rdata <= {8'd0, dd_scb.cmd, dd_scb.data};
end
REG_DD_HEAD_TRACK: begin
reg_rdata <= {18'd0, dd_scb.index_lock, dd_scb.head_track};
end
REG_DD_SECTOR_INFO: begin
reg_rdata <= {
dd_scb.sectors_in_block,
dd_scb.sector_size_full,
dd_scb.sector_size,
dd_scb.sector_num
};
end
endcase endcase
end end
end end
@ -559,6 +608,13 @@ module mcu_top (
n64_scb.rtc_done <= 1'b0; n64_scb.rtc_done <= 1'b0;
dd_scb.hard_reset_clear <= 1'b0;
dd_scb.cmd_ready <= 1'b0;
dd_scb.bm_start_clear <= 1'b0;
dd_scb.bm_stop_clear <= 1'b0;
dd_scb.bm_clear <= 1'b0;
dd_scb.bm_ready <= 1'b0;
if (n64_scb.n64_nmi) begin if (n64_scb.n64_nmi) begin
n64_scb.bootloader_enabled <= !bootloader_skip; n64_scb.bootloader_enabled <= !bootloader_skip;
end end
@ -567,6 +623,10 @@ module mcu_top (
flash_scb.erase_pending <= 1'b0; flash_scb.erase_pending <= 1'b0;
end end
if (dd_scb.bm_interrupt_ack) begin
dd_bm_ack <= 1'b1;
end
if (reset) begin if (reset) begin
mcu_int <= 1'b0; mcu_int <= 1'b0;
sd_scb.clock_mode <= 2'd0; sd_scb.clock_mode <= 2'd0;
@ -582,6 +642,7 @@ module mcu_top (
bootloader_skip <= 1'b0; bootloader_skip <= 1'b0;
n64_scb.bootloader_enabled <= 1'b1; n64_scb.bootloader_enabled <= 1'b1;
flash_scb.erase_pending <= 1'b0; flash_scb.erase_pending <= 1'b0;
dd_bm_ack <= 1'b0;
end else if (reg_write) begin end else if (reg_write) begin
case (address) case (address)
REG_STATUS: begin end REG_STATUS: begin end
@ -701,6 +762,35 @@ module mcu_top (
sd_dma_scb.start sd_dma_scb.start
} <= reg_wdata[2:0]; } <= reg_wdata[2:0];
end end
REG_DD_SCR: begin
dd_scb.bm_clear <= reg_wdata[19];
if (reg_wdata[18]) begin
dd_bm_ack <= 1'b0;
end
dd_scb.bm_micro_error <= reg_wdata[16];
dd_scb.bm_transfer_c2 <= reg_wdata[15];
dd_scb.bm_transfer_data <= reg_wdata[14];
dd_scb.bm_stop_clear <= reg_wdata[11];
dd_scb.bm_start_clear <= reg_wdata[9];
dd_scb.disk_changed <= reg_wdata[7];
dd_scb.disk_inserted <= reg_wdata[6];
dd_scb.bm_ready <= reg_wdata[5];
dd_scb.cmd_ready <= reg_wdata[3];
dd_scb.hard_reset_clear <= reg_wdata[1];
end
REG_DD_CMD_DATA: begin
dd_scb.cmd_data <= reg_wdata[15:0];
end
REG_DD_HEAD_TRACK: begin
{dd_scb.index_lock, dd_scb.head_track} <= reg_wdata[13:0];
end
REG_DD_DRIVE_ID: begin
dd_scb.drive_id <= reg_wdata[15:0];
end
endcase endcase
end end
end end

View File

@ -1,3 +1,114 @@
interface dd_scb ();
// N64 controlled regs
logic hard_reset;
logic [15:0] data;
logic [7:0] cmd;
logic cmd_pending;
logic cmd_interrupt;
logic bm_start_pending;
logic bm_stop_pending;
logic bm_transfer_mode;
logic bm_transfer_blocks;
logic bm_pending;
logic bm_interrupt;
logic bm_interrupt_ack;
logic [7:0] sector_num;
logic [7:0] sector_size;
logic [7:0] sector_size_full;
logic [7:0] sectors_in_block;
// CPU controlled regs
logic hard_reset_clear;
logic [15:0] cmd_data;
logic cmd_ready;
logic bm_start_clear;
logic bm_stop_clear;
logic bm_transfer_c2;
logic bm_transfer_data;
logic bm_micro_error;
logic bm_clear;
logic bm_ready;
logic disk_inserted;
logic disk_changed;
logic index_lock;
logic [12:0] head_track;
logic [15:0] drive_id;
modport controller (
input hard_reset,
input data,
input cmd,
input cmd_pending,
input bm_start_pending,
input bm_stop_pending,
input bm_transfer_mode,
input bm_transfer_blocks,
input bm_pending,
input bm_interrupt_ack,
input sector_num,
input sector_size,
input sector_size_full,
input sectors_in_block,
output hard_reset_clear,
output cmd_data,
output cmd_ready,
output bm_start_clear,
output bm_stop_clear,
output bm_transfer_c2,
output bm_transfer_data,
output bm_micro_error,
output bm_ready,
output bm_clear,
output disk_inserted,
output disk_changed,
output index_lock,
output head_track,
output drive_id
);
modport dd (
output hard_reset,
output data,
output cmd,
output cmd_pending,
output cmd_interrupt,
output bm_start_pending,
output bm_stop_pending,
output bm_transfer_mode,
output bm_transfer_blocks,
output bm_pending,
output bm_interrupt,
output bm_interrupt_ack,
output sector_num,
output sector_size,
output sector_size_full,
output sectors_in_block,
input hard_reset_clear,
input cmd_data,
input cmd_ready,
input bm_start_clear,
input bm_stop_clear,
input bm_transfer_c2,
input bm_transfer_data,
input bm_micro_error,
input bm_clear,
input bm_ready,
input disk_inserted,
input disk_changed,
input index_lock,
input head_track,
input drive_id
);
endinterface
module n64_dd ( module n64_dd (
input clk, input clk,
input reset, input reset,
@ -5,232 +116,171 @@ module n64_dd (
n64_reg_bus.dd reg_bus, n64_reg_bus.dd reg_bus,
n64_scb.dd n64_scb, n64_scb.dd n64_scb,
dd_scb.dd dd_scb,
output logic irq output logic irq
); );
assign irq = 1'b0; const bit [10:0] MEM_C2_BUFFER = 11'h000;
const bit [10:0] MEM_SECTOR_BUFFER = 11'h400;
// const bit [10:0] M_C2_BUFFER = 11'h000; typedef enum bit [10:0] {
// const bit [10:0] M_SECTOR_BUFFER = 11'h400; REG_DATA = 11'h500,
REG_CMD_SR = 11'h508,
REG_TRK_CUR = 11'h50C,
REG_BM_SCR = 11'h510,
REG_RESET = 11'h520,
REG_SEC_SIZ = 11'h528,
REG_SEC_INFO = 11'h530,
REG_ID = 11'h540
} e_reg_id;
// typedef enum bit [10:0] { typedef enum bit [3:0] {
// R_DATA = 11'h500, BM_CONTROL_START_BUFFER_MANAGER = 4'd15,
// R_CMD_SR = 11'h508, BM_CONTROL_BUFFER_MANAGER_MODE = 4'd14,
// R_TRK_CUR = 11'h50C, BM_CONTROL_BUFFER_MANAGER_RESET = 4'd12,
// R_BM_SCR = 11'h510, BM_CONTROL_BLOCK_TRANSFER = 4'd9,
// R_RESET = 11'h520, BM_CONTROL_MECHANIC_INTERRUPT_RESET = 4'd8
// R_SEC_SIZ = 11'h528, } e_bm_control_id;
// R_SEC_INFO = 11'h530,
// R_ID = 11'h540
// } e_reg_id;
// typedef enum bit [3:0] { always_comb begin
// BM_CONTROL_START_BUFFER_MANAGER = 4'd15, reg_bus.rdata = 16'd0;
// BM_CONTROL_BUFFER_MANAGER_MODE = 4'd14, if (reg_bus.address[10:8] == MEM_SECTOR_BUFFER[10:8]) begin
// BM_CONTROL_BUFFER_MANAGER_RESET = 4'd12, reg_bus.rdata = n64_scb.dd_rdata;
// BM_CONTROL_BLOCK_TRANSFER = 4'd9, end else begin
// BM_CONTROL_MECHANIC_INTERRUPT_RESET = 4'd8 case (reg_bus.address[10:0])
// } e_bm_control_id; REG_DATA: reg_bus.rdata = dd_scb.data;
REG_CMD_SR: reg_bus.rdata = {
1'b0,
dd_scb.bm_transfer_data,
1'b0,
dd_scb.bm_transfer_c2,
1'b0,
dd_scb.bm_interrupt,
dd_scb.cmd_interrupt,
dd_scb.disk_inserted,
dd_scb.cmd_pending,
dd_scb.hard_reset,
1'b0,
1'b0,
1'b0,
1'b0,
1'b0,
dd_scb.disk_changed
};
REG_TRK_CUR: reg_bus.rdata = {1'd0, {2{dd_scb.index_lock}}, dd_scb.head_track};
REG_BM_SCR: reg_bus.rdata = {6'd0, dd_scb.bm_micro_error, 9'd0};
REG_ID: reg_bus.rdata = dd_scb.drive_id;
endcase
end
end
// // typedef enum bit [0:0] { always_ff @(posedge clk) begin
// // S_IDLE, dd_scb.bm_interrupt_ack <= 1'b0;
// // S_WAIT
// // } e_state;
// // e_state state; if (dd_scb.hard_reset_clear) begin
dd_scb.hard_reset <= 1'b0;
end
if (dd_scb.cmd_ready) begin
dd_scb.data <= dd_scb.cmd_data;
dd_scb.cmd_pending <= 1'b0;
dd_scb.cmd_interrupt <= 1'b1;
end
if (dd_scb.bm_start_clear) begin
dd_scb.bm_start_pending <= 1'b0;
end
if (dd_scb.bm_stop_clear) begin
dd_scb.bm_stop_pending <= 1'b0;
end
if (dd_scb.bm_clear) begin
dd_scb.bm_pending <= 1'b0;
end
if (dd_scb.bm_ready) begin
dd_scb.bm_interrupt <= 1'b1;
end
if (reg_bus.address[10:0] == (MEM_C2_BUFFER + ({dd_scb.sector_size[7:1], 1'b0} * 3'd4)) && reg_bus.read) begin
dd_scb.bm_pending <= 1'b1;
end
if (reg_bus.address[10:0] == (MEM_SECTOR_BUFFER + {dd_scb.sector_size[7:1], 1'b0}) && (reg_bus.read || reg_bus.write)) begin
dd_scb.bm_pending <= 1'b1;
end
if (reg_bus.address[10:0] == REG_CMD_SR && reg_bus.read) begin
dd_scb.bm_interrupt <= 1'b0;
dd_scb.bm_interrupt_ack <= 1'b1;
end
// // always_comb begin if (reset || n64_scb.n64_reset) begin
// // dd.sector_address = bus.address[7:1]; dd_scb.hard_reset <= 1'b1;
// // dd.sector_address_valid = bus.request && bus.address[11:8] == M_SECTOR_BUFFER[11:8]; dd_scb.cmd_pending <= 1'b0;
// // dd.sector_write = bus.write && dd.sector_address_valid; dd_scb.cmd_interrupt <= 1'b0;
// // dd.sector_wdata = bus.wdata; dd_scb.bm_start_pending <= 1'b0;
// // end dd_scb.bm_stop_pending <= 1'b0;
dd_scb.bm_pending <= 1'b0;
dd_scb.bm_interrupt <= 1'b0;
end else if (reg_bus.write) begin
case (reg_bus.address[10:0])
REG_DATA: begin
dd_scb.data <= reg_bus.wdata;
end
// always_comb begin REG_CMD_SR: begin
// bus.rdata = 16'd0; dd_scb.cmd <= reg_bus.wdata[7:0];
// if (bus.ack) begin dd_scb.cmd_pending <= 1'b1;
// if (bus.address[10:8] == M_SECTOR_BUFFER[10:8]) begin end
// if (bus.address[1]) begin
// bus.rdata = dd.sector_rdata[15:0];
// end else begin
// bus.rdata = dd.sector_rdata[31:16];
// end
// end else begin
// case (bus.address[10:0])
// R_DATA: bus.rdata = dd.data;
// R_CMD_SR: bus.rdata = {
// 1'b0,
// dd.bm_transfer_data,
// 1'b0,
// dd.bm_transfer_c2,
// 1'b0,
// dd.bm_interrupt,
// dd.cmd_interrupt,
// dd.disk_inserted,
// dd.cmd_pending,
// dd.hard_reset,
// 1'b0,
// 1'b0,
// 1'b0,
// 1'b0,
// 1'b0,
// dd.disk_changed
// };
// R_TRK_CUR: bus.rdata = {1'd0, {2{dd.index_lock}}, dd.head_track};
// R_BM_SCR: bus.rdata = {6'd0, dd.bm_micro_error, 9'd0};
// R_ID: bus.rdata = {dd.drive_id};
// default: bus.rdata = 16'd0;
// endcase
// end
// end
// end
// always_comb begin REG_BM_SCR: begin
// reg_bus.rdata = 16'd0; dd_scb.sector_num <= reg_bus.wdata[7:0];
// if (reg_bus.address[10:8] == M_SECTOR_BUFFER[10:8]) begin if (reg_bus.wdata[BM_CONTROL_START_BUFFER_MANAGER]) begin
// end else begin dd_scb.bm_start_pending <= 1'b1;
// case (reg_bus.address[10:0]) dd_scb.bm_stop_pending <= 1'b0;
// R_DATA: reg_bus.rdata = dd.data; dd_scb.bm_transfer_mode <= reg_bus.wdata[BM_CONTROL_BUFFER_MANAGER_MODE];
// R_CMD_SR: reg_bus.rdata = { dd_scb.bm_transfer_blocks <= reg_bus.wdata[BM_CONTROL_BLOCK_TRANSFER];
// 1'b0, end
// dd.bm_transfer_data, if (reg_bus.wdata[BM_CONTROL_BUFFER_MANAGER_RESET]) begin
// 1'b0, dd_scb.bm_start_pending <= 1'b0;
// dd.bm_transfer_c2, dd_scb.bm_stop_pending <= 1'b1;
// 1'b0, dd_scb.bm_transfer_mode <= 1'b0;
// dd.bm_interrupt, dd_scb.bm_transfer_blocks <= 1'b0;
// dd.cmd_interrupt, dd_scb.bm_pending <= 1'b0;
// dd.disk_inserted, dd_scb.bm_interrupt <= 1'b0;
// dd.cmd_pending, end
// dd.hard_reset, if (reg_bus.wdata[BM_CONTROL_MECHANIC_INTERRUPT_RESET]) begin
// 1'b0, dd_scb.cmd_interrupt <= 1'b0;
// 1'b0, end
// 1'b0, end
// 1'b0,
// 1'b0,
// dd.disk_changed
// };
// R_TRK_CUR: reg_bus.rdata = {1'd0, {2{dd.index_lock}}, dd.head_track};
// R_BM_SCR: reg_bus.rdata = {6'd0, dd.bm_micro_error, 9'd0};
// R_ID: reg_bus.rdata = {dd.drive_id};
// default: reg_bus.rdata = 16'd0;
// endcase
// end
// end
// always_ff @(posedge sys.clk) begin REG_RESET: begin
// bus.ack <= 1'b0; if (reg_bus.wdata == 16'hAAAA) begin
// dd.bm_interrupt_ack <= 1'b0; dd_scb.hard_reset <= 1'b1;
dd_scb.cmd_pending <= 1'b0;
dd_scb.cmd_interrupt <= 1'b0;
dd_scb.bm_start_pending <= 1'b0;
dd_scb.bm_stop_pending <= 1'b0;
dd_scb.bm_pending <= 1'b0;
dd_scb.bm_interrupt <= 1'b0;
end
end
// if (dd.hard_reset_clear) begin REG_SEC_SIZ: begin
// dd.hard_reset <= 1'b0; dd_scb.sector_size <= reg_bus.wdata[7:0];
// end end
// if (dd.cmd_ready) begin
// dd.data <= dd.cmd_data;
// dd.cmd_pending <= 1'b0;
// dd.cmd_interrupt <= 1'b1;
// end
// if (dd.bm_start_clear) begin
// dd.bm_start_pending <= 1'b0;
// end
// if (dd.bm_stop_clear) begin
// dd.bm_stop_pending <= 1'b0;
// end
// if (dd.bm_clear) begin
// dd.bm_pending <= 1'b0;
// end
// if (dd.bm_ready) begin
// dd.bm_interrupt <= 1'b1;
// end
// if (bus.real_address == (M_C2_BUFFER + ({dd.sector_size[7:1], 1'b0} * 3'd4)) && bus.read_op) begin
// dd.bm_pending <= 1'b1;
// end
// if (bus.real_address == (M_SECTOR_BUFFER + {dd.sector_size[7:1], 1'b0}) && (bus.read_op || bus.write_op)) begin
// dd.bm_pending <= 1'b1;
// end
// if (bus.real_address == (M_BASE + R_CMD_SR) && bus.read_op) begin
// dd.bm_interrupt <= 1'b0;
// dd.bm_interrupt_ack <= 1'b1;
// end
// if (sys.reset || sys.n64_hard_reset) begin REG_SEC_INFO: begin
// dd.hard_reset <= 1'b1; dd_scb.sectors_in_block <= reg_bus.wdata[15:8];
// dd.cmd_pending <= 1'b0; dd_scb.sector_size_full <= reg_bus.wdata[7:0];
// dd.cmd_interrupt <= 1'b0; end
// dd.bm_start_pending <= 1'b0; endcase
// dd.bm_stop_pending <= 1'b0; end
// dd.bm_pending <= 1'b0; end
// dd.bm_interrupt <= 1'b0;
// state <= S_IDLE;
// end else begin
// case (state)
// S_IDLE: begin
// if (bus.request) begin
// state <= S_WAIT;
// bus.ack <= 1'b1;
// if (bus.write) begin
// case (bus.address[10:0])
// R_DATA: begin
// dd.data <= bus.wdata;
// end
// R_CMD_SR: begin always_comb begin
// dd.cmd <= bus.wdata[7:0]; irq = dd_scb.cmd_interrupt || dd_scb.bm_interrupt;
// dd.cmd_pending <= 1'b1; end
// end
// R_BM_SCR: begin
// dd.sector_num <= bus.wdata[7:0];
// if (bus.wdata[BM_CONTROL_START_BUFFER_MANAGER]) begin
// dd.bm_start_pending <= 1'b1;
// dd.bm_stop_pending <= 1'b0;
// dd.bm_transfer_mode <= bus.wdata[BM_CONTROL_BUFFER_MANAGER_MODE];
// dd.bm_transfer_blocks <= bus.wdata[BM_CONTROL_BLOCK_TRANSFER];
// end
// if (bus.wdata[BM_CONTROL_BUFFER_MANAGER_RESET]) begin
// dd.bm_start_pending <= 1'b0;
// dd.bm_stop_pending <= 1'b1;
// dd.bm_transfer_mode <= 1'b0;
// dd.bm_transfer_blocks <= 1'b0;
// dd.bm_pending <= 1'b0;
// dd.bm_interrupt <= 1'b0;
// end
// if (bus.wdata[BM_CONTROL_MECHANIC_INTERRUPT_RESET]) begin
// dd.cmd_interrupt <= 1'b0;
// end
// end
// R_RESET: begin
// if (bus.wdata == 16'hAAAA) begin
// dd.hard_reset <= 1'b1;
// dd.cmd_pending <= 1'b0;
// dd.cmd_interrupt <= 1'b0;
// dd.bm_start_pending <= 1'b0;
// dd.bm_stop_pending <= 1'b0;
// dd.bm_pending <= 1'b0;
// dd.bm_interrupt <= 1'b0;
// end
// end
// R_SEC_SIZ: begin
// dd.sector_size <= bus.wdata[7:0];
// end
// R_SEC_INFO: begin
// dd.sectors_in_block <= bus.wdata[15:8];
// dd.sector_size_full <= bus.wdata[7:0];
// end
// endcase
// end
// end
// end
// S_WAIT: begin
// state <= S_IDLE;
// end
// endcase
// end
// end
always_comb begin
n64_scb.dd_write = reg_bus.write && reg_bus.address[10:8] == MEM_SECTOR_BUFFER[10:8];
n64_scb.dd_address = {2'b00, reg_bus.address[7:1]};
n64_scb.dd_wdata = reg_bus.wdata;
end
endmodule endmodule

View File

@ -2,9 +2,10 @@ module n64_top (
input clk, input clk,
input reset, input reset,
mem_bus.controller mem_bus,
n64_scb n64_scb, n64_scb n64_scb,
dd_scb.dd dd_scb,
mem_bus.controller mem_bus,
input n64_reset, input n64_reset,
input n64_nmi, input n64_nmi,
@ -52,6 +53,7 @@ module n64_top (
.reg_bus(reg_bus), .reg_bus(reg_bus),
.n64_scb(n64_scb), .n64_scb(n64_scb),
.dd_scb(dd_scb),
.irq(n64_dd_irq) .irq(n64_dd_irq)
); );

View File

@ -52,6 +52,7 @@ module top (
logic reset; logic reset;
n64_scb n64_scb (); n64_scb n64_scb ();
dd_scb dd_scb ();
usb_scb usb_scb (); usb_scb usb_scb ();
dma_scb usb_dma_scb (); dma_scb usb_dma_scb ();
sd_scb sd_scb (); sd_scb sd_scb ();
@ -86,6 +87,7 @@ module top (
.reset(reset), .reset(reset),
.n64_scb(n64_scb), .n64_scb(n64_scb),
.dd_scb(dd_scb),
.usb_scb(usb_scb), .usb_scb(usb_scb),
.usb_dma_scb(usb_dma_scb), .usb_dma_scb(usb_dma_scb),
.sd_scb(sd_scb), .sd_scb(sd_scb),
@ -113,6 +115,7 @@ module top (
.reset(reset), .reset(reset),
.n64_scb(n64_scb), .n64_scb(n64_scb),
.dd_scb(dd_scb),
.mem_bus(n64_mem_bus), .mem_bus(n64_mem_bus),

View File

@ -16,6 +16,7 @@ SRC_FILES = \
startup.S \ startup.S \
cfg.c \ cfg.c \
cic.c \ cic.c \
dd.c \
flash.c \ flash.c \
flashram.c \ flashram.c \
fpga.c \ fpga.c \

View File

@ -141,7 +141,7 @@ void cfg_update (uint32_t *args) {
change_scr_bits(CFG_SCR_ROM_SHADOW_ENABLED, args[1]); change_scr_bits(CFG_SCR_ROM_SHADOW_ENABLED, args[1]);
break; break;
case CFG_ID_DD_ENABLE: case CFG_ID_DD_ENABLE:
change_scr_bits(CFG_SCR_DD_ENABLED, args[1]); change_scr_bits(CFG_SCR_DD_ENABLED | CFG_SCR_DDIPL_ENABLED, args[1]);
break; break;
case CFG_ID_ISV_ENABLE: case CFG_ID_ISV_ENABLE:
break; break;

115
sw/controller/src/dd.c Normal file
View File

@ -0,0 +1,115 @@
#include <stdbool.h>
#include <stdint.h>
#include "fpga.h"
#include "rtc.h"
#define DD_DRIVE_ID_RETAIL (0x0003)
#define DD_DRIVE_ID_DEVELOPMENT (0x0004)
#define DD_VERSION_RETAIL (0x0114)
typedef enum {
DD_CMD_SEEK_READ = 0x01,
DD_CMD_SEEK_WRITE = 0x02,
DD_CMD_CLEAR_DISK_CHANGE = 0x08,
DD_CMD_CLEAR_RESET_STATE = 0x09,
DD_CMD_READ_VERSION = 0x0A,
DD_CMD_SET_DISK_TYPE = 0x0B,
DD_CMD_REQUEST_STATUS = 0x0C,
DD_CMD_SET_RTC_YEAR_MONTH = 0x0F,
DD_CMD_SET_RTC_DAY_HOUR = 0x10,
DD_CMD_SET_RTC_MINUTE_SECOND = 0x11,
DD_CMD_GET_RTC_YEAR_MONTH = 0x12,
DD_CMD_GET_RTC_DAY_HOUR = 0x13,
DD_CMD_GET_RTC_MINUTE_SECOND = 0x14,
DD_CMD_READ_PROGRAM_VERSION = 0x1B,
} dd_cmd_t;
static rtc_time_t time;
void dd_init (void) {
fpga_reg_set(REG_DD_SCR, 0);
fpga_reg_set(REG_DD_HEAD_TRACK, 0);
fpga_reg_set(REG_DD_DRIVE_ID, DD_DRIVE_ID_RETAIL);
}
void dd_process (void) {
uint32_t scr = fpga_reg_get(REG_DD_SCR);
if (scr & DD_SCR_HARD_RESET) {
fpga_reg_set(REG_DD_SCR, scr & ~(DD_SCR_DISK_CHANGED));
fpga_reg_set(REG_DD_HEAD_TRACK, 0);
}
if (scr & DD_SCR_CMD_PENDING) {
uint32_t cmd_data = fpga_reg_get(REG_DD_CMD_DATA);
uint8_t cmd = (cmd_data >> 16) & 0xFF;
uint16_t data = cmd_data & 0xFFFF;
fpga_reg_set(REG_DD_CMD_DATA, data);
switch (cmd) {
case DD_CMD_CLEAR_DISK_CHANGE:
fpga_reg_set(REG_DD_SCR, scr & ~(DD_SCR_DISK_CHANGED));
break;
case DD_CMD_CLEAR_RESET_STATE:
fpga_reg_set(REG_DD_SCR, scr & ~(DD_SCR_DISK_CHANGED));
fpga_reg_set(REG_DD_SCR, scr | DD_SCR_HARD_RESET_CLEAR);
break;
case DD_CMD_READ_VERSION:
fpga_reg_set(REG_DD_CMD_DATA, DD_VERSION_RETAIL);
break;
case DD_CMD_SET_DISK_TYPE:
break;
case DD_CMD_REQUEST_STATUS:
fpga_reg_set(REG_DD_CMD_DATA, 0);
break;
case DD_CMD_SET_RTC_YEAR_MONTH:
time.year = ((data >> 8) & 0xFF);
time.month = (data & 0xFF);
break;
case DD_CMD_SET_RTC_DAY_HOUR:
time.day = ((data >> 8) & 0xFF);
time.hour = (data & 0xFF);
break;
case DD_CMD_SET_RTC_MINUTE_SECOND:
time.minute = ((data >> 8) & 0xFF);
time.second = (data & 0xFF);
rtc_set_time(&time);
break;
case DD_CMD_GET_RTC_YEAR_MONTH:
fpga_reg_set(REG_DD_CMD_DATA, (time.year << 8) | time.month);
break;
case DD_CMD_GET_RTC_DAY_HOUR:
fpga_reg_set(REG_DD_CMD_DATA, (time.day << 8) | time.hour);
break;
case DD_CMD_GET_RTC_MINUTE_SECOND:
rtc_get_time(&time);
fpga_reg_set(REG_DD_CMD_DATA, (time.minute << 8) | time.second);
break;
case DD_CMD_READ_PROGRAM_VERSION:
fpga_reg_set(REG_DD_CMD_DATA, 0);
break;
default:
break;
}
fpga_reg_set(REG_DD_SCR, scr | DD_SCR_CMD_READY);
}
}

9
sw/controller/src/dd.h Normal file
View File

@ -0,0 +1,9 @@
#ifndef DD_H__
#define DD_H__
void dd_init (void);
void dd_process (void);
#endif

View File

@ -46,6 +46,11 @@ typedef enum {
REG_SD_DMA_ADDRESS, REG_SD_DMA_ADDRESS,
REG_SD_DMA_LENGTH, REG_SD_DMA_LENGTH,
REG_SD_DMA_SCR, REG_SD_DMA_SCR,
REG_DD_SCR,
REG_DD_CMD_DATA,
REG_DD_HEAD_TRACK,
REG_DD_SECTOR_INFO,
REG_DD_DRIVE_ID
} fpga_reg_t; } fpga_reg_t;
@ -115,6 +120,32 @@ typedef enum {
#define SD_SCR_CLOCK_MODE_25MHZ (2 << 0) #define SD_SCR_CLOCK_MODE_25MHZ (2 << 0)
#define SD_SCR_CLOCK_MODE_50MHZ (3 << 0) #define SD_SCR_CLOCK_MODE_50MHZ (3 << 0)
#define DD_SCR_HARD_RESET (1 << 0)
#define DD_SCR_HARD_RESET_CLEAR (1 << 1)
#define DD_SCR_CMD_PENDING (1 << 2)
#define DD_SCR_CMD_READY (1 << 3)
#define DD_SCR_BM_PENDING (1 << 4)
#define DD_SCR_BM_READY (1 << 5)
#define DD_SCR_DISK_INSERTED (1 << 6)
#define DD_SCR_DISK_CHANGED (1 << 7)
#define DD_SCR_BM_START (1 << 8)
#define DD_SCR_BM_START_CLEAR (1 << 9)
#define DD_SCR_BM_STOP (1 << 10)
#define DD_SCR_BM_STOP_CLEAR (1 << 11)
#define DD_SCR_BM_TRANSFER_MODE (1 << 12)
#define DD_SCR_BM_TRANSFER_BLOCKS (1 << 13)
#define DD_SCR_BM_TRANSFER_DATA (1 << 14)
#define DD_SCR_BM_TRANSFER_C2 (1 << 15)
#define DD_SCR_BM_MICRO_ERROR (1 << 16)
#define DD_SCR_BM_ACK (1 << 17)
#define DD_SCR_BM_ACK_CLEAR (1 << 18)
#define DD_SCR_BM_CLEAR (1 << 19)
#define DD_TRACK_MASK (0x0FFF)
#define DD_HEAD_MASK (0x1000)
#define DD_HEAD_TRACK_MASK (DD_HEAD_MASK | DD_TRACK_MASK)
#define DD_HEAD_TRACK_INDEX_LOCK (1 << 13)
uint8_t fpga_id_get (void); uint8_t fpga_id_get (void);
uint32_t fpga_reg_get (fpga_reg_t reg); uint32_t fpga_reg_get (fpga_reg_t reg);

View File

@ -1,3 +1,4 @@
#include "dd.h"
#include "cfg.h" #include "cfg.h"
#include "flashram.h" #include "flashram.h"
#include "fpga.h" #include "fpga.h"
@ -8,50 +9,16 @@
void gvr_task (void) { void gvr_task (void) {
while (fpga_id_get() != FPGA_ID); while (fpga_id_get() != FPGA_ID);
dd_init();
cfg_init(); cfg_init();
flashram_init(); flashram_init();
usb_init(); usb_init();
// fpga_reg_set(REG_SD_SCR, SD_SCR_CLOCK_MODE_25MHZ);
while (1) { while (1) {
dd_process();
cfg_process(); cfg_process();
flashram_process(); flashram_process();
usb_process(); usb_process();
rtc_process(); rtc_process();
} }
} }
// while (1) {
// while (fpga_reg_get(REG_STATUS) & STATUS_BUTTON);
// fpga_reg_set(REG_FLASH_SCR, 0x00E00000UL);
// while (!(fpga_reg_get(REG_STATUS) & STATUS_BUTTON));
// }
// if (!(fpga_reg_get(REG_STATUS) & STATUS_BUTTON)) {
// hw_gpio_set(GPIO_ID_LED);
// fpga_reg_set(REG_FLASH_SCR, FLASH_SCR_ERASE_MODE);
// for (int i = 0; i < ((2*1024)-128)*1024; i += 64*1024) {
// fpga_mem_write(((64+14)*1024*1024) + i, 2, buffer);
// }
// fpga_reg_set(REG_FLASH_SCR, 0);
// fpga_mem_read((64+14)*1024*1024, 2, buffer);
// hw_gpio_reset(GPIO_ID_LED);
// }
// fpga_reg_set(REG_CFG_SCR, 0); //CFG_SCR_BOOTLOADER_ENABLED
// uint8_t buffer[2];
// fpga_mem_read(0*1024*1024, 16, buffer);
// fpga_mem_read(64*1024*1024, 16, buffer);
// fpga_mem_read(64*1024*1024 + 128, 16, buffer);
// buffer[0] = 0x21;
// buffer[1] = 0x37;
// buffer[2] = 0x69;
// buffer[3] = 0x42;
// fpga_mem_write(((64 + 16)*1024*1024)-(128 * 1024), 4, buffer);
// fpga_mem_read(((64 + 16)*1024*1024)-(128 * 1024)-8, 16, buffer);