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_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;

View File

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

View File

@ -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

View File

@ -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: