PicoSoC QSPI and XIP now working (tested in hardware)

This commit is contained in:
Clifford Wolf 2017-09-19 15:32:41 +02:00
parent 2cc1256ce7
commit 7639e6ebac
4 changed files with 54 additions and 26 deletions

View File

@ -14,7 +14,7 @@ extern uint32_t sram;
extern uint32_t flashio_worker_begin; extern uint32_t flashio_worker_begin;
extern uint32_t flashio_worker_end; extern uint32_t flashio_worker_end;
void flashio(uint8_t *data, int len) void flashio(uint8_t *data, int len, uint8_t wrencmd)
{ {
uint32_t func[&flashio_worker_end - &flashio_worker_begin]; uint32_t func[&flashio_worker_end - &flashio_worker_begin];
@ -24,7 +24,17 @@ void flashio(uint8_t *data, int len)
while (src_ptr != &flashio_worker_end) while (src_ptr != &flashio_worker_end)
*(dst_ptr++) = *(src_ptr++); *(dst_ptr++) = *(src_ptr++);
((void(*)(uint8_t*, int))func)(data, len); ((void(*)(uint8_t*, uint32_t, uint32_t))func)(data, len, wrencmd);
}
void set_quad_spi_flag()
{
uint32_t addr = 0x800002;
uint8_t buffer_rd[6] = {0x65, addr >> 16, addr >> 8, addr, 0, 0};
flashio(buffer_rd, 6, 0);
uint8_t buffer_wr[5] = {0x71, addr >> 16, addr >> 8, addr, buffer_rd[5] | 2};
flashio(buffer_wr, 5, 0x06);
} }
// -------------------------------------------------------- // --------------------------------------------------------
@ -114,10 +124,10 @@ char getchar()
// -------------------------------------------------------- // --------------------------------------------------------
void cmd_read_spi_flash_id() void cmd_read_flash_id()
{ {
uint8_t buffer[17] = { 0x9F, /* zeros */ }; uint8_t buffer[17] = { 0x9F, /* zeros */ };
flashio(buffer, 17); flashio(buffer, 17, 0);
for (int i = 1; i <= 16; i++) { for (int i = 1; i <= 16; i++) {
putchar(' '); putchar(' ');
@ -128,10 +138,10 @@ void cmd_read_spi_flash_id()
// -------------------------------------------------------- // --------------------------------------------------------
uint8_t cmd_read_spi_flash_regs_print(uint32_t addr, const char *name) uint8_t cmd_read_flash_regs_print(uint32_t addr, const char *name)
{ {
uint8_t buffer[6] = {0x65, addr >> 16, addr >> 8, addr, 0, 0}; uint8_t buffer[6] = {0x65, addr >> 16, addr >> 8, addr, 0, 0};
flashio(buffer, 6); flashio(buffer, 6, 0);
print("0x"); print("0x");
print_hex(addr, 6); print_hex(addr, 6);
@ -144,15 +154,15 @@ uint8_t cmd_read_spi_flash_regs_print(uint32_t addr, const char *name)
return buffer[5]; return buffer[5];
} }
void cmd_read_spi_flash_regs() void cmd_read_flash_regs()
{ {
print("\n"); print("\n");
uint8_t sr1v = cmd_read_spi_flash_regs_print(0x800000, "SR1V"); uint8_t sr1v = cmd_read_flash_regs_print(0x800000, "SR1V");
uint8_t sr2v = cmd_read_spi_flash_regs_print(0x800001, "SR2V"); uint8_t sr2v = cmd_read_flash_regs_print(0x800001, "SR2V");
uint8_t cr1v = cmd_read_spi_flash_regs_print(0x800002, "CR1V"); uint8_t cr1v = cmd_read_flash_regs_print(0x800002, "CR1V");
uint8_t cr2v = cmd_read_spi_flash_regs_print(0x800003, "CR2V"); uint8_t cr2v = cmd_read_flash_regs_print(0x800003, "CR2V");
uint8_t cr3v = cmd_read_spi_flash_regs_print(0x800004, "CR3V"); uint8_t cr3v = cmd_read_flash_regs_print(0x800004, "CR3V");
uint8_t vdlp = cmd_read_spi_flash_regs_print(0x800005, "VDLP"); uint8_t vdlp = cmd_read_flash_regs_print(0x800005, "VDLP");
} }
// -------------------------------------------------------- // --------------------------------------------------------
@ -212,6 +222,8 @@ void cmd_benchmark()
void main() void main()
{ {
reg_uart_clkdiv = 104; reg_uart_clkdiv = 104;
set_quad_spi_flag();
while (getchar_prompt("Press ENTER to continue..\n") != '\r') { /* wait */ } while (getchar_prompt("Press ENTER to continue..\n") != '\r') { /* wait */ }
print("\n"); print("\n");
@ -227,15 +239,15 @@ void main()
print("\n"); print("\n");
print("SPI State:\n"); print("SPI State:\n");
print(" LATENCY ");
print_dec((reg_spictrl >> 16) & 15);
print("\n");
print(" DDR "); print(" DDR ");
if ((reg_spictrl & (1 << 22)) != 0) if ((reg_spictrl & (1 << 22)) != 0)
print("ON"); print("ON\n");
else else
print("OFF"); print("OFF\n");
print(" (latency=");
print_dec((reg_spictrl >> 16) & 15);
print(")\n");
print(" QSPI "); print(" QSPI ");
if ((reg_spictrl & (1 << 21)) != 0) if ((reg_spictrl & (1 << 21)) != 0)
@ -271,10 +283,10 @@ void main()
switch (cmd) switch (cmd)
{ {
case '1': case '1':
cmd_read_spi_flash_id(); cmd_read_flash_id();
break; break;
case '2': case '2':
cmd_read_spi_flash_regs(); cmd_read_flash_regs();
break; break;
case '3': case '3':
reg_spictrl ^= 1 << 22; reg_spictrl ^= 1 << 22;

View File

@ -27,7 +27,7 @@ module testbench;
$dumpfile("testbench.vcd"); $dumpfile("testbench.vcd");
$dumpvars(0, testbench); $dumpvars(0, testbench);
repeat (100000) @(posedge clk); repeat (200000) @(posedge clk);
$finish; $finish;
end end

View File

@ -42,6 +42,7 @@ module spiflash (
inout io3 inout io3
); );
localparam verbose = 0; localparam verbose = 0;
localparam integer latency = 8;
reg [7:0] buffer; reg [7:0] buffer;
integer bitcount = 0; integer bitcount = 0;
@ -148,7 +149,7 @@ module spiflash (
if (bytecount == 5) begin if (bytecount == 5) begin
xip_cmd = (buffer == 8'h a5) ? spi_cmd : 8'h 00; xip_cmd = (buffer == 8'h a5) ? spi_cmd : 8'h 00;
mode = mode_qspi_wr; mode = mode_qspi_wr;
dummycount = 1; dummycount = latency;
end end
if (bytecount >= 5) begin if (bytecount >= 5) begin
@ -173,7 +174,7 @@ module spiflash (
if (bytecount == 5) begin if (bytecount == 5) begin
xip_cmd = (buffer == 8'h a5) ? spi_cmd : 8'h 00; xip_cmd = (buffer == 8'h a5) ? spi_cmd : 8'h 00;
mode = mode_qspi_ddr_wr; mode = mode_qspi_ddr_wr;
dummycount = 1; dummycount = latency;
end end
if (bytecount >= 5) begin if (bytecount >= 5) begin

View File

@ -45,6 +45,7 @@ j loop
flashio_worker_begin: flashio_worker_begin:
# a0 ... data pointer # a0 ... data pointer
# a1 ... data length # a1 ... data length
# a2 ... optional WREN cmd (0 = disable)
# address of SPI ctrl reg # address of SPI ctrl reg
li t0, 0x02000000 li t0, 0x02000000
@ -54,8 +55,22 @@ li t1, 0x120
sh t1, 0(t0) sh t1, 0(t0)
# Enable Manual SPI Ctrl # Enable Manual SPI Ctrl
li t1, 0x00 sb zero, 3(t0)
sb t1, 3(t0)
# Send optional WREN cmd
beqz a2, flashio_worker_L1
li t5, 8
andi t2, a2, 0xff
flashio_worker_L4:
srli t4, t2, 7
sb t4, 0(t0)
ori t4, t4, 0x10
sb t4, 0(t0)
slli t2, t2, 1
andi t2, t2, 0xff
addi t5, t5, -1
bnez t5, flashio_worker_L4
sb t1, 0(t0)
# SPI transfer # SPI transfer
flashio_worker_L1: flashio_worker_L1: