Improve PicoSoC demo firmware (read flash ID is working now)

This commit is contained in:
Clifford Wolf 2017-09-16 22:08:05 +02:00
parent 76124b8649
commit dabebeb008
5 changed files with 138 additions and 72 deletions

View File

@ -53,7 +53,7 @@ firmware.elf: sections.lds start.s firmware.c
riscv32-unknown-elf-gcc -Wl,-Bstatic,-T,sections.lds,--strip-debug -ffreestanding -nostdlib -o firmware.elf start.s firmware.c
firmware.hex: firmware.elf
riscv32-unknown-elf-objcopy -O verilog firmware.elf /dev/stdout | sed -e '2,65537 d;' > firmware.hex
riscv32-unknown-elf-objcopy -O verilog firmware.elf /dev/stdout | sed -e '1 s/@00000000/@00100000/; 2,65537 d;' > firmware.hex
firmware.bin: firmware.elf
riscv32-unknown-elf-objcopy -O binary firmware.elf /dev/stdout | tail -c +1048577 > firmware.bin

View File

@ -38,8 +38,8 @@ and upload them to a connected iCE40-HX8K Breakout Board.
| 0x02000008 .. 0x0200000B | UART Send/Recv Data Register |
| 0x03000000 .. 0xFFFFFFFF | Memory mapped user peripherals |
The addresses in the internal SRAM region beyond the end of the physical
SRAM map to the corresponding addresses in serial flash.
Reading from the addresses in the internal SRAM region beyond the end of the
physical SRAM will read from the corresponding addresses in serial flash.
Reading from the UART Send/Recv Data Register will return the last received
byte, or -1 (all 32 bits set) when the receive buffer is empty.
@ -52,15 +52,15 @@ GPIO pins mapped to the 32 bit word at address 0x03000000.
| Bit(s) | Description |
| -----: | --------------------------------------------------------- |
| 31 | MEMIO Enable (reset=1, set to 0 to bit bang SPI commands) |
| 30:20 | Reserved (read 0) |
| 19:16 | IO Output enable bits in bit bang mode |
| 15:14 | Reserved (read 0) |
| 13 | Chip select (CS) line in bit bang mode |
| 12 | Serial clock line in bit bang mode |
| 11:8 | IO data bits in bit bang mode |
| 7 | Reserved (read 0) |
| 6 | DDR Enable bit (reset=0) |
| 5 | QSPI Enable bit (reset=0) |
| 4 | Continous Read Enable bit (reset=0) |
| 3:0 | Number of QSPI dummy cycles (reset=0) |
| 30:23 | Reserved (read 0) |
| 22 | DDR Enable bit (reset=0) |
| 21 | QSPI Enable bit (reset=0) |
| 20 | Continous Read Enable bit (reset=0) |
| 19:16 | Number of QSPI dummy cycles (reset=0) |
| 15:12 | Reserved (read 0) |
| 11:8 | IO Output enable bits in bit bang mode |
| 7:6 | Reserved (read 0) |
| 5 | Chip select (CS) line in bit bang mode |
| 4 | Serial clock line in bit bang mode |
| 3:0 | IO data bits in bit bang mode |

View File

@ -9,12 +9,26 @@ extern uint32_t sram;
#define reg_uart_data (*(volatile uint32_t*)0x02000008)
#define reg_leds (*(volatile uint32_t*)0x03000000)
void putchar(char c)
{
if (c == '\n')
putchar('\r');
reg_uart_data = c;
}
void print(const char *p)
{
while (*p) {
if (*p == '\n')
reg_uart_data = '\r';
reg_uart_data = *(p++);
while (*p)
putchar(*(p++));
}
void print_hex(uint32_t v, int digits)
{
for (int i = 7; i >= 0; i--) {
char c = "0123456789abcdef"[(v >> (4*i)) & 15];
if (c == '0' && i >= digits) continue;
putchar(c);
digits = i;
}
}
@ -63,6 +77,12 @@ void cmd_read_spi_flash_id()
*(dst_ptr++) = *(src_ptr++);
((void(*)())&sram)();
for (int i = 0; i < 16; i++) {
putchar(' ');
print_hex(((uint8_t*)&sram)[i], 2);
}
putchar('\n');
}
// --------------------------------------------------------
@ -93,7 +113,7 @@ void main()
print("Command> ");
char cmd = getchar();
if (cmd > 32 && cmd < 127)
reg_uart_data = cmd;
putchar(cmd);
print("\n");
switch (cmd)

