From 47633e3f36cccd4f9f8ea92f9eb5ed8afc49047a Mon Sep 17 00:00:00 2001 From: Polprzewodnikowy Date: Fri, 22 Jul 2022 12:43:53 +0200 Subject: [PATCH] dd basics --- fw/rtl/mcu/mcu_top.sv | 94 +++++++- fw/rtl/n64/n64_dd.sv | 470 ++++++++++++++++++++++----------------- fw/rtl/n64/n64_top.sv | 6 +- fw/rtl/top.sv | 3 + sw/controller/Makefile | 1 + sw/controller/src/cfg.c | 2 +- sw/controller/src/dd.c | 115 ++++++++++ sw/controller/src/dd.h | 9 + sw/controller/src/fpga.h | 31 +++ sw/controller/src/gvr.c | 39 +--- 10 files changed, 519 insertions(+), 251 deletions(-) create mode 100644 sw/controller/src/dd.c create mode 100644 sw/controller/src/dd.h diff --git a/fw/rtl/mcu/mcu_top.sv b/fw/rtl/mcu/mcu_top.sv index d334a4e..9de3de0 100644 --- a/fw/rtl/mcu/mcu_top.sv +++ b/fw/rtl/mcu/mcu_top.sv @@ -2,11 +2,12 @@ module mcu_top ( input clk, input reset, + n64_scb.controller n64_scb, + dd_scb.controller dd_scb, usb_scb.controller usb_scb, dma_scb.controller usb_dma_scb, sd_scb.controller sd_scb, dma_scb.controller sd_dma_scb, - n64_scb.controller n64_scb, flash_scb.controller flash_scb, fifo_bus.controller fifo_bus, @@ -347,13 +348,20 @@ module mcu_top ( REG_SD_DAT, REG_SD_DMA_ADDRESS, 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; logic bootloader_skip; assign n64_scb.cfg_version = 32'h53437632; + logic dd_bm_ack; + // Register read logic @@ -529,6 +537,47 @@ module mcu_top ( 2'b00 }; 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 end end @@ -559,6 +608,13 @@ module mcu_top ( 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 n64_scb.bootloader_enabled <= !bootloader_skip; end @@ -567,6 +623,10 @@ module mcu_top ( flash_scb.erase_pending <= 1'b0; end + if (dd_scb.bm_interrupt_ack) begin + dd_bm_ack <= 1'b1; + end + if (reset) begin mcu_int <= 1'b0; sd_scb.clock_mode <= 2'd0; @@ -582,6 +642,7 @@ module mcu_top ( bootloader_skip <= 1'b0; n64_scb.bootloader_enabled <= 1'b1; flash_scb.erase_pending <= 1'b0; + dd_bm_ack <= 1'b0; end else if (reg_write) begin case (address) REG_STATUS: begin end @@ -701,6 +762,35 @@ module mcu_top ( sd_dma_scb.start } <= reg_wdata[2:0]; 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 end end diff --git a/fw/rtl/n64/n64_dd.sv b/fw/rtl/n64/n64_dd.sv index 543c71f..929fb3f 100644 --- a/fw/rtl/n64/n64_dd.sv +++ b/fw/rtl/n64/n64_dd.sv @@ -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 ( input clk, input reset, @@ -5,232 +116,171 @@ module n64_dd ( n64_reg_bus.dd reg_bus, n64_scb.dd n64_scb, + dd_scb.dd dd_scb, 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; - // const bit [10:0] M_SECTOR_BUFFER = 11'h400; + typedef enum bit [10:0] { + 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] { - // R_DATA = 11'h500, - // R_CMD_SR = 11'h508, - // R_TRK_CUR = 11'h50C, - // R_BM_SCR = 11'h510, - // R_RESET = 11'h520, - // R_SEC_SIZ = 11'h528, - // R_SEC_INFO = 11'h530, - // R_ID = 11'h540 - // } e_reg_id; + typedef enum bit [3:0] { + BM_CONTROL_START_BUFFER_MANAGER = 4'd15, + BM_CONTROL_BUFFER_MANAGER_MODE = 4'd14, + BM_CONTROL_BUFFER_MANAGER_RESET = 4'd12, + BM_CONTROL_BLOCK_TRANSFER = 4'd9, + BM_CONTROL_MECHANIC_INTERRUPT_RESET = 4'd8 + } e_bm_control_id; - // typedef enum bit [3:0] { - // BM_CONTROL_START_BUFFER_MANAGER = 4'd15, - // BM_CONTROL_BUFFER_MANAGER_MODE = 4'd14, - // BM_CONTROL_BUFFER_MANAGER_RESET = 4'd12, - // BM_CONTROL_BLOCK_TRANSFER = 4'd9, - // BM_CONTROL_MECHANIC_INTERRUPT_RESET = 4'd8 - // } e_bm_control_id; + always_comb begin + reg_bus.rdata = 16'd0; + if (reg_bus.address[10:8] == MEM_SECTOR_BUFFER[10:8]) begin + reg_bus.rdata = n64_scb.dd_rdata; + end else begin + case (reg_bus.address[10:0]) + 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] { - // // S_IDLE, - // // S_WAIT - // // } e_state; + always_ff @(posedge clk) begin + dd_scb.bm_interrupt_ack <= 1'b0; - // // 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 - // // dd.sector_address = bus.address[7:1]; - // // dd.sector_address_valid = bus.request && bus.address[11:8] == M_SECTOR_BUFFER[11:8]; - // // dd.sector_write = bus.write && dd.sector_address_valid; - // // dd.sector_wdata = bus.wdata; - // // end + if (reset || n64_scb.n64_reset) begin + 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 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 - // bus.rdata = 16'd0; - // if (bus.ack) begin - // if (bus.address[10:8] == M_SECTOR_BUFFER[10:8]) begin - // 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 + REG_CMD_SR: begin + dd_scb.cmd <= reg_bus.wdata[7:0]; + dd_scb.cmd_pending <= 1'b1; + end - // always_comb begin - // reg_bus.rdata = 16'd0; - // if (reg_bus.address[10:8] == M_SECTOR_BUFFER[10:8]) begin - // end else begin - // case (reg_bus.address[10:0]) - // R_DATA: reg_bus.rdata = dd.data; - // R_CMD_SR: reg_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: 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 + REG_BM_SCR: begin + dd_scb.sector_num <= reg_bus.wdata[7:0]; + if (reg_bus.wdata[BM_CONTROL_START_BUFFER_MANAGER]) begin + dd_scb.bm_start_pending <= 1'b1; + dd_scb.bm_stop_pending <= 1'b0; + dd_scb.bm_transfer_mode <= reg_bus.wdata[BM_CONTROL_BUFFER_MANAGER_MODE]; + dd_scb.bm_transfer_blocks <= reg_bus.wdata[BM_CONTROL_BLOCK_TRANSFER]; + end + if (reg_bus.wdata[BM_CONTROL_BUFFER_MANAGER_RESET]) begin + dd_scb.bm_start_pending <= 1'b0; + dd_scb.bm_stop_pending <= 1'b1; + dd_scb.bm_transfer_mode <= 1'b0; + dd_scb.bm_transfer_blocks <= 1'b0; + dd_scb.bm_pending <= 1'b0; + dd_scb.bm_interrupt <= 1'b0; + end + if (reg_bus.wdata[BM_CONTROL_MECHANIC_INTERRUPT_RESET]) begin + dd_scb.cmd_interrupt <= 1'b0; + end + end - // always_ff @(posedge sys.clk) begin - // bus.ack <= 1'b0; - // dd.bm_interrupt_ack <= 1'b0; + REG_RESET: begin + if (reg_bus.wdata == 16'hAAAA) begin + 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 - // dd.hard_reset <= 1'b0; - // 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 + REG_SEC_SIZ: begin + dd_scb.sector_size <= reg_bus.wdata[7:0]; + end - // if (sys.reset || sys.n64_hard_reset) 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; - // 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 + REG_SEC_INFO: begin + dd_scb.sectors_in_block <= reg_bus.wdata[15:8]; + dd_scb.sector_size_full <= reg_bus.wdata[7:0]; + end + endcase + end + end - // R_CMD_SR: begin - // dd.cmd <= bus.wdata[7:0]; - // dd.cmd_pending <= 1'b1; - // 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 + irq = dd_scb.cmd_interrupt || dd_scb.bm_interrupt; + 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 diff --git a/fw/rtl/n64/n64_top.sv b/fw/rtl/n64/n64_top.sv index 939186d..c63eafc 100644 --- a/fw/rtl/n64/n64_top.sv +++ b/fw/rtl/n64/n64_top.sv @@ -2,9 +2,10 @@ module n64_top ( input clk, input reset, - mem_bus.controller mem_bus, - n64_scb n64_scb, + dd_scb.dd dd_scb, + + mem_bus.controller mem_bus, input n64_reset, input n64_nmi, @@ -52,6 +53,7 @@ module n64_top ( .reg_bus(reg_bus), .n64_scb(n64_scb), + .dd_scb(dd_scb), .irq(n64_dd_irq) ); diff --git a/fw/rtl/top.sv b/fw/rtl/top.sv index 65dfcd3..bc05538 100644 --- a/fw/rtl/top.sv +++ b/fw/rtl/top.sv @@ -52,6 +52,7 @@ module top ( logic reset; n64_scb n64_scb (); + dd_scb dd_scb (); usb_scb usb_scb (); dma_scb usb_dma_scb (); sd_scb sd_scb (); @@ -86,6 +87,7 @@ module top ( .reset(reset), .n64_scb(n64_scb), + .dd_scb(dd_scb), .usb_scb(usb_scb), .usb_dma_scb(usb_dma_scb), .sd_scb(sd_scb), @@ -113,6 +115,7 @@ module top ( .reset(reset), .n64_scb(n64_scb), + .dd_scb(dd_scb), .mem_bus(n64_mem_bus), diff --git a/sw/controller/Makefile b/sw/controller/Makefile index 2d4ea72..55ab241 100644 --- a/sw/controller/Makefile +++ b/sw/controller/Makefile @@ -16,6 +16,7 @@ SRC_FILES = \ startup.S \ cfg.c \ cic.c \ + dd.c \ flash.c \ flashram.c \ fpga.c \ diff --git a/sw/controller/src/cfg.c b/sw/controller/src/cfg.c index 9802035..d942983 100644 --- a/sw/controller/src/cfg.c +++ b/sw/controller/src/cfg.c @@ -141,7 +141,7 @@ void cfg_update (uint32_t *args) { change_scr_bits(CFG_SCR_ROM_SHADOW_ENABLED, args[1]); break; 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; case CFG_ID_ISV_ENABLE: break; diff --git a/sw/controller/src/dd.c b/sw/controller/src/dd.c new file mode 100644 index 0000000..7f96c1b --- /dev/null +++ b/sw/controller/src/dd.c @@ -0,0 +1,115 @@ +#include +#include +#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); + } +} diff --git a/sw/controller/src/dd.h b/sw/controller/src/dd.h new file mode 100644 index 0000000..3368741 --- /dev/null +++ b/sw/controller/src/dd.h @@ -0,0 +1,9 @@ +#ifndef DD_H__ +#define DD_H__ + + +void dd_init (void); +void dd_process (void); + + +#endif diff --git a/sw/controller/src/fpga.h b/sw/controller/src/fpga.h index e2666dd..53e2a06 100644 --- a/sw/controller/src/fpga.h +++ b/sw/controller/src/fpga.h @@ -46,6 +46,11 @@ typedef enum { REG_SD_DMA_ADDRESS, REG_SD_DMA_LENGTH, 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; @@ -115,6 +120,32 @@ typedef enum { #define SD_SCR_CLOCK_MODE_25MHZ (2 << 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); uint32_t fpga_reg_get (fpga_reg_t reg); diff --git a/sw/controller/src/gvr.c b/sw/controller/src/gvr.c index 184c0eb..a3ad97f 100644 --- a/sw/controller/src/gvr.c +++ b/sw/controller/src/gvr.c @@ -1,3 +1,4 @@ +#include "dd.h" #include "cfg.h" #include "flashram.h" #include "fpga.h" @@ -8,50 +9,16 @@ void gvr_task (void) { while (fpga_id_get() != FPGA_ID); + dd_init(); cfg_init(); flashram_init(); usb_init(); - // fpga_reg_set(REG_SD_SCR, SD_SCR_CLOCK_MODE_25MHZ); - while (1) { + dd_process(); cfg_process(); flashram_process(); usb_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); - - -