aboutsummaryrefslogtreecommitdiffstats
path: root/picosoc
diff options
context:
space:
mode:
authorClifford Wolf <clifford@clifford.at>2017-09-19 15:32:41 +0200
committerClifford Wolf <clifford@clifford.at>2017-09-19 15:32:41 +0200
commit7639e6ebac26fafbff2c3e2a72e83cf5cd0c3a3e (patch)
treed344f2a29afb2d11890425ca52e87f5ad6812b88 /picosoc
parent2cc1256ce7aab8637d82d91506cdeb73d42604b2 (diff)
downloadpicorv32-7639e6ebac26fafbff2c3e2a72e83cf5cd0c3a3e.tar.gz
picorv32-7639e6ebac26fafbff2c3e2a72e83cf5cd0c3a3e.zip
PicoSoC QSPI and XIP now working (tested in hardware)
Diffstat (limited to 'picosoc')
-rw-r--r--picosoc/firmware.c54
-rw-r--r--picosoc/hx8kdemo_tb.v2
-rw-r--r--picosoc/spiflash.v5
-rw-r--r--picosoc/start.s19
4 files changed, 54 insertions, 26 deletions
diff --git a/picosoc/firmware.c b/picosoc/firmware.c
index 70ab5eb..ecc8657 100644
--- a/picosoc/firmware.c
+++ b/picosoc/firmware.c
@@ -14,7 +14,7 @@ extern uint32_t sram;
extern uint32_t flashio_worker_begin;
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];
@@ -24,7 +24,17 @@ void flashio(uint8_t *data, int len)
while (src_ptr != &flashio_worker_end)
*(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 */ };
- flashio(buffer, 17);
+ flashio(buffer, 17, 0);
for (int i = 1; i <= 16; i++) {
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};
- flashio(buffer, 6);
+ flashio(buffer, 6, 0);
print("0x");
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];
}
-void cmd_read_spi_flash_regs()
+void cmd_read_flash_regs()
{
print("\n");
- uint8_t sr1v = cmd_read_spi_flash_regs_print(0x800000, "SR1V");
- uint8_t sr2v = cmd_read_spi_flash_regs_print(0x800001, "SR2V");
- uint8_t cr1v = cmd_read_spi_flash_regs_print(0x800002, "CR1V");
- uint8_t cr2v = cmd_read_spi_flash_regs_print(0x800003, "CR2V");
- uint8_t cr3v = cmd_read_spi_flash_regs_print(0x800004, "CR3V");
- uint8_t vdlp = cmd_read_spi_flash_regs_print(0x800005, "VDLP");
+ uint8_t sr1v = cmd_read_flash_regs_print(0x800000, "SR1V");
+ uint8_t sr2v = cmd_read_flash_regs_print(0x800001, "SR2V");
+ uint8_t cr1v = cmd_read_flash_regs_print(0x800002, "CR1V");
+ uint8_t cr2v = cmd_read_flash_regs_print(0x800003, "CR2V");
+ uint8_t cr3v = cmd_read_flash_regs_print(0x800004, "CR3V");
+ uint8_t vdlp = cmd_read_flash_regs_print(0x800005, "VDLP");
}
// --------------------------------------------------------
@@ -212,6 +222,8 @@ void cmd_benchmark()
void main()
{
reg_uart_clkdiv = 104;
+ set_quad_spi_flag();
+
while (getchar_prompt("Press ENTER to continue..\n") != '\r') { /* wait */ }
print("\n");
@@ -227,15 +239,15 @@ void main()
print("\n");
print("SPI State:\n");
+ print(" LATENCY ");
+ print_dec((reg_spictrl >> 16) & 15);
+ print("\n");
+
print(" DDR ");
if ((reg_spictrl & (1 << 22)) != 0)
- print("ON");
+ print("ON\n");
else
- print("OFF");
-
- print(" (latency=");
- print_dec((reg_spictrl >> 16) & 15);
- print(")\n");
+ print("OFF\n");
print(" QSPI ");
if ((reg_spictrl & (1 << 21)) != 0)
@@ -271,10 +283,10 @@ void main()
switch (cmd)
{
case '1':
- cmd_read_spi_flash_id();
+ cmd_read_flash_id();
break;
case '2':
- cmd_read_spi_flash_regs();
+ cmd_read_flash_regs();
break;
case '3':
reg_spictrl ^= 1 << 22;
diff --git a/picosoc/hx8kdemo_tb.v b/picosoc/hx8kdemo_tb.v
index 585c8dd..83b1340 100644
--- a/picosoc/hx8kdemo_tb.v
+++ b/picosoc/hx8kdemo_tb.v
@@ -27,7 +27,7 @@ module testbench;
$dumpfile("testbench.vcd");
$dumpvars(0, testbench);
- repeat (100000) @(posedge clk);
+ repeat (200000) @(posedge clk);
$finish;
end
diff --git a/picosoc/spiflash.v b/picosoc/spiflash.v
index d06f6cd..18cd68d 100644
--- a/picosoc/spiflash.v
+++ b/picosoc/spiflash.v
@@ -42,6 +42,7 @@ module spiflash (
inout io3
);
localparam verbose = 0;
+ localparam integer latency = 8;
reg [7:0] buffer;
integer bitcount = 0;
@@ -148,7 +149,7 @@ module spiflash (
if (bytecount == 5) begin
xip_cmd = (buffer == 8'h a5) ? spi_cmd : 8'h 00;
mode = mode_qspi_wr;
- dummycount = 1;
+ dummycount = latency;
end
if (bytecount >= 5) begin
@@ -173,7 +174,7 @@ module spiflash (
if (bytecount == 5) begin
xip_cmd = (buffer == 8'h a5) ? spi_cmd : 8'h 00;
mode = mode_qspi_ddr_wr;
- dummycount = 1;
+ dummycount = latency;
end
if (bytecount >= 5) begin
diff --git a/picosoc/start.s b/picosoc/start.s
index 5b051b0..9a285d1 100644
--- a/picosoc/start.s
+++ b/picosoc/start.s
@@ -45,6 +45,7 @@ j loop
flashio_worker_begin:
# a0 ... data pointer
# a1 ... data length
+# a2 ... optional WREN cmd (0 = disable)
# address of SPI ctrl reg
li t0, 0x02000000
@@ -54,8 +55,22 @@ li t1, 0x120
sh t1, 0(t0)
# Enable Manual SPI Ctrl
-li t1, 0x00
-sb t1, 3(t0)
+sb zero, 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
flashio_worker_L1: