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

View File

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

View File

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

View File

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

View File

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