mirror of
https://github.com/Polprzewodnikowy/SummerCart64.git
synced 2024-11-29 08:44:15 +01:00
boot screen
This commit is contained in:
parent
200f164363
commit
59491be835
@ -178,7 +178,7 @@ set_global_assignment -name TIMING_ANALYZER_DO_REPORT_TIMING ON
|
|||||||
|
|
||||||
# Compiler Assignments
|
# Compiler Assignments
|
||||||
# ====================
|
# ====================
|
||||||
set_global_assignment -name OPTIMIZATION_MODE "HIGH PERFORMANCE EFFORT"
|
set_global_assignment -name OPTIMIZATION_MODE "AGGRESSIVE PERFORMANCE"
|
||||||
|
|
||||||
# Analysis & Synthesis Assignments
|
# Analysis & Synthesis Assignments
|
||||||
# ================================
|
# ================================
|
||||||
|
@ -10,7 +10,7 @@ module sd_dat (
|
|||||||
input i_dat_width,
|
input i_dat_width,
|
||||||
input i_dat_direction,
|
input i_dat_direction,
|
||||||
input [6:0] i_dat_block_size,
|
input [6:0] i_dat_block_size,
|
||||||
input [10:0] i_dat_num_blocks,
|
input [7:0] i_dat_num_blocks,
|
||||||
input i_dat_start,
|
input i_dat_start,
|
||||||
input i_dat_stop,
|
input i_dat_stop,
|
||||||
output o_dat_busy,
|
output o_dat_busy,
|
||||||
@ -64,16 +64,16 @@ module sd_dat (
|
|||||||
|
|
||||||
// Block counter logic
|
// Block counter logic
|
||||||
|
|
||||||
reg [10:0] r_block_counter;
|
reg [7:0] r_block_counter;
|
||||||
|
|
||||||
wire w_read_start = i_dat_start && r_state[STATE_IDLE];
|
wire w_read_start = i_dat_start && r_state[STATE_IDLE];
|
||||||
wire w_read_stop = r_block_counter == 11'd0;
|
wire w_read_stop = r_block_counter == 8'd0;
|
||||||
|
|
||||||
always @(posedge i_clk) begin
|
always @(posedge i_clk) begin
|
||||||
if (w_read_start) begin
|
if (w_read_start) begin
|
||||||
r_block_counter <= i_dat_num_blocks;
|
r_block_counter <= i_dat_num_blocks;
|
||||||
end else if (w_data_end) begin
|
end else if (w_data_end) begin
|
||||||
if (r_block_counter > 11'd0) begin
|
if (r_block_counter > 8'd0) begin
|
||||||
r_block_counter <= r_block_counter - 1'd1;
|
r_block_counter <= r_block_counter - 1'd1;
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -4,8 +4,8 @@ module sd_dma (
|
|||||||
|
|
||||||
input [3:0] i_dma_bank,
|
input [3:0] i_dma_bank,
|
||||||
input [23:0] i_dma_address,
|
input [23:0] i_dma_address,
|
||||||
input [17:0] i_dma_length,
|
input [14:0] i_dma_length,
|
||||||
output [17:0] o_dma_left,
|
output reg [14:0] o_dma_left,
|
||||||
input i_dma_load_bank_address,
|
input i_dma_load_bank_address,
|
||||||
input i_dma_load_length,
|
input i_dma_load_length,
|
||||||
input i_dma_direction,
|
input i_dma_direction,
|
||||||
@ -33,6 +33,58 @@ module sd_dma (
|
|||||||
|
|
||||||
wire w_request_successful = o_request && !i_busy;
|
wire w_request_successful = o_request && !i_busy;
|
||||||
|
|
||||||
|
always @(posedge i_clk) begin
|
||||||
|
if (i_dma_load_length && !o_dma_busy) begin
|
||||||
|
o_dma_left <= i_dma_length;
|
||||||
|
end else if (w_request_successful && o_dma_left > 15'd0) begin
|
||||||
|
o_dma_left <= o_dma_left - 1'd1;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
always @(posedge i_clk) begin
|
||||||
|
if (i_reset) begin
|
||||||
|
o_dma_busy <= 1'b0;
|
||||||
|
end else begin
|
||||||
|
if (i_dma_start && !o_dma_busy) begin
|
||||||
|
o_dma_busy <= 1'b1;
|
||||||
|
end
|
||||||
|
if (i_dma_stop || (w_request_successful && o_dma_left == 15'd0)) begin
|
||||||
|
o_dma_busy <= 1'b0;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
assign o_rx_fifo_pop = o_dma_busy && o_write && w_request_successful;
|
||||||
|
|
||||||
|
assign o_tx_fifo_push = o_dma_busy && !o_write && i_ack;
|
||||||
|
assign o_tx_fifo_data = i_data;
|
||||||
|
|
||||||
|
reg r_pending_ack;
|
||||||
|
|
||||||
|
always @(posedge i_clk) begin
|
||||||
|
if (i_reset || i_dma_stop) begin
|
||||||
|
r_pending_ack <= 1'b0;
|
||||||
|
end else if (o_dma_busy && !o_write) begin
|
||||||
|
if (w_request_successful) begin
|
||||||
|
r_pending_ack <= 1'b1;
|
||||||
|
end else if (i_ack) begin
|
||||||
|
r_pending_ack <= 1'b0;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
assign o_request = o_dma_busy && (o_write ? (
|
||||||
|
!i_rx_fifo_empty
|
||||||
|
) : (
|
||||||
|
!r_pending_ack && !i_tx_fifo_full
|
||||||
|
));
|
||||||
|
|
||||||
|
always @(posedge i_clk) begin
|
||||||
|
if (i_dma_start && !o_dma_busy) begin
|
||||||
|
o_write <= i_dma_direction;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
always @(posedge i_clk) begin
|
always @(posedge i_clk) begin
|
||||||
if (i_dma_load_bank_address && !o_dma_busy) begin
|
if (i_dma_load_bank_address && !o_dma_busy) begin
|
||||||
o_bank <= i_dma_bank;
|
o_bank <= i_dma_bank;
|
||||||
@ -47,47 +99,6 @@ module sd_dma (
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
reg [17:0] r_remaining;
|
|
||||||
|
|
||||||
assign o_dma_left = r_remaining;
|
|
||||||
|
|
||||||
always @(posedge i_clk) begin
|
|
||||||
if (i_dma_load_length && !o_dma_busy) begin
|
|
||||||
r_remaining <= i_dma_length;
|
|
||||||
end else if (w_request_successful && r_remaining > 18'd0) begin
|
|
||||||
r_remaining <= r_remaining - 1'd1;
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
always @(posedge i_clk) begin
|
|
||||||
if (i_reset) begin
|
|
||||||
o_dma_busy <= 1'b0;
|
|
||||||
end else begin
|
|
||||||
if (i_dma_start && !o_dma_busy) begin
|
|
||||||
o_dma_busy <= 1'b1;
|
|
||||||
end
|
|
||||||
if (i_dma_stop || (w_request_successful && r_remaining == 18'd0)) begin
|
|
||||||
o_dma_busy <= 1'b0;
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
assign o_rx_fifo_pop = o_dma_busy && o_write && w_request_successful;
|
|
||||||
|
|
||||||
assign o_tx_fifo_data = i_data;
|
|
||||||
|
|
||||||
assign o_request = o_dma_busy && (o_write ? (
|
|
||||||
!i_rx_fifo_empty
|
|
||||||
) : (
|
|
||||||
1'b0 // TODO: Reading
|
|
||||||
));
|
|
||||||
|
|
||||||
always @(posedge i_clk) begin
|
|
||||||
if (i_dma_start) begin
|
|
||||||
o_write <= i_dma_direction;
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
assign o_data = i_rx_fifo_data;
|
assign o_data = i_rx_fifo_data;
|
||||||
|
|
||||||
endmodule
|
endmodule
|
||||||
|
@ -7,22 +7,22 @@ module sd_fifo (
|
|||||||
input i_fifo_pop,
|
input i_fifo_pop,
|
||||||
output o_fifo_empty,
|
output o_fifo_empty,
|
||||||
output o_fifo_full,
|
output o_fifo_full,
|
||||||
output [7:0] o_fifo_items,
|
|
||||||
output reg o_fifo_underrun,
|
output reg o_fifo_underrun,
|
||||||
output reg o_fifo_overrun,
|
output reg o_fifo_overrun,
|
||||||
|
output [8:0] o_fifo_items,
|
||||||
input [31:0] i_fifo_data,
|
input [31:0] i_fifo_data,
|
||||||
output [31:0] o_fifo_data
|
output [31:0] o_fifo_data
|
||||||
);
|
);
|
||||||
|
|
||||||
reg [31:0] r_fifo_mem [0:127];
|
reg [31:0] r_fifo_mem [0:255];
|
||||||
|
|
||||||
reg [7:0] r_fifo_wrptr;
|
reg [8:0] r_fifo_wrptr;
|
||||||
reg [7:0] r_fifo_rdptr;
|
reg [8:0] r_fifo_rdptr;
|
||||||
|
|
||||||
assign o_fifo_data = r_fifo_mem[r_fifo_rdptr[6:0]];
|
assign o_fifo_data = r_fifo_mem[r_fifo_rdptr[7:0]];
|
||||||
|
|
||||||
wire w_empty = r_fifo_wrptr[7] == r_fifo_rdptr[7];
|
wire w_empty = r_fifo_wrptr[8] == r_fifo_rdptr[8];
|
||||||
wire w_full_or_empty = r_fifo_wrptr[6:0] == r_fifo_rdptr[6:0];
|
wire w_full_or_empty = r_fifo_wrptr[7:0] == r_fifo_rdptr[7:0];
|
||||||
|
|
||||||
assign o_fifo_empty = w_empty && w_full_or_empty;
|
assign o_fifo_empty = w_empty && w_full_or_empty;
|
||||||
assign o_fifo_full = !w_empty && w_full_or_empty;
|
assign o_fifo_full = !w_empty && w_full_or_empty;
|
||||||
@ -30,20 +30,20 @@ module sd_fifo (
|
|||||||
|
|
||||||
always @(posedge i_clk) begin
|
always @(posedge i_clk) begin
|
||||||
if (i_reset) begin
|
if (i_reset) begin
|
||||||
r_fifo_wrptr <= 8'd0;
|
r_fifo_wrptr <= 9'd0;
|
||||||
r_fifo_rdptr <= 8'd0;
|
r_fifo_rdptr <= 9'd0;
|
||||||
o_fifo_underrun <= 1'b0;
|
o_fifo_underrun <= 1'b0;
|
||||||
o_fifo_overrun <= 1'b0;
|
o_fifo_overrun <= 1'b0;
|
||||||
end else begin
|
end else begin
|
||||||
if (i_fifo_flush) begin
|
if (i_fifo_flush) begin
|
||||||
r_fifo_wrptr <= 8'd0;
|
r_fifo_wrptr <= 9'd0;
|
||||||
r_fifo_rdptr <= 8'd0;
|
r_fifo_rdptr <= 9'd0;
|
||||||
o_fifo_underrun <= 1'b0;
|
o_fifo_underrun <= 1'b0;
|
||||||
o_fifo_overrun <= 1'b0;
|
o_fifo_overrun <= 1'b0;
|
||||||
end
|
end
|
||||||
if (i_fifo_push) begin
|
if (i_fifo_push) begin
|
||||||
o_fifo_overrun <= o_fifo_overrun ? 1'b1 : o_fifo_full;
|
o_fifo_overrun <= o_fifo_overrun ? 1'b1 : o_fifo_full;
|
||||||
r_fifo_mem[r_fifo_wrptr[6:0]] <= i_fifo_data;
|
r_fifo_mem[r_fifo_wrptr[7:0]] <= i_fifo_data;
|
||||||
r_fifo_wrptr <= r_fifo_wrptr + 1'd1;
|
r_fifo_wrptr <= r_fifo_wrptr + 1'd1;
|
||||||
end
|
end
|
||||||
if (i_fifo_pop) begin
|
if (i_fifo_pop) begin
|
||||||
|
@ -85,8 +85,9 @@ module sd_interface (
|
|||||||
wire w_rx_fifo_regs_pop;
|
wire w_rx_fifo_regs_pop;
|
||||||
wire w_rx_fifo_dma_pop;
|
wire w_rx_fifo_dma_pop;
|
||||||
wire w_rx_fifo_empty;
|
wire w_rx_fifo_empty;
|
||||||
wire [7:0] w_rx_fifo_items;
|
wire w_rx_fifo_full;
|
||||||
wire w_rx_fifo_overrun;
|
wire w_rx_fifo_overrun;
|
||||||
|
wire [8:0] w_rx_fifo_items;
|
||||||
wire [31:0] w_rx_fifo_i_data;
|
wire [31:0] w_rx_fifo_i_data;
|
||||||
wire [31:0] w_rx_fifo_o_data;
|
wire [31:0] w_rx_fifo_o_data;
|
||||||
|
|
||||||
@ -98,10 +99,10 @@ module sd_interface (
|
|||||||
.i_fifo_push(w_rx_fifo_push),
|
.i_fifo_push(w_rx_fifo_push),
|
||||||
.i_fifo_pop(w_rx_fifo_regs_pop || w_rx_fifo_dma_pop),
|
.i_fifo_pop(w_rx_fifo_regs_pop || w_rx_fifo_dma_pop),
|
||||||
.o_fifo_empty(w_rx_fifo_empty),
|
.o_fifo_empty(w_rx_fifo_empty),
|
||||||
.o_fifo_full(),
|
.o_fifo_full(w_rx_fifo_full),
|
||||||
.o_fifo_items(w_rx_fifo_items),
|
|
||||||
.o_fifo_underrun(),
|
.o_fifo_underrun(),
|
||||||
.o_fifo_overrun(w_rx_fifo_overrun),
|
.o_fifo_overrun(w_rx_fifo_overrun),
|
||||||
|
.o_fifo_items(w_rx_fifo_items),
|
||||||
.i_fifo_data(w_rx_fifo_i_data),
|
.i_fifo_data(w_rx_fifo_i_data),
|
||||||
.o_fifo_data(w_rx_fifo_o_data)
|
.o_fifo_data(w_rx_fifo_o_data)
|
||||||
);
|
);
|
||||||
@ -115,6 +116,8 @@ module sd_interface (
|
|||||||
wire w_tx_fifo_pop;
|
wire w_tx_fifo_pop;
|
||||||
wire w_tx_fifo_empty;
|
wire w_tx_fifo_empty;
|
||||||
wire w_tx_fifo_full;
|
wire w_tx_fifo_full;
|
||||||
|
wire w_tx_fifo_underrun;
|
||||||
|
wire [8:0] w_tx_fifo_items;
|
||||||
reg [31:0] r_tx_fifo_i_data;
|
reg [31:0] r_tx_fifo_i_data;
|
||||||
wire [31:0] w_tx_fifo_o_data;
|
wire [31:0] w_tx_fifo_o_data;
|
||||||
|
|
||||||
@ -136,9 +139,9 @@ module sd_interface (
|
|||||||
.i_fifo_pop(w_tx_fifo_pop),
|
.i_fifo_pop(w_tx_fifo_pop),
|
||||||
.o_fifo_empty(w_tx_fifo_empty),
|
.o_fifo_empty(w_tx_fifo_empty),
|
||||||
.o_fifo_full(w_tx_fifo_full),
|
.o_fifo_full(w_tx_fifo_full),
|
||||||
.o_fifo_items(),
|
.o_fifo_underrun(w_tx_fifo_underrun),
|
||||||
.o_fifo_underrun(),
|
|
||||||
.o_fifo_overrun(),
|
.o_fifo_overrun(),
|
||||||
|
.o_fifo_items(w_tx_fifo_items),
|
||||||
.i_fifo_data(r_tx_fifo_i_data),
|
.i_fifo_data(r_tx_fifo_i_data),
|
||||||
.o_fifo_data(w_tx_fifo_o_data)
|
.o_fifo_data(w_tx_fifo_o_data)
|
||||||
);
|
);
|
||||||
@ -149,7 +152,7 @@ module sd_interface (
|
|||||||
wire w_dat_width;
|
wire w_dat_width;
|
||||||
wire w_dat_direction;
|
wire w_dat_direction;
|
||||||
wire [6:0] w_dat_block_size;
|
wire [6:0] w_dat_block_size;
|
||||||
wire [10:0] w_dat_num_blocks;
|
wire [7:0] w_dat_num_blocks;
|
||||||
wire w_dat_start;
|
wire w_dat_start;
|
||||||
wire w_dat_stop;
|
wire w_dat_stop;
|
||||||
wire w_dat_busy;
|
wire w_dat_busy;
|
||||||
@ -187,8 +190,8 @@ module sd_interface (
|
|||||||
|
|
||||||
wire [3:0] w_dma_bank;
|
wire [3:0] w_dma_bank;
|
||||||
wire [23:0] w_dma_address;
|
wire [23:0] w_dma_address;
|
||||||
wire [17:0] w_dma_length;
|
wire [14:0] w_dma_length;
|
||||||
wire [17:0] w_dma_left;
|
wire [14:0] w_dma_left;
|
||||||
wire w_dma_load_bank_address;
|
wire w_dma_load_bank_address;
|
||||||
wire w_dma_load_length;
|
wire w_dma_load_length;
|
||||||
wire w_dma_direction;
|
wire w_dma_direction;
|
||||||
@ -260,14 +263,18 @@ module sd_interface (
|
|||||||
|
|
||||||
.o_rx_fifo_flush(w_rx_fifo_flush),
|
.o_rx_fifo_flush(w_rx_fifo_flush),
|
||||||
.o_rx_fifo_pop(w_rx_fifo_regs_pop),
|
.o_rx_fifo_pop(w_rx_fifo_regs_pop),
|
||||||
.i_rx_fifo_items(w_rx_fifo_items),
|
.i_rx_fifo_empty(w_rx_fifo_empty),
|
||||||
|
.i_rx_fifo_full(w_rx_fifo_full),
|
||||||
.i_rx_fifo_overrun(w_rx_fifo_overrun),
|
.i_rx_fifo_overrun(w_rx_fifo_overrun),
|
||||||
|
.i_rx_fifo_items(w_rx_fifo_items),
|
||||||
.i_rx_fifo_data(w_rx_fifo_o_data),
|
.i_rx_fifo_data(w_rx_fifo_o_data),
|
||||||
|
|
||||||
.o_tx_fifo_flush(w_tx_fifo_flush),
|
.o_tx_fifo_flush(w_tx_fifo_flush),
|
||||||
.o_tx_fifo_push(w_tx_fifo_regs_push),
|
.o_tx_fifo_push(w_tx_fifo_regs_push),
|
||||||
.i_tx_fifo_empty(w_tx_fifo_empty),
|
.i_tx_fifo_empty(w_tx_fifo_empty),
|
||||||
.i_tx_fifo_full(w_tx_fifo_full),
|
.i_tx_fifo_full(w_tx_fifo_full),
|
||||||
|
.i_tx_fifo_underrun(w_tx_fifo_underrun),
|
||||||
|
.i_tx_fifo_items(w_tx_fifo_items),
|
||||||
.o_tx_fifo_data(w_tx_fifo_i_data_regs),
|
.o_tx_fifo_data(w_tx_fifo_i_data_regs),
|
||||||
|
|
||||||
.o_dma_bank(w_dma_bank),
|
.o_dma_bank(w_dma_bank),
|
||||||
|
@ -18,7 +18,7 @@ module sd_regs (
|
|||||||
output reg o_dat_width,
|
output reg o_dat_width,
|
||||||
output reg o_dat_direction,
|
output reg o_dat_direction,
|
||||||
output reg [6:0] o_dat_block_size,
|
output reg [6:0] o_dat_block_size,
|
||||||
output reg [10:0] o_dat_num_blocks,
|
output reg [7:0] o_dat_num_blocks,
|
||||||
output reg o_dat_start,
|
output reg o_dat_start,
|
||||||
output reg o_dat_stop,
|
output reg o_dat_stop,
|
||||||
input i_dat_busy,
|
input i_dat_busy,
|
||||||
@ -26,24 +26,28 @@ module sd_regs (
|
|||||||
|
|
||||||
output reg o_rx_fifo_flush,
|
output reg o_rx_fifo_flush,
|
||||||
output reg o_rx_fifo_pop,
|
output reg o_rx_fifo_pop,
|
||||||
input [7:0] i_rx_fifo_items,
|
input i_rx_fifo_empty,
|
||||||
|
input i_rx_fifo_full,
|
||||||
input i_rx_fifo_overrun,
|
input i_rx_fifo_overrun,
|
||||||
|
input [8:0] i_rx_fifo_items,
|
||||||
input [31:0] i_rx_fifo_data,
|
input [31:0] i_rx_fifo_data,
|
||||||
|
|
||||||
output reg o_tx_fifo_flush,
|
output reg o_tx_fifo_flush,
|
||||||
output reg o_tx_fifo_push,
|
output o_tx_fifo_push,
|
||||||
input i_tx_fifo_empty,
|
input i_tx_fifo_empty,
|
||||||
input i_tx_fifo_full,
|
input i_tx_fifo_full,
|
||||||
output reg [31:0] o_tx_fifo_data,
|
input i_tx_fifo_underrun,
|
||||||
|
input [8:0] i_tx_fifo_items,
|
||||||
|
output [31:0] o_tx_fifo_data,
|
||||||
|
|
||||||
output reg [3:0] o_dma_bank,
|
output [3:0] o_dma_bank,
|
||||||
output reg [23:0] o_dma_address,
|
output [23:0] o_dma_address,
|
||||||
output reg [17:0] o_dma_length,
|
output [14:0] o_dma_length,
|
||||||
input [3:0] i_dma_bank,
|
input [3:0] i_dma_bank,
|
||||||
input [23:0] i_dma_address,
|
input [23:0] i_dma_address,
|
||||||
input [17:0] i_dma_left,
|
input [14:0] i_dma_left,
|
||||||
output reg o_dma_load_bank_address,
|
output o_dma_load_bank_address,
|
||||||
output reg o_dma_load_length,
|
output o_dma_load_length,
|
||||||
output reg o_dma_direction,
|
output reg o_dma_direction,
|
||||||
output reg o_dma_start,
|
output reg o_dma_start,
|
||||||
output reg o_dma_stop,
|
output reg o_dma_stop,
|
||||||
@ -73,9 +77,11 @@ module sd_regs (
|
|||||||
always @(*) begin
|
always @(*) begin
|
||||||
o_dma_bank = i_data[31:28];
|
o_dma_bank = i_data[31:28];
|
||||||
o_dma_address = i_data[25:2];
|
o_dma_address = i_data[25:2];
|
||||||
o_dma_length = i_data[17:0];
|
o_dma_length = i_data[14:0];
|
||||||
o_dma_load_bank_address = w_write_request && !i_address[3] && (i_address[2:0] == SD_REG_DMA_ADDR);
|
o_dma_load_bank_address = w_write_request && !i_address[3] && (i_address[2:0] == SD_REG_DMA_ADDR);
|
||||||
o_dma_load_length = w_write_request && !i_address[3] && (i_address[2:0] == SD_REG_DMA_LEN);
|
o_dma_load_length = w_write_request && !i_address[3] && (i_address[2:0] == SD_REG_DMA_LEN);
|
||||||
|
o_tx_fifo_data = i_data;
|
||||||
|
o_tx_fifo_push = w_write_request && i_address[3] && !i_tx_fifo_full && !i_dma_busy;
|
||||||
o_busy = 1'b0;
|
o_busy = 1'b0;
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -84,7 +90,6 @@ module sd_regs (
|
|||||||
o_dat_start <= 1'b0;
|
o_dat_start <= 1'b0;
|
||||||
o_rx_fifo_flush <= 1'b0;
|
o_rx_fifo_flush <= 1'b0;
|
||||||
o_tx_fifo_flush <= 1'b0;
|
o_tx_fifo_flush <= 1'b0;
|
||||||
o_tx_fifo_push <= 1'b0;
|
|
||||||
o_dma_start <= 1'b0;
|
o_dma_start <= 1'b0;
|
||||||
o_dat_stop <= 1'b0;
|
o_dat_stop <= 1'b0;
|
||||||
o_dma_stop <= 1'b0;
|
o_dma_stop <= 1'b0;
|
||||||
@ -94,49 +99,62 @@ module sd_regs (
|
|||||||
o_dat_width <= 1'b0;
|
o_dat_width <= 1'b0;
|
||||||
o_dat_direction <= 1'b0;
|
o_dat_direction <= 1'b0;
|
||||||
o_dat_block_size <= 7'd0;
|
o_dat_block_size <= 7'd0;
|
||||||
o_dat_num_blocks <= 11'd0;
|
o_dat_num_blocks <= 8'd0;
|
||||||
o_dma_direction <= 1'b0;
|
o_dma_direction <= 1'b0;
|
||||||
end else if (w_write_request) begin
|
end else if (w_write_request) begin
|
||||||
if (!i_address[3]) begin
|
if (!i_address[3]) begin
|
||||||
case (i_address[2:0])
|
case (i_address[2:0])
|
||||||
SD_REG_SCR: begin
|
SD_REG_SCR: begin
|
||||||
{o_dat_width, o_sd_clk_config} <= i_data[2:0];
|
if (!i_command_busy && !i_dat_busy) begin
|
||||||
|
o_sd_clk_config <= i_data[1:0];
|
||||||
|
end
|
||||||
|
if (!i_dat_busy) begin
|
||||||
|
o_dat_width <= i_data[2];
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
SD_REG_ARG: begin
|
SD_REG_ARG: begin
|
||||||
o_command_argument <= i_data;
|
if (!i_command_busy) begin
|
||||||
|
o_command_argument <= i_data;
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
SD_REG_CMD: begin
|
SD_REG_CMD: begin
|
||||||
{
|
if (!i_command_busy) begin
|
||||||
o_command_skip_response,
|
{
|
||||||
o_command_long_response,
|
o_command_skip_response,
|
||||||
o_command_start,
|
o_command_long_response,
|
||||||
o_command_index
|
o_command_start,
|
||||||
} <= i_data[8:0];
|
o_command_index
|
||||||
|
} <= i_data[8:0];
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
SD_REG_RSP: begin
|
SD_REG_RSP: begin
|
||||||
end
|
end
|
||||||
|
|
||||||
SD_REG_DAT: begin
|
SD_REG_DAT: begin
|
||||||
{
|
if (!i_dat_busy || i_data[1]) begin
|
||||||
o_tx_fifo_flush,
|
{
|
||||||
o_rx_fifo_flush,
|
o_tx_fifo_flush,
|
||||||
o_dat_num_blocks,
|
o_rx_fifo_flush,
|
||||||
o_dat_block_size,
|
o_dat_num_blocks,
|
||||||
o_dat_direction,
|
o_dat_block_size,
|
||||||
o_dat_stop,
|
o_dat_direction,
|
||||||
o_dat_start
|
o_dat_stop,
|
||||||
} <= i_data[22:0];
|
o_dat_start
|
||||||
|
} <= i_data[19:0];
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
SD_REG_DMA_SCR: begin
|
SD_REG_DMA_SCR: begin
|
||||||
{
|
if (!i_dma_busy || i_data[1]) begin
|
||||||
o_dma_direction,
|
{
|
||||||
o_dma_stop,
|
o_dma_direction,
|
||||||
o_dma_start
|
o_dma_stop,
|
||||||
} <= i_data[2:0];
|
o_dma_start
|
||||||
|
} <= i_data[2:0];
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
SD_REG_DMA_ADDR: begin
|
SD_REG_DMA_ADDR: begin
|
||||||
@ -145,9 +163,6 @@ module sd_regs (
|
|||||||
SD_REG_DMA_LEN: begin
|
SD_REG_DMA_LEN: begin
|
||||||
end
|
end
|
||||||
endcase
|
endcase
|
||||||
end else begin
|
|
||||||
o_tx_fifo_push <= 1'b1;
|
|
||||||
o_tx_fifo_data <= i_data;
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -173,11 +188,9 @@ module sd_regs (
|
|||||||
|
|
||||||
SD_REG_CMD: begin
|
SD_REG_CMD: begin
|
||||||
o_data <= {
|
o_data <= {
|
||||||
21'd0,
|
23'd0,
|
||||||
i_command_response_crc_error,
|
i_command_response_crc_error,
|
||||||
i_command_timeout,
|
i_command_timeout,
|
||||||
o_command_skip_response,
|
|
||||||
o_command_long_response,
|
|
||||||
i_command_busy,
|
i_command_busy,
|
||||||
i_command_index
|
i_command_index
|
||||||
};
|
};
|
||||||
@ -189,13 +202,15 @@ module sd_regs (
|
|||||||
|
|
||||||
SD_REG_DAT: begin
|
SD_REG_DAT: begin
|
||||||
o_data <= {
|
o_data <= {
|
||||||
i_rx_fifo_items,
|
6'd0,
|
||||||
|
i_tx_fifo_items,
|
||||||
i_tx_fifo_full,
|
i_tx_fifo_full,
|
||||||
i_tx_fifo_empty,
|
i_tx_fifo_empty,
|
||||||
|
i_tx_fifo_underrun,
|
||||||
|
i_rx_fifo_items,
|
||||||
|
i_rx_fifo_full,
|
||||||
|
i_rx_fifo_empty,
|
||||||
i_rx_fifo_overrun,
|
i_rx_fifo_overrun,
|
||||||
o_dat_num_blocks,
|
|
||||||
o_dat_block_size,
|
|
||||||
o_dat_direction,
|
|
||||||
i_dat_crc_error,
|
i_dat_crc_error,
|
||||||
i_dat_busy
|
i_dat_busy
|
||||||
};
|
};
|
||||||
@ -210,11 +225,13 @@ module sd_regs (
|
|||||||
end
|
end
|
||||||
|
|
||||||
SD_REG_DMA_LEN: begin
|
SD_REG_DMA_LEN: begin
|
||||||
o_data <= {14'd0, i_dma_left};
|
o_data <= {17'd0, i_dma_left};
|
||||||
end
|
end
|
||||||
endcase
|
endcase
|
||||||
end else begin
|
end else begin
|
||||||
o_rx_fifo_pop <= 1'b1;
|
if (!i_rx_fifo_empty && !i_dma_busy) begin
|
||||||
|
o_rx_fifo_pop <= 1'b1;
|
||||||
|
end
|
||||||
o_data <= i_rx_fifo_data;
|
o_data <= i_rx_fifo_data;
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -1,58 +1,67 @@
|
|||||||
ROOTDIR = $(N64_INST)
|
ROOTDIR = $(N64_INST)
|
||||||
|
|
||||||
GCCN64PREFIX = $(ROOTDIR)/bin/mips64-elf-
|
GCCN64PREFIX = $(ROOTDIR)/bin/mips64-elf-
|
||||||
CHKSUM64PATH = $(ROOTDIR)/bin/chksum64
|
|
||||||
MKDFSPATH = $(ROOTDIR)/bin/mkdfs
|
|
||||||
HEADERPATH = $(ROOTDIR)/mips64-elf/lib
|
|
||||||
N64TOOL = $(ROOTDIR)/bin/n64tool
|
|
||||||
HEADERNAME = header
|
|
||||||
LINK_FLAGS = -L$(ROOTDIR)/mips64-elf/lib -ldragon -lc -lm -ldragonsys -Tn64.ld
|
|
||||||
CFLAGS = -std=gnu99 -march=vr4300 -mtune=vr4300 -Os -Wall -I./src -I./src/boot -I./src/fatfs -I./src/sc64 -I$(ROOTDIR)/mips64-elf/include
|
|
||||||
ASFLAGS = -mtune=vr4300 -march=vr4300
|
|
||||||
CC = $(GCCN64PREFIX)gcc
|
CC = $(GCCN64PREFIX)gcc
|
||||||
AS = $(GCCN64PREFIX)as
|
AS = $(GCCN64PREFIX)as
|
||||||
LD = $(GCCN64PREFIX)ld
|
LD = $(GCCN64PREFIX)ld
|
||||||
OBJCOPY = $(GCCN64PREFIX)objcopy
|
OBJCOPY = $(GCCN64PREFIX)objcopy
|
||||||
OBJDUMP = $(GCCN64PREFIX)objdump
|
OBJDUMP = $(GCCN64PREFIX)objdump
|
||||||
|
|
||||||
SRC_DIRS = src src/boot src/fatfs src/sc64
|
CHKSUM64 = $(ROOTDIR)/bin/chksum64
|
||||||
SRC_FILES = $(wildcard $(patsubst %, %/*.c, . $(SRC_DIRS)))
|
MKSPRITE = $(ROOTDIR)/bin/mksprite
|
||||||
OBJ_FILES = $(addprefix build/, $(notdir $(SRC_FILES:.c=.o)))
|
N64TOOL = $(ROOTDIR)/bin/n64tool
|
||||||
VPATH = $(SRC_DIRS)
|
|
||||||
|
|
||||||
ROM_SIZE = 90k
|
HEADER_PATH = $(ROOTDIR)/mips64-elf/lib
|
||||||
|
HEADER_NAME = header
|
||||||
ifeq ($(N64_BYTE_SWAP),true)
|
|
||||||
ROM_EXTENSION = .v64
|
|
||||||
N64_FLAGS = -b -l $(ROM_SIZE) -h $(HEADERPATH)/$(HEADERNAME) -o build/$(PROG_NAME)$(ROM_EXTENSION)
|
|
||||||
else
|
|
||||||
ROM_EXTENSION = .z64
|
|
||||||
N64_FLAGS = -l $(ROM_SIZE) -h $(HEADERPATH)/$(HEADERNAME) -o build/$(PROG_NAME)$(ROM_EXTENSION)
|
|
||||||
endif
|
|
||||||
|
|
||||||
PROG_NAME = SummerLoader64
|
PROG_NAME = SummerLoader64
|
||||||
|
|
||||||
all: make_output_dir build/$(PROG_NAME)$(ROM_EXTENSION)
|
ROM_SIZE = 90k
|
||||||
|
|
||||||
|
SOURCE_DIR = src
|
||||||
|
BUILD_DIR = build
|
||||||
|
|
||||||
|
SRC_DIRS = $(SOURCE_DIR) $(sort $(dir $(wildcard $(SOURCE_DIR)/*/.)))
|
||||||
|
INC_DIRS = $(addprefix -I, . $(SRC_DIRS))
|
||||||
|
SRC_FILES = $(wildcard $(patsubst %, %/*.c, . $(SRC_DIRS)))
|
||||||
|
IMG_FILES = $(wildcard $(patsubst %, %/*.png, . $(SRC_DIRS)))
|
||||||
|
OBJ_FILES = $(addprefix $(BUILD_DIR)/, $(notdir $(IMG_FILES:.png=.o) $(SRC_FILES:.c=.o)))
|
||||||
|
|
||||||
|
VPATH = $(SRC_DIRS)
|
||||||
|
|
||||||
|
COMMONFLAGS = -march=vr4300 -mtune=vr4300
|
||||||
|
ASFLAGS = $(COMMONFLAGS)
|
||||||
|
CFLAGS = $(COMMONFLAGS) -std=gnu99 -Os -Wall -I$(ROOTDIR)/mips64-elf/include $(INC_DIRS)
|
||||||
|
LINK_FLAGS = -L$(ROOTDIR)/mips64-elf/lib -ldragon -lc -lm -ldragonsys -Tn64.ld
|
||||||
|
N64_FLAGS = -l $(ROM_SIZE) -h $(HEADER_PATH)/$(HEADER_NAME) -o $(BUILD_DIR)/$(PROG_NAME).z64
|
||||||
|
|
||||||
|
all: make_output_dir $(BUILD_DIR)/$(PROG_NAME).z64
|
||||||
|
|
||||||
$(OBJ_FILES): Makefile
|
$(OBJ_FILES): Makefile
|
||||||
|
|
||||||
build/$(PROG_NAME)$(ROM_EXTENSION): build/$(PROG_NAME).elf
|
$(BUILD_DIR)/$(PROG_NAME).z64: $(BUILD_DIR)/$(PROG_NAME).elf
|
||||||
$(OBJCOPY) build/$(PROG_NAME).elf build/$(PROG_NAME).bin -O binary
|
$(OBJCOPY) $(BUILD_DIR)/$(PROG_NAME).elf $(BUILD_DIR)/$(PROG_NAME).bin -O binary
|
||||||
$(OBJDUMP) -S build/$(PROG_NAME).elf > build/$(PROG_NAME).lst
|
$(OBJDUMP) -S $(BUILD_DIR)/$(PROG_NAME).elf > $(BUILD_DIR)/$(PROG_NAME).lst
|
||||||
rm -f build/$(PROG_NAME)$(ROM_EXTENSION)
|
$(N64TOOL) $(N64_FLAGS) -t $(PROG_NAME) $(BUILD_DIR)/$(PROG_NAME).bin
|
||||||
$(N64TOOL) $(N64_FLAGS) -t $(PROG_NAME) build/$(PROG_NAME).bin
|
$(CHKSUM64) $(BUILD_DIR)/$(PROG_NAME).z64
|
||||||
$(CHKSUM64PATH) build/$(PROG_NAME)$(ROM_EXTENSION)
|
$(OBJCOPY) $(BUILD_DIR)/$(PROG_NAME).z64 $(BUILD_DIR)/$(PROG_NAME).hex -I binary -O ihex
|
||||||
$(OBJCOPY) build/$(PROG_NAME)$(ROM_EXTENSION) build/$(PROG_NAME).hex -I binary -O ihex
|
|
||||||
|
|
||||||
build/$(PROG_NAME).elf: $(OBJ_FILES)
|
$(BUILD_DIR)/$(PROG_NAME).elf: $(OBJ_FILES)
|
||||||
$(LD) -o build/$(PROG_NAME).elf $(OBJ_FILES) $(LINK_FLAGS)
|
$(LD) -o $(BUILD_DIR)/$(PROG_NAME).elf $(OBJ_FILES) $(LINK_FLAGS)
|
||||||
|
|
||||||
build/%.o: %.c
|
$(BUILD_DIR)/%.o: %.c
|
||||||
$(COMPILE.c) $(OUTPUT_OPTION) $<
|
$(COMPILE.c) $(OUTPUT_OPTION) $<
|
||||||
|
|
||||||
|
$(BUILD_DIR)/%.sprite: $(IMG_FILES)
|
||||||
|
$(MKSPRITE) 32 $< $@
|
||||||
|
|
||||||
|
$(BUILD_DIR)/%.o: $(BUILD_DIR)/%.sprite
|
||||||
|
$(OBJCOPY) -I binary -O elf32-bigmips -B mips:4000 --rename-section .data=.rodata $< $@
|
||||||
|
|
||||||
make_output_dir:
|
make_output_dir:
|
||||||
$(shell mkdir ./build 2>/dev/null)
|
$(shell mkdir ./$(BUILD_DIR) 2> /dev/null)
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -rf ./build
|
$(shell rm -rf ./$(BUILD_DIR) 2> /dev/null)
|
||||||
|
|
||||||
.PHONY: all clean make_output_dir
|
.PHONY: all clean make_output_dir
|
||||||
|
@ -1,7 +1,3 @@
|
|||||||
# SummerLoader64
|
# SummerLoader64
|
||||||
|
|
||||||
A N64 bootloader for SummerCart64. This project is mainly based on work by **`jago85`** contained in [Brutzelkarte_Bootloader repository](https://github.com/jago85/Brutzelkarte_Bootloader) with some modifications that made code a little bit more readable.
|
A N64 bootloader for SummerCart64. This project is mainly based on work by **`jago85`** contained in [Brutzelkarte_Bootloader repository](https://github.com/jago85/Brutzelkarte_Bootloader) with some modifications that made code a little bit more readable.
|
||||||
|
|
||||||
## TODO
|
|
||||||
|
|
||||||
- Expand documentation
|
|
||||||
|
@ -1,3 +1,10 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
docker run -t --mount type=bind,src="$(pwd)",target="/libdragon" anacierdem/libdragon:4.1.1 /bin/bash -c "/usr/bin/make clean; /usr/bin/make all N64_BYTE_SWAP=false"
|
LIBDRAGON_DOCKER_VERSION=latest
|
||||||
|
|
||||||
|
docker \
|
||||||
|
run \
|
||||||
|
-t \
|
||||||
|
--mount type=bind,src=`realpath "$(dirname $0)"`,target="/libdragon" \
|
||||||
|
anacierdem/libdragon:$LIBDRAGON_DOCKER_VERSION \
|
||||||
|
/bin/bash -c "make clean && make all"
|
||||||
|
12
sw/bootloader/src/assets/assets.h
Normal file
12
sw/bootloader/src/assets/assets.h
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
#ifndef ASSETS_H__
|
||||||
|
#define ASSETS_H__
|
||||||
|
|
||||||
|
|
||||||
|
#include <libdragon.h>
|
||||||
|
|
||||||
|
|
||||||
|
extern sprite_t _binary_build_sc64_logo_sprite_start[];
|
||||||
|
extern sprite_t _binary_build_sc64_logo_sprite_end[];
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
BIN
sw/bootloader/src/assets/sc64_logo.png
Normal file
BIN
sw/bootloader/src/assets/sc64_logo.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 8.4 KiB |
@ -3,7 +3,10 @@
|
|||||||
#include "n64_regs.h"
|
#include "n64_regs.h"
|
||||||
|
|
||||||
|
|
||||||
static const struct crc32_to_cic_seed crc32_to_cic_seed[] = {
|
static const struct crc32_to_cic_seed {
|
||||||
|
uint32_t ipl3_crc32;
|
||||||
|
uint16_t cic_seed;
|
||||||
|
} crc32_to_cic_seed[] = {
|
||||||
{ .ipl3_crc32 = 0x587BD543, .cic_seed = 0x00AC }, // CIC5101
|
{ .ipl3_crc32 = 0x587BD543, .cic_seed = 0x00AC }, // CIC5101
|
||||||
{ .ipl3_crc32 = 0x6170A4A1, .cic_seed = 0x013F }, // CIC6101
|
{ .ipl3_crc32 = 0x6170A4A1, .cic_seed = 0x013F }, // CIC6101
|
||||||
{ .ipl3_crc32 = 0x009E9EA3, .cic_seed = 0x013F }, // CIC7102
|
{ .ipl3_crc32 = 0x009E9EA3, .cic_seed = 0x013F }, // CIC7102
|
||||||
@ -53,7 +56,7 @@ tv_type_t boot_get_tv_type(cart_header_t *cart_header) {
|
|||||||
case 'W':
|
case 'W':
|
||||||
case 'X':
|
case 'X':
|
||||||
case 'Y':
|
case 'Y':
|
||||||
return E_TV_TYPE_PAL;
|
return TV_PAL;
|
||||||
case '7':
|
case '7':
|
||||||
case 'A':
|
case 'A':
|
||||||
case 'C':
|
case 'C':
|
||||||
@ -62,11 +65,11 @@ tv_type_t boot_get_tv_type(cart_header_t *cart_header) {
|
|||||||
case 'K':
|
case 'K':
|
||||||
case 'N':
|
case 'N':
|
||||||
case 'U':
|
case 'U':
|
||||||
return E_TV_TYPE_NTSC;
|
return TV_NTSC;
|
||||||
case 'B':
|
case 'B':
|
||||||
return E_TV_TYPE_MPAL;
|
return TV_MPAL;
|
||||||
default:
|
default:
|
||||||
return E_TV_TYPE_UNKNOWN;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -78,7 +81,7 @@ void boot(cart_header_t *cart_header, uint16_t cic_seed, tv_type_t tv_type, uint
|
|||||||
(cic_seed == crc32_to_cic_seed[8].cic_seed) ||
|
(cic_seed == crc32_to_cic_seed[8].cic_seed) ||
|
||||||
(cic_seed == crc32_to_cic_seed[9].cic_seed)
|
(cic_seed == crc32_to_cic_seed[9].cic_seed)
|
||||||
);
|
);
|
||||||
tv_type_t os_tv_type = tv_type == E_TV_TYPE_UNKNOWN ? OS_BOOT_CONFIG->tv_type : tv_type;
|
tv_type_t os_tv_type = tv_type < 0 ? OS_BOOT_CONFIG->tv_type : tv_type;
|
||||||
|
|
||||||
volatile uint64_t gpr_regs[32];
|
volatile uint64_t gpr_regs[32];
|
||||||
|
|
||||||
@ -134,7 +137,7 @@ void boot(cart_header_t *cart_header, uint16_t cic_seed, tv_type_t tv_type, uint
|
|||||||
gpr_regs[CPU_REG_S6] = BOOT_SEED_IPL3(cic_seed);
|
gpr_regs[CPU_REG_S6] = BOOT_SEED_IPL3(cic_seed);
|
||||||
gpr_regs[CPU_REG_S7] = BOOT_SEED_OS_VERSION(cic_seed);
|
gpr_regs[CPU_REG_S7] = BOOT_SEED_OS_VERSION(cic_seed);
|
||||||
gpr_regs[CPU_REG_SP] = CPU_ADDRESS_IN_REG(SP_MEM->imem[ARRAY_ITEMS(SP_MEM->imem) - 4]);
|
gpr_regs[CPU_REG_SP] = CPU_ADDRESS_IN_REG(SP_MEM->imem[ARRAY_ITEMS(SP_MEM->imem) - 4]);
|
||||||
gpr_regs[CPU_REG_RA] = CPU_ADDRESS_IN_REG(SP_MEM->imem[(os_tv_type == E_TV_TYPE_PAL) ? 341 : 340]);
|
gpr_regs[CPU_REG_RA] = CPU_ADDRESS_IN_REG(SP_MEM->imem[(os_tv_type == TV_PAL) ? 341 : 340]);
|
||||||
|
|
||||||
__asm__ (
|
__asm__ (
|
||||||
".set noat \n\t"
|
".set noat \n\t"
|
||||||
|
@ -5,18 +5,6 @@
|
|||||||
#include "platform.h"
|
#include "platform.h"
|
||||||
|
|
||||||
|
|
||||||
struct crc32_to_cic_seed {
|
|
||||||
uint32_t ipl3_crc32;
|
|
||||||
uint16_t cic_seed;
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef enum tv_type_e {
|
|
||||||
E_TV_TYPE_PAL,
|
|
||||||
E_TV_TYPE_NTSC,
|
|
||||||
E_TV_TYPE_MPAL,
|
|
||||||
E_TV_TYPE_UNKNOWN,
|
|
||||||
} tv_type_t;
|
|
||||||
|
|
||||||
struct cart_header_s {
|
struct cart_header_s {
|
||||||
uint32_t pi_conf;
|
uint32_t pi_conf;
|
||||||
uint32_t clock_rate;
|
uint32_t clock_rate;
|
||||||
|
@ -1,45 +0,0 @@
|
|||||||
#include <stdio.h>
|
|
||||||
|
|
||||||
#include "error_display.h"
|
|
||||||
|
|
||||||
|
|
||||||
void error_display_and_halt(menu_load_error_t error, const char *path) {
|
|
||||||
init_interrupts();
|
|
||||||
|
|
||||||
display_init(RESOLUTION_320x240, DEPTH_32_BPP, 2, GAMMA_NONE, ANTIALIAS_RESAMPLE);
|
|
||||||
|
|
||||||
console_init();
|
|
||||||
console_set_render_mode(RENDER_MANUAL);
|
|
||||||
console_clear();
|
|
||||||
|
|
||||||
printf("SC64 Bootloader ver. %d.%02d error:\n\n%2d: ", BOOTLOADER_VERSION_MAJOR, BOOTLOADER_VERSION_MINOR, error);
|
|
||||||
|
|
||||||
switch (error) {
|
|
||||||
case E_MENU_OK:
|
|
||||||
printf("No error :O");
|
|
||||||
break;
|
|
||||||
case E_MENU_ERROR_NOT_SC64:
|
|
||||||
printf("SummerCart64 not detected");
|
|
||||||
break;
|
|
||||||
case E_MENU_ERROR_NO_CARD:
|
|
||||||
printf("SD Card not detected");
|
|
||||||
break;
|
|
||||||
case E_MENU_ERROR_NO_FILESYSTEM:
|
|
||||||
printf("No filesystem (FAT or exFAT)\nfound on SD Card");
|
|
||||||
break;
|
|
||||||
case E_MENU_ERROR_NO_FILE:
|
|
||||||
printf("Unable to locate menu file:\n(%s)", path);
|
|
||||||
break;
|
|
||||||
case E_MENU_ERROR_READ_ERROR:
|
|
||||||
printf("Error while reading data from\nSD Card");
|
|
||||||
break;
|
|
||||||
case E_MENU_ERROR_OTHER_ERROR:
|
|
||||||
default:
|
|
||||||
printf("Unknown error");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
console_render();
|
|
||||||
|
|
||||||
while (1);
|
|
||||||
}
|
|
@ -1,8 +1,5 @@
|
|||||||
#ifndef ERROR_DISPLAY_H__
|
#ifndef ERRORS_H__
|
||||||
#define ERROR_DISPLAY_H__
|
#define ERRORS_H__
|
||||||
|
|
||||||
|
|
||||||
#include "platform.h"
|
|
||||||
|
|
||||||
|
|
||||||
typedef enum menu_load_error_e {
|
typedef enum menu_load_error_e {
|
||||||
@ -13,10 +10,8 @@ typedef enum menu_load_error_e {
|
|||||||
E_MENU_ERROR_NO_FILE,
|
E_MENU_ERROR_NO_FILE,
|
||||||
E_MENU_ERROR_READ_ERROR,
|
E_MENU_ERROR_READ_ERROR,
|
||||||
E_MENU_ERROR_OTHER_ERROR,
|
E_MENU_ERROR_OTHER_ERROR,
|
||||||
|
E_MENU_END,
|
||||||
} menu_load_error_t;
|
} menu_load_error_t;
|
||||||
|
|
||||||
|
|
||||||
void error_display_and_halt(menu_load_error_t error, const char *path);
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
@ -48,6 +48,14 @@ DRESULT disk_read(BYTE pdrv, BYTE *buff, LBA_t sector, UINT count) {
|
|||||||
return RES_OK;
|
return RES_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if !FF_FS_READONLY
|
||||||
|
|
||||||
|
DRESULT disk_write (BYTE pdrv, const BYTE* buff, LBA_t sector, UINT count) {
|
||||||
|
return RES_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
DRESULT disk_ioctl(BYTE pdrv, BYTE cmd, void *buff) {
|
DRESULT disk_ioctl(BYTE pdrv, BYTE cmd, void *buff) {
|
||||||
return RES_PARERR;
|
return RES_PARERR;
|
||||||
}
|
}
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
/ Function Configurations
|
/ Function Configurations
|
||||||
/---------------------------------------------------------------------------*/
|
/---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
#define FF_FS_READONLY 1
|
#define FF_FS_READONLY 0
|
||||||
/* This option switches read-only configuration. (0:Read/Write or 1:Read-only)
|
/* This option switches read-only configuration. (0:Read/Write or 1:Read-only)
|
||||||
/ Read-only configuration removes writing API functions, f_write(), f_sync(),
|
/ Read-only configuration removes writing API functions, f_write(), f_sync(),
|
||||||
/ f_unlink(), f_mkdir(), f_chmod(), f_rename(), f_truncate(), f_getfree()
|
/ f_unlink(), f_mkdir(), f_chmod(), f_rename(), f_truncate(), f_getfree()
|
||||||
|
106
sw/bootloader/src/loader/loader.c
Normal file
106
sw/bootloader/src/loader/loader.c
Normal file
@ -0,0 +1,106 @@
|
|||||||
|
#include <libdragon.h>
|
||||||
|
|
||||||
|
#include "platform.h"
|
||||||
|
#include "assets/assets.h"
|
||||||
|
|
||||||
|
#include "loader.h"
|
||||||
|
|
||||||
|
|
||||||
|
#define X_OFFSET (24)
|
||||||
|
#define Y_OFFSET (16)
|
||||||
|
#define Y_PADDING (12)
|
||||||
|
|
||||||
|
#define LAST_CHAR(s) (sizeof(s) - 1)
|
||||||
|
#define EDIT_CHAR(s, n) s[(n) >= 0 ? 0 : LAST_CHAR((s)) + (n)]
|
||||||
|
#define NTOA(n) ('0' + ((n) % 10))
|
||||||
|
|
||||||
|
|
||||||
|
static char version_string[] = "SC64 Bootloader ver. X.X";
|
||||||
|
static char error_number_string[] = "ERROR X";
|
||||||
|
static const char *error_strings[] = {
|
||||||
|
"No error :O",
|
||||||
|
"SummerCart64 not detected",
|
||||||
|
"SD Card not detected",
|
||||||
|
"No filesystem (FAT or exFAT)\nfound on SD Card",
|
||||||
|
"Unable to locate menu file",
|
||||||
|
"Error while reading data from\nSD Card",
|
||||||
|
"Unknown error",
|
||||||
|
};
|
||||||
|
|
||||||
|
static int x_offset = X_OFFSET;
|
||||||
|
static int y_offset = Y_OFFSET;
|
||||||
|
|
||||||
|
|
||||||
|
static display_context_t loader_get_display(void) {
|
||||||
|
display_context_t display;
|
||||||
|
|
||||||
|
do {
|
||||||
|
display = display_lock();
|
||||||
|
} while (!display);
|
||||||
|
|
||||||
|
x_offset = X_OFFSET;
|
||||||
|
y_offset = Y_OFFSET;
|
||||||
|
|
||||||
|
return display;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void loader_draw_version_and_logo(display_context_t display) {
|
||||||
|
EDIT_CHAR(version_string, -3) = NTOA(BOOTLOADER_VERSION_MAJOR);
|
||||||
|
EDIT_CHAR(version_string, -1) = NTOA(BOOTLOADER_VERSION_MINOR);
|
||||||
|
graphics_draw_text(display, x_offset, y_offset, version_string);
|
||||||
|
y_offset += Y_PADDING;
|
||||||
|
|
||||||
|
sprite_t *logo = _binary_build_sc64_logo_sprite_start;
|
||||||
|
|
||||||
|
int center_x = (320 / 2) - (logo->width / 2);
|
||||||
|
int center_y = (240 / 2) - (logo->height / 2);
|
||||||
|
|
||||||
|
graphics_draw_sprite(display, center_x, center_y, logo);
|
||||||
|
}
|
||||||
|
|
||||||
|
void loader_init(void) {
|
||||||
|
display_context_t display;
|
||||||
|
|
||||||
|
init_interrupts();
|
||||||
|
|
||||||
|
audio_init(44100, 2);
|
||||||
|
audio_write_silence();
|
||||||
|
|
||||||
|
display_init(RESOLUTION_320x240, DEPTH_32_BPP, 2, GAMMA_NONE, ANTIALIAS_OFF);
|
||||||
|
|
||||||
|
display = loader_get_display();
|
||||||
|
|
||||||
|
loader_draw_version_and_logo(display);
|
||||||
|
|
||||||
|
display_show(display);
|
||||||
|
}
|
||||||
|
|
||||||
|
void loader_cleanup(void) {
|
||||||
|
audio_close();
|
||||||
|
display_close();
|
||||||
|
}
|
||||||
|
|
||||||
|
void loader_display_error_and_halt(menu_load_error_t error, const char *path) {
|
||||||
|
display_context_t display;
|
||||||
|
|
||||||
|
display = loader_get_display();
|
||||||
|
|
||||||
|
loader_draw_version_and_logo(display);
|
||||||
|
|
||||||
|
EDIT_CHAR(error_number_string, -1) = NTOA(error);
|
||||||
|
graphics_draw_text(display, x_offset, y_offset, error_number_string);
|
||||||
|
y_offset += Y_PADDING;
|
||||||
|
|
||||||
|
int error_string_index = error >= E_MENU_END ? (E_MENU_END - 1) : error;
|
||||||
|
const char *error_string = error_strings[error_string_index];
|
||||||
|
graphics_draw_text(display, x_offset, y_offset, error_string);
|
||||||
|
y_offset += Y_PADDING;
|
||||||
|
|
||||||
|
if (error == E_MENU_ERROR_NO_FILE) {
|
||||||
|
graphics_draw_text(display, x_offset, y_offset, path);
|
||||||
|
}
|
||||||
|
|
||||||
|
display_show(display);
|
||||||
|
|
||||||
|
while (1);
|
||||||
|
}
|
13
sw/bootloader/src/loader/loader.h
Normal file
13
sw/bootloader/src/loader/loader.h
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
#ifndef LOADER_H__
|
||||||
|
#define LOADER_H__
|
||||||
|
|
||||||
|
|
||||||
|
#include "errors.h"
|
||||||
|
|
||||||
|
|
||||||
|
void loader_init(void);
|
||||||
|
void loader_cleanup(void);
|
||||||
|
void loader_display_error_and_halt(menu_load_error_t error, const char *path);
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
@ -1,16 +1,17 @@
|
|||||||
#include "boot.h"
|
#include "boot/boot.h"
|
||||||
#include "error_display.h"
|
#include "loader/loader.h"
|
||||||
|
#include "sc64/sc64.h"
|
||||||
#include "sc64.h"
|
#include "sc64/sc64_sd_fs.h"
|
||||||
#include "sc64_sd_fs.h"
|
|
||||||
|
|
||||||
|
|
||||||
static const char *MENU_FILE_PATH = "SC64/MENU.z64";
|
static const char *MENU_FILE_PATH = "SC64/MENU.z64";
|
||||||
|
|
||||||
|
|
||||||
int main(void) {
|
int main(void) {
|
||||||
|
loader_init();
|
||||||
|
|
||||||
if (sc64_get_version() != SC64_CART_VERSION_A) {
|
if (sc64_get_version() != SC64_CART_VERSION_A) {
|
||||||
error_display_and_halt(E_MENU_ERROR_NOT_SC64, MENU_FILE_PATH);
|
loader_display_error_and_halt(E_MENU_ERROR_NOT_SC64, "");
|
||||||
}
|
}
|
||||||
|
|
||||||
sc64_enable_rom_switch();
|
sc64_enable_rom_switch();
|
||||||
@ -50,7 +51,7 @@ int main(void) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (error != E_MENU_OK) {
|
if (error != E_MENU_OK) {
|
||||||
error_display_and_halt(error, MENU_FILE_PATH);
|
loader_display_error_and_halt(error, MENU_FILE_PATH);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -70,5 +71,7 @@ int main(void) {
|
|||||||
tv_type = boot_get_tv_type(cart_header);
|
tv_type = boot_get_tv_type(cart_header);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
loader_cleanup();
|
||||||
|
|
||||||
boot(cart_header, cic_seed, tv_type, ddipl_override);
|
boot(cart_header, cic_seed, tv_type, ddipl_override);
|
||||||
}
|
}
|
||||||
|
@ -11,10 +11,6 @@
|
|||||||
#define BOOTLOADER_VERSION_MAJOR (1)
|
#define BOOTLOADER_VERSION_MAJOR (1)
|
||||||
#define BOOTLOADER_VERSION_MINOR (0)
|
#define BOOTLOADER_VERSION_MINOR (0)
|
||||||
|
|
||||||
|
|
||||||
#define TRUE (1)
|
|
||||||
#define FALSE (0)
|
|
||||||
|
|
||||||
#define __IO volatile
|
#define __IO volatile
|
||||||
|
|
||||||
typedef uint32_t reg_t;
|
typedef uint32_t reg_t;
|
||||||
|
@ -27,7 +27,7 @@ typedef struct sc64_cart_registers {
|
|||||||
__IO reg_t USB_DMA_LEN; // USB transfer length for DMA to PC
|
__IO reg_t USB_DMA_LEN; // USB transfer length for DMA to PC
|
||||||
__IO reg_t DDIPL_ADDR; // 64 Disk Drive IPL location in SDRAM
|
__IO reg_t DDIPL_ADDR; // 64 Disk Drive IPL location in SDRAM
|
||||||
__IO reg_t SRAM_ADDR; // SRAM save emulation location in SDRAM
|
__IO reg_t SRAM_ADDR; // SRAM save emulation location in SDRAM
|
||||||
__IO reg_t __reserved[1015];
|
__IO reg_t __unused[1015];
|
||||||
__IO reg_t USB_FIFO[1024]; // USB data from PC read FIFO memory end
|
__IO reg_t USB_FIFO[1024]; // USB data from PC read FIFO memory end
|
||||||
} sc64_cart_registers_t;
|
} sc64_cart_registers_t;
|
||||||
|
|
||||||
@ -35,6 +35,7 @@ typedef struct sc64_cart_registers {
|
|||||||
|
|
||||||
#define SC64_CART ((__IO sc64_cart_registers_t *) SC64_CART_BASE)
|
#define SC64_CART ((__IO sc64_cart_registers_t *) SC64_CART_BASE)
|
||||||
|
|
||||||
|
|
||||||
#define SC64_CART_SCR_FLASHRAM_ENABLE (1 << 9)
|
#define SC64_CART_SCR_FLASHRAM_ENABLE (1 << 9)
|
||||||
#define SC64_CART_SCR_SRAM_768K_MODE (1 << 8)
|
#define SC64_CART_SCR_SRAM_768K_MODE (1 << 8)
|
||||||
#define SC64_CART_SCR_SRAM_ENABLE (1 << 7)
|
#define SC64_CART_SCR_SRAM_ENABLE (1 << 7)
|
||||||
@ -52,6 +53,7 @@ typedef struct sc64_cart_registers {
|
|||||||
#define SC64_CART_BOOT_DDIPL_OVERRIDE (1 << 12)
|
#define SC64_CART_BOOT_DDIPL_OVERRIDE (1 << 12)
|
||||||
#define SC64_CART_BOOT_TV_TYPE_BIT (10)
|
#define SC64_CART_BOOT_TV_TYPE_BIT (10)
|
||||||
#define SC64_CART_BOOT_TV_TYPE_MASK (0x3 << SC64_CART_BOOT_TV_TYPE_BIT)
|
#define SC64_CART_BOOT_TV_TYPE_MASK (0x3 << SC64_CART_BOOT_TV_TYPE_BIT)
|
||||||
|
#define SC64_CART_BOOT_ROM_LOADED (1 << 9)
|
||||||
#define SC64_CART_BOOT_CIC_SEED_BIT (0)
|
#define SC64_CART_BOOT_CIC_SEED_BIT (0)
|
||||||
#define SC64_CART_BOOT_CIC_SEED_MASK (0x1FF << SC64_CART_BOOT_CIC_SEED_BIT)
|
#define SC64_CART_BOOT_CIC_SEED_MASK (0x1FF << SC64_CART_BOOT_CIC_SEED_BIT)
|
||||||
|
|
||||||
@ -123,6 +125,7 @@ typedef struct sc64_sd_registers_s {
|
|||||||
|
|
||||||
#define SC64_SD ((__IO sc64_sd_registers_t *) SC64_SD_BASE)
|
#define SC64_SD ((__IO sc64_sd_registers_t *) SC64_SD_BASE)
|
||||||
|
|
||||||
|
|
||||||
#define SC64_SD_SCR_DAT_WIDTH (1 << 2)
|
#define SC64_SD_SCR_DAT_WIDTH (1 << 2)
|
||||||
#define SC64_SD_SCR_CLK_MASK (0x3 << 0)
|
#define SC64_SD_SCR_CLK_MASK (0x3 << 0)
|
||||||
#define SC64_SD_SCR_CLK_STOP (0 << 0)
|
#define SC64_SD_SCR_CLK_STOP (0 << 0)
|
||||||
@ -130,43 +133,53 @@ typedef struct sc64_sd_registers_s {
|
|||||||
#define SC64_SD_SCR_CLK_25_MHZ (2 << 0)
|
#define SC64_SD_SCR_CLK_25_MHZ (2 << 0)
|
||||||
#define SC64_SD_SCR_CLK_50_MHZ (3 << 0)
|
#define SC64_SD_SCR_CLK_50_MHZ (3 << 0)
|
||||||
|
|
||||||
#define SC64_SD_CMD_RESPONSE_CRC_ERROR (1 << 10)
|
|
||||||
#define SC64_SD_CMD_TIMEOUT (1 << 9)
|
#define SC64_SD_CMD_RESPONSE_CRC_ERROR (1 << 8)
|
||||||
|
#define SC64_SD_CMD_TIMEOUT (1 << 7)
|
||||||
|
#define SC64_SD_CMD_BUSY (1 << 6)
|
||||||
|
#define SC64_SD_CMD_INDEX_GET(cmd) ((cmd) & 0x3F)
|
||||||
|
|
||||||
#define SC64_SD_CMD_SKIP_RESPONSE (1 << 8)
|
#define SC64_SD_CMD_SKIP_RESPONSE (1 << 8)
|
||||||
#define SC64_SD_CMD_LONG_RESPONSE (1 << 7)
|
#define SC64_SD_CMD_LONG_RESPONSE (1 << 7)
|
||||||
#define SC64_SD_CMD_BUSY (1 << 6)
|
|
||||||
#define SC64_SD_CMD_START (1 << 6)
|
#define SC64_SD_CMD_START (1 << 6)
|
||||||
#define SC64_SD_CMD_INDEX_GET(cmd) ((cmd) & 0x3F)
|
|
||||||
#define SC64_SD_CMD_INDEX(i) ((i) & 0x3F)
|
#define SC64_SD_CMD_INDEX(i) ((i) & 0x3F)
|
||||||
|
|
||||||
#define SC64_SD_DAT_RX_FIFO_FULL (1 << 31)
|
|
||||||
#define SC64_SD_DAT_RX_FIFO_ITEMS_GET(dat) (((dat) >> 24) & 0xFF)
|
#define SC64_SD_DAT_TX_FIFO_ITEMS_GET(dat) (((dat) >> 17) & 0x1FF)
|
||||||
#define SC64_SD_DAT_TX_FIFO_FULL (1 << 23)
|
#define SC64_SD_DAT_TX_FIFO_FULL (1 << 16)
|
||||||
#define SC64_SD_DAT_TX_FIFO_EMPTY (1 << 22)
|
#define SC64_SD_DAT_TX_FIFO_EMPTY (1 << 15)
|
||||||
#define SC64_SD_DAT_TX_FIFO_FLUSH (1 << 22)
|
#define SC64_SD_DAT_TX_FIFO_UNDERRUN (1 << 14)
|
||||||
#define SC64_SD_DAT_RX_FIFO_OVERRUN (1 << 21)
|
#define SC64_SD_DAT_RX_FIFO_ITEMS_GET(dat) (((dat) >> 5) & 0x1FF)
|
||||||
#define SC64_SD_DAT_RX_FIFO_FLUSH (1 << 21)
|
#define SC64_SD_DAT_RX_FIFO_FULL (1 << 4)
|
||||||
#define SC64_SD_DAT_NUM_BLOCKS_GET(dat) ((((dat) >> 10) & 0x7FF) + 1)
|
#define SC64_SD_DAT_RX_FIFO_EMPTY (1 << 3)
|
||||||
#define SC64_SD_DAT_NUM_BLOCKS(nb) ((((nb) - 1) & 0x7FF) << 10)
|
#define SC64_SD_DAT_RX_FIFO_OVERRUN (1 << 2)
|
||||||
#define SC64_SD_DAT_BLOCK_SIZE_GET(dat) (((((dat) >> 3) & 0x7F) + 1) * 4)
|
#define SC64_SD_DAT_CRC_ERROR (1 << 1)
|
||||||
|
#define SC64_SD_DAT_BUSY (1 << 0)
|
||||||
|
|
||||||
|
#define SC64_SD_DAT_TX_FIFO_FLUSH (1 << 19)
|
||||||
|
#define SC64_SD_DAT_RX_FIFO_FLUSH (1 << 18)
|
||||||
|
#define SC64_SD_DAT_NUM_BLOCKS(nb) ((((nb) - 1) & 0xFF) << 10)
|
||||||
#define SC64_SD_DAT_BLOCK_SIZE(bs) (((((bs) / 4) - 1) & 0x7F) << 3)
|
#define SC64_SD_DAT_BLOCK_SIZE(bs) (((((bs) / 4) - 1) & 0x7F) << 3)
|
||||||
#define SC64_SD_DAT_DIRECTION (1 << 2)
|
#define SC64_SD_DAT_DIRECTION (1 << 2)
|
||||||
#define SC64_SD_DAT_CRC_ERROR (1 << 1)
|
|
||||||
#define SC64_SD_DAT_STOP (1 << 1)
|
#define SC64_SD_DAT_STOP (1 << 1)
|
||||||
#define SC64_SD_DAT_BUSY (1 << 0)
|
|
||||||
#define SC64_SD_DAT_START (1 << 0)
|
#define SC64_SD_DAT_START (1 << 0)
|
||||||
|
|
||||||
|
|
||||||
|
#define SC64_SD_DMA_SCR_BUSY (1 << 0)
|
||||||
|
|
||||||
#define SC64_SD_DMA_SCR_DIRECTION (1 << 2)
|
#define SC64_SD_DMA_SCR_DIRECTION (1 << 2)
|
||||||
#define SC64_SD_DMA_SCR_STOP (1 << 1)
|
#define SC64_SD_DMA_SCR_STOP (1 << 1)
|
||||||
#define SC64_SD_DMA_SCR_BUSY (1 << 0)
|
|
||||||
#define SC64_SD_DMA_SCR_START (1 << 0)
|
#define SC64_SD_DMA_SCR_START (1 << 0)
|
||||||
|
|
||||||
|
|
||||||
#define SC64_SD_DMA_ADDR_GET(addr) ((addr) & 0x3FFFFFC)
|
#define SC64_SD_DMA_ADDR_GET(addr) ((addr) & 0x3FFFFFC)
|
||||||
#define SC64_SD_DMA_BANK_GET(addr) (((addr) >> 28) & 0xF)
|
#define SC64_SD_DMA_BANK_GET(addr) (((addr) >> 28) & 0xF)
|
||||||
|
|
||||||
#define SC64_SD_DMA_BANK_ADDR(b, a) ((((b) & 0xF) << 28) | ((a) & 0x3FFFFFC))
|
#define SC64_SD_DMA_BANK_ADDR(b, a) ((((b) & 0xF) << 28) | ((a) & 0x3FFFFFC))
|
||||||
|
|
||||||
#define SC64_SD_DMA_LEN_GET(len) (((len) & 0x3FFFF) * 4)
|
#define SC64_SD_DMA_LEN_GET(len) (((len) & 0x7FFF) * 4)
|
||||||
#define SC64_SD_DMA_LEN(l) ((((l) / 4) - 1) & 0x3FFFF)
|
|
||||||
|
#define SC64_SD_DMA_LEN(l) ((((l) / 4) - 1) & 0x7FFF)
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -15,6 +15,8 @@
|
|||||||
|
|
||||||
#define SD_BLOCK_SIZE (512)
|
#define SD_BLOCK_SIZE (512)
|
||||||
|
|
||||||
|
#define MAX_NUM_BLOCKS (256)
|
||||||
|
|
||||||
|
|
||||||
typedef enum sc64_sd_clock_e {
|
typedef enum sc64_sd_clock_e {
|
||||||
CLOCK_STOP,
|
CLOCK_STOP,
|
||||||
@ -86,6 +88,7 @@ static void sc64_sd_set_dat_width(sc64_sd_dat_width_t dat_width) {
|
|||||||
static void sc64_sd_hw_init(void) {
|
static void sc64_sd_hw_init(void) {
|
||||||
sc64_enable_sd();
|
sc64_enable_sd();
|
||||||
|
|
||||||
|
while (platform_pi_io_read(&SC64_SD->CMD) & SC64_SD_CMD_BUSY);
|
||||||
platform_pi_io_write(&SC64_SD->DMA_SCR, SC64_SD_DMA_SCR_STOP);
|
platform_pi_io_write(&SC64_SD->DMA_SCR, SC64_SD_DMA_SCR_STOP);
|
||||||
platform_pi_io_write(&SC64_SD->DAT, SC64_SD_DAT_TX_FIFO_FLUSH | SC64_SD_DAT_RX_FIFO_FLUSH | SC64_SD_DAT_STOP);
|
platform_pi_io_write(&SC64_SD->DAT, SC64_SD_DAT_TX_FIFO_FLUSH | SC64_SD_DAT_RX_FIFO_FLUSH | SC64_SD_DAT_STOP);
|
||||||
platform_pi_io_write(&SC64_SD->SCR, 0);
|
platform_pi_io_write(&SC64_SD->SCR, 0);
|
||||||
@ -156,7 +159,7 @@ static void sc64_sd_dat_prepare(size_t num_blocks, size_t block_size, sc64_sd_da
|
|||||||
platform_pi_io_write(&SC64_SD->DAT, (
|
platform_pi_io_write(&SC64_SD->DAT, (
|
||||||
SC64_SD_DAT_NUM_BLOCKS(num_blocks) |
|
SC64_SD_DAT_NUM_BLOCKS(num_blocks) |
|
||||||
SC64_SD_DAT_BLOCK_SIZE(block_size) |
|
SC64_SD_DAT_BLOCK_SIZE(block_size) |
|
||||||
(direction ? SC64_SD_DAT_DIRECTION : 0) |
|
((direction == DAT_DIR_TX) ? SC64_SD_DAT_DIRECTION : 0) |
|
||||||
SC64_SD_DAT_START
|
SC64_SD_DAT_START
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
@ -179,7 +182,7 @@ static sc64_sd_err_t sc64_sd_dat_read(size_t block_size, void *buffer) {
|
|||||||
if (SC64_SD_DAT_RX_FIFO_ITEMS_GET(reg) >= block_size) {
|
if (SC64_SD_DAT_RX_FIFO_ITEMS_GET(reg) >= block_size) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} while ((reg & SC64_SD_DAT_BUSY) && (timeout--));
|
} while ((reg & SC64_SD_DAT_BUSY) && (--timeout));
|
||||||
|
|
||||||
if (reg & SC64_SD_DAT_CRC_ERROR) {
|
if (reg & SC64_SD_DAT_CRC_ERROR) {
|
||||||
return E_CRC_ERROR;
|
return E_CRC_ERROR;
|
||||||
@ -350,7 +353,7 @@ sc64_sd_err_t sc64_sd_read_sectors(uint32_t starting_sector, size_t count, void
|
|||||||
timeout = 100000;
|
timeout = 100000;
|
||||||
do {
|
do {
|
||||||
reg = platform_pi_io_read(&SC64_SD->DAT);
|
reg = platform_pi_io_read(&SC64_SD->DAT);
|
||||||
} while ((reg & SC64_SD_DAT_BUSY) && (timeout--));
|
} while ((reg & SC64_SD_DAT_BUSY) && (--timeout));
|
||||||
|
|
||||||
if (reg & SC64_SD_DAT_CRC_ERROR) {
|
if (reg & SC64_SD_DAT_CRC_ERROR) {
|
||||||
return E_CRC_ERROR;
|
return E_CRC_ERROR;
|
||||||
@ -404,7 +407,7 @@ sc64_sd_err_t sc64_sd_read_sectors_dma(uint32_t starting_sector, size_t count, u
|
|||||||
current_address = address;
|
current_address = address;
|
||||||
|
|
||||||
do {
|
do {
|
||||||
num_blocks = (sectors_left > 2048) ? 2048 : sectors_left;
|
num_blocks = (sectors_left > MAX_NUM_BLOCKS) ? MAX_NUM_BLOCKS : sectors_left;
|
||||||
|
|
||||||
platform_pi_io_write(&SC64_SD->DMA_ADDR, SC64_SD_DMA_BANK_ADDR(bank, current_address));
|
platform_pi_io_write(&SC64_SD->DMA_ADDR, SC64_SD_DMA_BANK_ADDR(bank, current_address));
|
||||||
platform_pi_io_write(&SC64_SD->DMA_LEN, SC64_SD_DMA_LEN(num_blocks * SD_BLOCK_SIZE));
|
platform_pi_io_write(&SC64_SD->DMA_LEN, SC64_SD_DMA_LEN(num_blocks * SD_BLOCK_SIZE));
|
||||||
@ -421,7 +424,7 @@ sc64_sd_err_t sc64_sd_read_sectors_dma(uint32_t starting_sector, size_t count, u
|
|||||||
timeout = 1000000;
|
timeout = 1000000;
|
||||||
do {
|
do {
|
||||||
reg = platform_pi_io_read(&SC64_SD->DAT);
|
reg = platform_pi_io_read(&SC64_SD->DAT);
|
||||||
} while ((reg & SC64_SD_DAT_BUSY) && (timeout--));
|
} while ((reg & SC64_SD_DAT_BUSY) && (--timeout));
|
||||||
|
|
||||||
error = sc64_sd_cmd_send(12, 0, NO_FLAGS, &response);
|
error = sc64_sd_cmd_send(12, 0, NO_FLAGS, &response);
|
||||||
if (error != E_OK) {
|
if (error != E_OK) {
|
||||||
|
Loading…
Reference in New Issue
Block a user