PicoSoC QSPI and XIP now working (tested in hardware)
This commit is contained in:
parent
2cc1256ce7
commit
7639e6ebac
|
@ -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;
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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:
|
||||||
|
|
Loading…
Reference in New Issue