View File

@ -74,27 +74,27 @@ module spimemio (
reg softreset;
reg config_en; // cfgreg[31]
reg [3:0] config_oe; // cfgreg[19:16]
reg config_csb; // cfgreg[13]
reg config_clk; // cfgref[12]
reg [3:0] config_do; // cfgreg[11:8]
reg config_ddr; // cfgreg[6]
reg config_qspi; // cfgreg[5]
reg config_cont; // cfgreg[4]
reg [3:0] config_dummy; // cfgreg[3:0]
reg config_ddr; // cfgreg[22]
reg config_qspi; // cfgreg[21]
reg config_cont; // cfgreg[20]
reg [3:0] config_dummy; // cfgreg[19:16]
reg [3:0] config_oe; // cfgreg[11:8]
reg config_csb; // cfgreg[5]
reg config_clk; // cfgref[4]
reg [3:0] config_do; // cfgreg[3:0]
assign cfgreg_do[31] = config_en;
assign cfgreg_do[30:20] = 0;
assign cfgreg_do[19:16] = {flash_io3_oe, flash_io2_oe, flash_io1_oe, flash_io0_oe};
assign cfgreg_do[15:14] = 0;
assign cfgreg_do[13] = flash_csb;
assign cfgreg_do[12] = flash_clk;
assign cfgreg_do[11:8] = {flash_io3_di, flash_io2_di, flash_io1_di, flash_io0_di};
assign cfgreg_do[7] = 0;
assign cfgreg_do[6] = config_ddr;
assign cfgreg_do[5] = config_qspi;
assign cfgreg_do[4] = config_cont;
assign cfgreg_do[3:0] = config_dummy;
assign cfgreg_do[30:23] = 0;
assign cfgreg_do[22] = config_ddr;
assign cfgreg_do[21] = config_qspi;
assign cfgreg_do[20] = config_cont;
assign cfgreg_do[19:16] = config_dummy;
assign cfgreg_do[15:12] = 0;
assign cfgreg_do[11:8] = {flash_io3_oe, flash_io2_oe, flash_io1_oe, flash_io0_oe};
assign cfgreg_do[7:6] = 0;
assign cfgreg_do[5] = flash_csb;
assign cfgreg_do[4] = flash_clk;
assign cfgreg_do[3:0] = {flash_io3_di, flash_io2_di, flash_io1_di, flash_io0_di};
always @(posedge clk) begin
softreset <= !config_en || cfgreg_we;
@ -111,18 +111,18 @@ module spimemio (
config_dummy <= 0;
end else begin
if (cfgreg_we[0]) begin
config_ddr <= cfgreg_di[6];
config_qspi <= cfgreg_di[5];
config_cont <= cfgreg_di[4];
config_dummy <= cfgreg_di[3:0];
config_csb <= cfgreg_di[5];
config_clk <= cfgreg_di[4];
config_do <= cfgreg_di[3:0];
end
if (cfgreg_we[1]) begin
config_csb <= cfgreg_di[13];
config_clk <= cfgreg_di[12];
config_do <= cfgreg_di[11:8];
config_oe <= cfgreg_di[11:8];
end
if (cfgreg_we[2]) begin
config_oe <= cfgreg_di[19:16];
config_ddr <= cfgreg_di[22];
config_qspi <= cfgreg_di[21];
config_cont <= cfgreg_di[20];
config_dummy <= cfgreg_di[19:16];
end
if (cfgreg_we[3]) begin
config_en <= cfgreg_di[31];
@ -130,6 +130,9 @@ module spimemio (
end
end
wire xfer_csb;
wire xfer_clk;
wire xfer_io0_oe;
wire xfer_io1_oe;
wire xfer_io2_oe;
@ -140,6 +143,9 @@ module spimemio (
wire xfer_io2_do;
wire xfer_io3_do;
assign flash_csb = config_en ? xfer_csb : config_csb;
assign flash_clk = config_en ? xfer_clk : config_clk;
assign flash_io0_oe = config_en ? xfer_io0_oe : config_oe[0];
assign flash_io1_oe = config_en ? xfer_io1_oe : config_oe[1];
assign flash_io2_oe = config_en ? xfer_io2_oe : config_oe[2];
@ -164,16 +170,16 @@ module spimemio (
.dout_valid (dout_valid ),
.dout_data (dout_data ),
.dout_tag (dout_tag ),
.flash_csb (flash_csb ),
.flash_clk (flash_clk ),
.flash_io0_oe (xfer_io0_oe),
.flash_io1_oe (xfer_io1_oe),
.flash_io2_oe (xfer_io2_oe),
.flash_io3_oe (xfer_io3_oe),
.flash_io0_do (xfer_io0_do),
.flash_io1_do (xfer_io1_do),
.flash_io2_do (xfer_io2_do),
.flash_io3_do (xfer_io3_do),
.flash_csb (xfer_csb ),
.flash_clk (xfer_clk ),
.flash_io0_oe (xfer_io0_oe ),
.flash_io1_oe (xfer_io1_oe ),
.flash_io2_oe (xfer_io2_oe ),
.flash_io3_oe (xfer_io3_oe ),
.flash_io0_do (xfer_io0_do ),
.flash_io1_do (xfer_io1_do ),
.flash_io2_do (xfer_io2_do ),
.flash_io3_do (xfer_io3_do ),
.flash_io0_di (flash_io0_di),
.flash_io1_di (flash_io1_di),
.flash_io2_di (flash_io2_di),

View File

@ -35,27 +35,67 @@ addi x31, zero, 0
li sp, 4*256
call main
j start
loop:
j loop
.global cmd_read_spi_flash_id_worker_begin
.global cmd_read_spi_flash_id_worker_end
cmd_read_spi_flash_id_worker_begin:
li t0,0x02000008
li t1,'F'
sw t1,0(t0)
li t1,'I'
sw t1,0(t0)
li t1,'X'
sw t1,0(t0)
li t1,'M'
sw t1,0(t0)
li t1,'E'
sw t1,0(t0)
li t1,'\r'
sw t1,0(t0)
li t1,'\n'
sw t1,0(t0)
# address of SPI ctrl reg
li t0, 0x02000000
# Manual Ctrl
li t1, 0x00
sb t1, 3(t0)
# CS high, IO0 is output
li t1, 0x120
sh t1, 0(t0)
# CS low
sb zero, 0(t0)
# Send 0x9F (EDEC-ID Read)
li t2, 0x9F
li t3, 8
cmd_read_spi_flash_id_worker_L1:
srli t4, t2, 7
andi t4, t4, 0x01
sb t4, 0(t0)
ori t4, t4, 0x10
slli t2, t2, 1
addi t3, t3, -1
sb t4, 0(t0)
bnez t3, cmd_read_spi_flash_id_worker_L1
# Read 16 bytes and store in zero page
li t3, 0
li a2, 16
cmd_read_spi_flash_id_worker_L2:
li a0, 8
li a1, 0
cmd_read_spi_flash_id_worker_L3:
sb zero, 0(t0)
li t4, 0x10
sb t4, 0(t0)
lb t4, 0(t0)
andi t4, t4, 2
srli t4, t4, 1
slli a1, a1, 1
or a1, a1, t4
addi a0, a0, -1
bnez a0, cmd_read_spi_flash_id_worker_L3
sb a1, 0(t3)
addi t3, t3, 1
bne t3, a2, cmd_read_spi_flash_id_worker_L2
# back to MEMIO mode
li t1, 0x80
sb t1, 3(t0)
ret
cmd_read_spi_flash_id_worker_end: