Improve PicoSoC demo firmware (read flash ID is working now)
This commit is contained in:
parent
76124b8649
commit
dabebeb008
|
@ -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
|
riscv32-unknown-elf-gcc -Wl,-Bstatic,-T,sections.lds,--strip-debug -ffreestanding -nostdlib -o firmware.elf start.s firmware.c
|
||||||
|
|
||||||
firmware.hex: firmware.elf
|
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
|
firmware.bin: firmware.elf
|
||||||
riscv32-unknown-elf-objcopy -O binary firmware.elf /dev/stdout | tail -c +1048577 > firmware.bin
|
riscv32-unknown-elf-objcopy -O binary firmware.elf /dev/stdout | tail -c +1048577 > firmware.bin
|
||||||
|
|
|
@ -38,8 +38,8 @@ and upload them to a connected iCE40-HX8K Breakout Board.
|
||||||
| 0x02000008 .. 0x0200000B | UART Send/Recv Data Register |
|
| 0x02000008 .. 0x0200000B | UART Send/Recv Data Register |
|
||||||
| 0x03000000 .. 0xFFFFFFFF | Memory mapped user peripherals |
|
| 0x03000000 .. 0xFFFFFFFF | Memory mapped user peripherals |
|
||||||
|
|
||||||
The addresses in the internal SRAM region beyond the end of the physical
|
Reading from the addresses in the internal SRAM region beyond the end of the
|
||||||
SRAM map to the corresponding addresses in serial flash.
|
physical SRAM will read from the corresponding addresses in serial flash.
|
||||||
|
|
||||||
Reading from the UART Send/Recv Data Register will return the last received
|
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.
|
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 |
|
| Bit(s) | Description |
|
||||||
| -----: | --------------------------------------------------------- |
|
| -----: | --------------------------------------------------------- |
|
||||||
| 31 | MEMIO Enable (reset=1, set to 0 to bit bang SPI commands) |
|
| 31 | MEMIO Enable (reset=1, set to 0 to bit bang SPI commands) |
|
||||||
| 30:20 | Reserved (read 0) |
|
| 30:23 | Reserved (read 0) |
|
||||||
| 19:16 | IO Output enable bits in bit bang mode |
|
| 22 | DDR Enable bit (reset=0) |
|
||||||
| 15:14 | Reserved (read 0) |
|
| 21 | QSPI Enable bit (reset=0) |
|
||||||
| 13 | Chip select (CS) line in bit bang mode |
|
| 20 | Continous Read Enable bit (reset=0) |
|
||||||
| 12 | Serial clock line in bit bang mode |
|
| 19:16 | Number of QSPI dummy cycles (reset=0) |
|
||||||
| 11:8 | IO data bits in bit bang mode |
|
| 15:12 | Reserved (read 0) |
|
||||||
| 7 | Reserved (read 0) |
|
| 11:8 | IO Output enable bits in bit bang mode |
|
||||||
| 6 | DDR Enable bit (reset=0) |
|
| 7:6 | Reserved (read 0) |
|
||||||
| 5 | QSPI Enable bit (reset=0) |
|
| 5 | Chip select (CS) line in bit bang mode |
|
||||||
| 4 | Continous Read Enable bit (reset=0) |
|
| 4 | Serial clock line in bit bang mode |
|
||||||
| 3:0 | Number of QSPI dummy cycles (reset=0) |
|
| 3:0 | IO data bits in bit bang mode |
|
||||||
|
|
||||||
|
|
|
@ -9,12 +9,26 @@ extern uint32_t sram;
|
||||||
#define reg_uart_data (*(volatile uint32_t*)0x02000008)
|
#define reg_uart_data (*(volatile uint32_t*)0x02000008)
|
||||||
#define reg_leds (*(volatile uint32_t*)0x03000000)
|
#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)
|
void print(const char *p)
|
||||||
{
|
{
|
||||||
while (*p) {
|
while (*p)
|
||||||
if (*p == '\n')
|
putchar(*(p++));
|
||||||
reg_uart_data = '\r';
|
}
|
||||||
reg_uart_data = *(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++);
|
*(dst_ptr++) = *(src_ptr++);
|
||||||
|
|
||||||
((void(*)())&sram)();
|
((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> ");
|
print("Command> ");
|
||||||
char cmd = getchar();
|
char cmd = getchar();
|
||||||
if (cmd > 32 && cmd < 127)
|
if (cmd > 32 && cmd < 127)
|
||||||
reg_uart_data = cmd;
|
putchar(cmd);
|
||||||
print("\n");
|
print("\n");
|
||||||
|
|
||||||
switch (cmd)
|
switch (cmd)
|
||||||
|
|
|
@ -74,27 +74,27 @@ module spimemio (
|
||||||
reg softreset;
|
reg softreset;
|
||||||
|
|
||||||
reg config_en; // cfgreg[31]
|
reg config_en; // cfgreg[31]
|
||||||
reg [3:0] config_oe; // cfgreg[19:16]
|
reg config_ddr; // cfgreg[22]
|
||||||
reg config_csb; // cfgreg[13]
|
reg config_qspi; // cfgreg[21]
|
||||||
reg config_clk; // cfgref[12]
|
reg config_cont; // cfgreg[20]
|
||||||
reg [3:0] config_do; // cfgreg[11:8]
|
reg [3:0] config_dummy; // cfgreg[19:16]
|
||||||
reg config_ddr; // cfgreg[6]
|
reg [3:0] config_oe; // cfgreg[11:8]
|
||||||
reg config_qspi; // cfgreg[5]
|
reg config_csb; // cfgreg[5]
|
||||||
reg config_cont; // cfgreg[4]
|
reg config_clk; // cfgref[4]
|
||||||
reg [3:0] config_dummy; // cfgreg[3:0]
|
reg [3:0] config_do; // cfgreg[3:0]
|
||||||
|
|
||||||
assign cfgreg_do[31] = config_en;
|
assign cfgreg_do[31] = config_en;
|
||||||
assign cfgreg_do[30:20] = 0;
|
assign cfgreg_do[30:23] = 0;
|
||||||
assign cfgreg_do[19:16] = {flash_io3_oe, flash_io2_oe, flash_io1_oe, flash_io0_oe};
|
assign cfgreg_do[22] = config_ddr;
|
||||||
assign cfgreg_do[15:14] = 0;
|
assign cfgreg_do[21] = config_qspi;
|
||||||
assign cfgreg_do[13] = flash_csb;
|
assign cfgreg_do[20] = config_cont;
|
||||||
assign cfgreg_do[12] = flash_clk;
|
assign cfgreg_do[19:16] = config_dummy;
|
||||||
assign cfgreg_do[11:8] = {flash_io3_di, flash_io2_di, flash_io1_di, flash_io0_di};
|
assign cfgreg_do[15:12] = 0;
|
||||||
assign cfgreg_do[7] = 0;
|
assign cfgreg_do[11:8] = {flash_io3_oe, flash_io2_oe, flash_io1_oe, flash_io0_oe};
|
||||||
assign cfgreg_do[6] = config_ddr;
|
assign cfgreg_do[7:6] = 0;
|
||||||
assign cfgreg_do[5] = config_qspi;
|
assign cfgreg_do[5] = flash_csb;
|
||||||
assign cfgreg_do[4] = config_cont;
|
assign cfgreg_do[4] = flash_clk;
|
||||||
assign cfgreg_do[3:0] = config_dummy;
|
assign cfgreg_do[3:0] = {flash_io3_di, flash_io2_di, flash_io1_di, flash_io0_di};
|
||||||
|
|
||||||
always @(posedge clk) begin
|
always @(posedge clk) begin
|
||||||
softreset <= !config_en || cfgreg_we;
|
softreset <= !config_en || cfgreg_we;
|
||||||
|
@ -111,18 +111,18 @@ module spimemio (
|
||||||
config_dummy <= 0;
|
config_dummy <= 0;
|
||||||
end else begin
|
end else begin
|
||||||
if (cfgreg_we[0]) begin
|
if (cfgreg_we[0]) begin
|
||||||
config_ddr <= cfgreg_di[6];
|
config_csb <= cfgreg_di[5];
|
||||||
config_qspi <= cfgreg_di[5];
|
config_clk <= cfgreg_di[4];
|
||||||
config_cont <= cfgreg_di[4];
|
config_do <= cfgreg_di[3:0];
|
||||||
config_dummy <= cfgreg_di[3:0];
|
|
||||||
end
|
end
|
||||||
if (cfgreg_we[1]) begin
|
if (cfgreg_we[1]) begin
|
||||||
config_csb <= cfgreg_di[13];
|
config_oe <= cfgreg_di[11:8];
|
||||||
config_clk <= cfgreg_di[12];
|
|
||||||
config_do <= cfgreg_di[11:8];
|
|
||||||
end
|
end
|
||||||
if (cfgreg_we[2]) begin
|
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
|
end
|
||||||
if (cfgreg_we[3]) begin
|
if (cfgreg_we[3]) begin
|
||||||
config_en <= cfgreg_di[31];
|
config_en <= cfgreg_di[31];
|
||||||
|
@ -130,6 +130,9 @@ module spimemio (
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
wire xfer_csb;
|
||||||
|
wire xfer_clk;
|
||||||
|
|
||||||
wire xfer_io0_oe;
|
wire xfer_io0_oe;
|
||||||
wire xfer_io1_oe;
|
wire xfer_io1_oe;
|
||||||
wire xfer_io2_oe;
|
wire xfer_io2_oe;
|
||||||
|
@ -140,6 +143,9 @@ module spimemio (
|
||||||
wire xfer_io2_do;
|
wire xfer_io2_do;
|
||||||
wire xfer_io3_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_io0_oe = config_en ? xfer_io0_oe : config_oe[0];
|
||||||
assign flash_io1_oe = config_en ? xfer_io1_oe : config_oe[1];
|
assign flash_io1_oe = config_en ? xfer_io1_oe : config_oe[1];
|
||||||
assign flash_io2_oe = config_en ? xfer_io2_oe : config_oe[2];
|
assign flash_io2_oe = config_en ? xfer_io2_oe : config_oe[2];
|
||||||
|
@ -164,16 +170,16 @@ module spimemio (
|
||||||
.dout_valid (dout_valid ),
|
.dout_valid (dout_valid ),
|
||||||
.dout_data (dout_data ),
|
.dout_data (dout_data ),
|
||||||
.dout_tag (dout_tag ),
|
.dout_tag (dout_tag ),
|
||||||
.flash_csb (flash_csb ),
|
.flash_csb (xfer_csb ),
|
||||||
.flash_clk (flash_clk ),
|
.flash_clk (xfer_clk ),
|
||||||
.flash_io0_oe (xfer_io0_oe),
|
.flash_io0_oe (xfer_io0_oe ),
|
||||||
.flash_io1_oe (xfer_io1_oe),
|
.flash_io1_oe (xfer_io1_oe ),
|
||||||
.flash_io2_oe (xfer_io2_oe),
|
.flash_io2_oe (xfer_io2_oe ),
|
||||||
.flash_io3_oe (xfer_io3_oe),
|
.flash_io3_oe (xfer_io3_oe ),
|
||||||
.flash_io0_do (xfer_io0_do),
|
.flash_io0_do (xfer_io0_do ),
|
||||||
.flash_io1_do (xfer_io1_do),
|
.flash_io1_do (xfer_io1_do ),
|
||||||
.flash_io2_do (xfer_io2_do),
|
.flash_io2_do (xfer_io2_do ),
|
||||||
.flash_io3_do (xfer_io3_do),
|
.flash_io3_do (xfer_io3_do ),
|
||||||
.flash_io0_di (flash_io0_di),
|
.flash_io0_di (flash_io0_di),
|
||||||
.flash_io1_di (flash_io1_di),
|
.flash_io1_di (flash_io1_di),
|
||||||
.flash_io2_di (flash_io2_di),
|
.flash_io2_di (flash_io2_di),
|
||||||
|
|
|
@ -35,27 +35,67 @@ addi x31, zero, 0
|
||||||
|
|
||||||
li sp, 4*256
|
li sp, 4*256
|
||||||
call main
|
call main
|
||||||
j start
|
|
||||||
|
loop:
|
||||||
|
j loop
|
||||||
|
|
||||||
.global cmd_read_spi_flash_id_worker_begin
|
.global cmd_read_spi_flash_id_worker_begin
|
||||||
.global cmd_read_spi_flash_id_worker_end
|
.global cmd_read_spi_flash_id_worker_end
|
||||||
|
|
||||||
cmd_read_spi_flash_id_worker_begin:
|
cmd_read_spi_flash_id_worker_begin:
|
||||||
li t0,0x02000008
|
|
||||||
li t1,'F'
|
# address of SPI ctrl reg
|
||||||
sw t1,0(t0)
|
li t0, 0x02000000
|
||||||
li t1,'I'
|
|
||||||
sw t1,0(t0)
|
# Manual Ctrl
|
||||||
li t1,'X'
|
li t1, 0x00
|
||||||
sw t1,0(t0)
|
sb t1, 3(t0)
|
||||||
li t1,'M'
|
|
||||||
sw t1,0(t0)
|
# CS high, IO0 is output
|
||||||
li t1,'E'
|
li t1, 0x120
|
||||||
sw t1,0(t0)
|
sh t1, 0(t0)
|
||||||
li t1,'\r'
|
|
||||||
sw t1,0(t0)
|
# CS low
|
||||||
li t1,'\n'
|
sb zero, 0(t0)
|
||||||
sw t1,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
|
ret
|
||||||
cmd_read_spi_flash_id_worker_end:
|
cmd_read_spi_flash_id_worker_end:
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue