mirror of https://github.com/YosysHQ/picorv32.git
Added printf and use it thruout the firmware.
(Proof of concept, not yet final.)
This commit is contained in:
parent
e308982e18
commit
71c33777e1
|
@ -40,7 +40,7 @@ hx8kdemo_sections.lds: sections.lds
|
|||
$(CROSS)cpp -P -DHX8KDEMO -o $@ $^
|
||||
|
||||
hx8kdemo_fw.elf: hx8kdemo_sections.lds start.s firmware.c
|
||||
$(CROSS)gcc $(CFLAGS) -DHX8KDEMO -march=rv32imc -Wl,-Bstatic,-T,hx8kdemo_sections.lds,--strip-debug -ffreestanding -nostdlib -o hx8kdemo_fw.elf start.s firmware.c
|
||||
$(CROSS)gcc $(CFLAGS) -DHX8KDEMO -march=rv32imc -Wl,-Bstatic,-T,hx8kdemo_sections.lds,--strip-debug -ffreestanding -nostdlib -o hx8kdemo_fw.elf start.s firmware.c -lgcc
|
||||
|
||||
hx8kdemo_fw.hex: hx8kdemo_fw.elf
|
||||
$(CROSS)objcopy -O verilog hx8kdemo_fw.elf hx8kdemo_fw.hex
|
||||
|
@ -86,7 +86,7 @@ icebreaker_sections.lds: sections.lds
|
|||
$(CROSS)cpp -P -DICEBREAKER -o $@ $^
|
||||
|
||||
icebreaker_fw.elf: icebreaker_sections.lds start.s firmware.c
|
||||
$(CROSS)gcc $(CFLAGS) -DICEBREAKER -march=rv32ic -Wl,-Bstatic,-T,icebreaker_sections.lds,--strip-debug -ffreestanding -nostdlib -o icebreaker_fw.elf start.s firmware.c
|
||||
$(CROSS)gcc $(CFLAGS) -DICEBREAKER -march=rv32ic -Wl,-Bstatic,-T,icebreaker_sections.lds,--strip-debug -ffreestanding -nostdlib -o icebreaker_fw.elf start.s firmware.c -lgcc
|
||||
|
||||
icebreaker_fw.hex: icebreaker_fw.elf
|
||||
$(CROSS)objcopy -O verilog icebreaker_fw.elf icebreaker_fw.hex
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
* PicoSoC - A simple example SoC using PicoRV32
|
||||
*
|
||||
* Copyright (C) 2017 Clifford Wolf <clifford@clifford.at>
|
||||
* Copyright (C) 2020 René Rebe <rene@exactcode.de>
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
|
@ -19,6 +20,7 @@
|
|||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#ifdef ICEBREAKER
|
||||
# define MEM_TOTAL 0x20000 /* 128 KB */
|
||||
|
@ -157,8 +159,9 @@ void enable_flash_crm()
|
|||
|
||||
void putchar(char c)
|
||||
{
|
||||
if (c == '\n')
|
||||
putchar('\r');
|
||||
if (c == '\n') {
|
||||
reg_uart_data = '\r';
|
||||
}
|
||||
reg_uart_data = c;
|
||||
}
|
||||
|
||||
|
@ -168,53 +171,132 @@ void print(const char *p)
|
|||
putchar(*(p++));
|
||||
}
|
||||
|
||||
void print_hex(uint32_t v, int digits)
|
||||
// 1st and early for debug prints, ...
|
||||
int printf(const char* format, ...)
|
||||
__attribute__ ((format (printf, 1, 2)));
|
||||
|
||||
int isdigit(int c) {
|
||||
if (c >= '0' && c <= '9')
|
||||
return c;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sprintf(char* out, const char* format, ...)
|
||||
__attribute__ ((format (printf, 2, 3)));
|
||||
int vsprintf(char* out, const char* format, va_list argp)
|
||||
{
|
||||
for (int i = 7; i >= 0; i--) {
|
||||
char c = "0123456789abcdef"[(v >> (4*i)) & 15];
|
||||
if (c == '0' && i >= digits) continue;
|
||||
putchar(c);
|
||||
digits = i;
|
||||
const char* _out = out;
|
||||
char temp[23]; // temp. formating buffer
|
||||
uint8_t tempi = sizeof(temp);
|
||||
for (; *format; ++format) {
|
||||
// TODO: >9 (single digit) format and precision!
|
||||
// TODO: and support for more formats, ...
|
||||
uint8_t precision = 0, width = 0, zeros = 0;
|
||||
if (*format == '%') {
|
||||
++format;
|
||||
if (*format == '0') {
|
||||
zeros = *format++;
|
||||
}
|
||||
if (isdigit(*format)) {
|
||||
width = *format++ - '0';
|
||||
}
|
||||
if (format[0] == '.' && isdigit(format[1])) {
|
||||
precision = format[1] - '0';
|
||||
format += 2;
|
||||
}
|
||||
const char fmt = *format;
|
||||
if (fmt == '%') {
|
||||
*out++ = '%';
|
||||
} else if (fmt == 'c') {
|
||||
char char_to_print = va_arg(argp, int);
|
||||
*out++ = char_to_print;
|
||||
} else if (fmt == 's') {
|
||||
char* str_to_print = va_arg(argp, char*);
|
||||
while (*str_to_print) {
|
||||
*out++ = *str_to_print++;
|
||||
if (precision && --precision == 0) break;
|
||||
}
|
||||
} else if (fmt == 'd' || fmt == 'i') {
|
||||
int int_to_print = va_arg(argp, int);
|
||||
if (int_to_print < 0) {
|
||||
*out++ = '-';
|
||||
int_to_print = -int_to_print;
|
||||
}
|
||||
// format int
|
||||
do {
|
||||
int _ = int_to_print % 10;
|
||||
temp[--tempi] = '0' + _;
|
||||
int_to_print /= 10;
|
||||
} while (int_to_print);
|
||||
goto output;
|
||||
} else if (fmt == 'u') {
|
||||
unsigned int_to_print = va_arg(argp, unsigned);
|
||||
// format unsigned
|
||||
do {
|
||||
int _ = int_to_print % 10;
|
||||
temp[--tempi] = '0' + _;
|
||||
int_to_print /= 10;
|
||||
} while (int_to_print);
|
||||
goto output;
|
||||
} else if (fmt == 'x' || fmt == 'p' || fmt == 'X') {
|
||||
unsigned hex_to_print = va_arg(argp, int);
|
||||
// hex format int
|
||||
do {
|
||||
int _ = hex_to_print & 0xf;
|
||||
if (_ > 9) _ += (fmt == 'X' ? 'A' : 'a') - '9' - 1;
|
||||
temp[--tempi] = '0' + _;
|
||||
hex_to_print >>= 4;
|
||||
} while (hex_to_print);
|
||||
goto output;
|
||||
} else {
|
||||
out += sprintf(out, "NIY: %%%c", fmt);
|
||||
}
|
||||
} else {
|
||||
*out++ = *format;
|
||||
}
|
||||
|
||||
void print_dec(uint32_t v)
|
||||
continue;
|
||||
|
||||
output:
|
||||
// copy to output buffer and implicitly reset tempi
|
||||
if (width) {
|
||||
const int w = sizeof(temp) - tempi;
|
||||
for (int i = 0; i < width - w; ++i)
|
||||
*out++ = zeros ? '0' : ' ';
|
||||
}
|
||||
for (; tempi < sizeof(temp); ++tempi)
|
||||
*out++ = temp[tempi];
|
||||
}
|
||||
|
||||
*out = 0;
|
||||
return out - _out;
|
||||
}
|
||||
|
||||
int sprintf(char* text, const char* format, ...)
|
||||
__attribute__ ((format (printf, 2, 3)));
|
||||
int sprintf(char* text, const char* format, ...)
|
||||
{
|
||||
if (v >= 1000) {
|
||||
print(">=1000");
|
||||
return;
|
||||
va_list argp, argp2;
|
||||
va_start(argp, format);
|
||||
va_copy(argp2, argp);
|
||||
int ret = vsprintf(text, format, argp2);
|
||||
va_end(argp2);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (v >= 900) { putchar('9'); v -= 900; }
|
||||
else if (v >= 800) { putchar('8'); v -= 800; }
|
||||
else if (v >= 700) { putchar('7'); v -= 700; }
|
||||
else if (v >= 600) { putchar('6'); v -= 600; }
|
||||
else if (v >= 500) { putchar('5'); v -= 500; }
|
||||
else if (v >= 400) { putchar('4'); v -= 400; }
|
||||
else if (v >= 300) { putchar('3'); v -= 300; }
|
||||
else if (v >= 200) { putchar('2'); v -= 200; }
|
||||
else if (v >= 100) { putchar('1'); v -= 100; }
|
||||
int printf(const char* format, ...)
|
||||
{
|
||||
char text[120]; // TODO: dynamic!
|
||||
|
||||
if (v >= 90) { putchar('9'); v -= 90; }
|
||||
else if (v >= 80) { putchar('8'); v -= 80; }
|
||||
else if (v >= 70) { putchar('7'); v -= 70; }
|
||||
else if (v >= 60) { putchar('6'); v -= 60; }
|
||||
else if (v >= 50) { putchar('5'); v -= 50; }
|
||||
else if (v >= 40) { putchar('4'); v -= 40; }
|
||||
else if (v >= 30) { putchar('3'); v -= 30; }
|
||||
else if (v >= 20) { putchar('2'); v -= 20; }
|
||||
else if (v >= 10) { putchar('1'); v -= 10; }
|
||||
va_list argp, argp2;
|
||||
va_start(argp, format);
|
||||
va_copy(argp2, argp);
|
||||
int ret = vsprintf(text, format, argp2);
|
||||
va_end(argp2);
|
||||
|
||||
if (v >= 9) { putchar('9'); v -= 9; }
|
||||
else if (v >= 8) { putchar('8'); v -= 8; }
|
||||
else if (v >= 7) { putchar('7'); v -= 7; }
|
||||
else if (v >= 6) { putchar('6'); v -= 6; }
|
||||
else if (v >= 5) { putchar('5'); v -= 5; }
|
||||
else if (v >= 4) { putchar('4'); v -= 4; }
|
||||
else if (v >= 3) { putchar('3'); v -= 3; }
|
||||
else if (v >= 2) { putchar('2'); v -= 2; }
|
||||
else if (v >= 1) { putchar('1'); v -= 1; }
|
||||
else putchar('0');
|
||||
print(text);
|
||||
return ret;
|
||||
}
|
||||
|
||||
char getchar_prompt(char *prompt)
|
||||
|
@ -253,28 +335,10 @@ char getchar()
|
|||
void cmd_print_spi_state()
|
||||
{
|
||||
print("SPI State:\n");
|
||||
|
||||
print(" LATENCY ");
|
||||
print_dec((reg_spictrl >> 16) & 15);
|
||||
print("\n");
|
||||
|
||||
print(" DDR ");
|
||||
if ((reg_spictrl & (1 << 22)) != 0)
|
||||
print("ON\n");
|
||||
else
|
||||
print("OFF\n");
|
||||
|
||||
print(" QSPI ");
|
||||
if ((reg_spictrl & (1 << 21)) != 0)
|
||||
print("ON\n");
|
||||
else
|
||||
print("OFF\n");
|
||||
|
||||
print(" CRM ");
|
||||
if ((reg_spictrl & (1 << 20)) != 0)
|
||||
print("ON\n");
|
||||
else
|
||||
print("OFF\n");
|
||||
printf(" LATENCY %d\n", (reg_spictrl >> 16) & 15);
|
||||
printf(" DDR %s\n", (reg_spictrl & (1 << 22)) != 0 ? "ON" : "OFF");
|
||||
printf(" QSPI %s\n", (reg_spictrl & (1 << 21)) != 0 ? "ON" : "OFF");
|
||||
printf(" CRM %s\n", (reg_spictrl & (1 << 20)) != 0 ? "ON" : "OFF");
|
||||
}
|
||||
|
||||
uint32_t xorshift32(uint32_t *state)
|
||||
|
@ -312,9 +376,7 @@ void cmd_memtest()
|
|||
|
||||
for (int word = 0; word < MEM_TOTAL / sizeof(int); word += stride) {
|
||||
if (*(base_word + word) != xorshift32(&state)) {
|
||||
print(" ***FAILED WORD*** at ");
|
||||
print_hex(4*word, 4);
|
||||
print("\n");
|
||||
printf(" ***FAILED WORD*** at %x\n", 4*word);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -329,9 +391,7 @@ void cmd_memtest()
|
|||
|
||||
for (int byte = 0; byte < 128; byte++) {
|
||||
if (*(base_byte + byte) != (uint8_t) byte) {
|
||||
print(" ***FAILED BYTE*** at ");
|
||||
print_hex(byte, 4);
|
||||
print("\n");
|
||||
printf(" ***FAILED BYTE*** at %x\n", byte);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -347,8 +407,7 @@ void cmd_read_flash_id()
|
|||
flashio(buffer, 17, 0);
|
||||
|
||||
for (int i = 1; i <= 16; i++) {
|
||||
putchar(' ');
|
||||
print_hex(buffer[i], 2);
|
||||
printf(" %x", buffer[i]);
|
||||
}
|
||||
putchar('\n');
|
||||
}
|
||||
|
@ -363,13 +422,7 @@ 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, 0);
|
||||
|
||||
print("0x");
|
||||
print_hex(addr, 6);
|
||||
print(" ");
|
||||
print(name);
|
||||
print(" 0x");
|
||||
print_hex(buffer[5], 2);
|
||||
print("\n");
|
||||
printf("0x%x &s 0x%x\n", addr, name, buffer[5]);
|
||||
|
||||
return buffer[5];
|
||||
}
|
||||
|
@ -488,17 +541,9 @@ uint32_t cmd_benchmark(bool verbose, uint32_t *instns_p)
|
|||
|
||||
if (verbose)
|
||||
{
|
||||
print("Cycles: 0x");
|
||||
print_hex(cycles_end - cycles_begin, 8);
|
||||
putchar('\n');
|
||||
|
||||
print("Instns: 0x");
|
||||
print_hex(instns_end - instns_begin, 8);
|
||||
putchar('\n');
|
||||
|
||||
print("Chksum: 0x");
|
||||
print_hex(x32, 8);
|
||||
putchar('\n');
|
||||
printf("Cycles: 0x%x\n", cycles_end - cycles_begin);
|
||||
printf("Instns: 0x%x\n", instns_end - instns_begin);
|
||||
printf("Chksum: 0x%x\n", x32);
|
||||
}
|
||||
|
||||
if (instns_p)
|
||||
|
@ -516,97 +561,69 @@ void cmd_benchmark_all()
|
|||
|
||||
print("default ");
|
||||
reg_spictrl = (reg_spictrl & ~0x00700000) | 0x00000000;
|
||||
print(": ");
|
||||
print_hex(cmd_benchmark(false, &instns), 8);
|
||||
putchar('\n');
|
||||
printf(": %x\n", cmd_benchmark(false, &instns));
|
||||
|
||||
for (int i = 8; i > 0; i--)
|
||||
{
|
||||
print("dspi-");
|
||||
print_dec(i);
|
||||
print(" ");
|
||||
|
||||
printf("dspi-%d ", i);
|
||||
set_flash_latency(i);
|
||||
reg_spictrl = (reg_spictrl & ~0x00700000) | 0x00400000;
|
||||
|
||||
print(": ");
|
||||
print_hex(cmd_benchmark(false, &instns), 8);
|
||||
putchar('\n');
|
||||
printf(": %x\n", cmd_benchmark(false, &instns));
|
||||
}
|
||||
|
||||
for (int i = 8; i > 0; i--)
|
||||
{
|
||||
print("dspi-crm-");
|
||||
print_dec(i);
|
||||
print(" ");
|
||||
printf("dspi-crm-%d ", i);;
|
||||
|
||||
set_flash_latency(i);
|
||||
reg_spictrl = (reg_spictrl & ~0x00700000) | 0x00500000;
|
||||
|
||||
print(": ");
|
||||
print_hex(cmd_benchmark(false, &instns), 8);
|
||||
putchar('\n');
|
||||
printf(": %x\n", cmd_benchmark(false, &instns));
|
||||
}
|
||||
|
||||
for (int i = 8; i > 0; i--)
|
||||
{
|
||||
print("qspi-");
|
||||
print_dec(i);
|
||||
print(" ");
|
||||
printf("qspi-%d ", i);
|
||||
|
||||
set_flash_latency(i);
|
||||
reg_spictrl = (reg_spictrl & ~0x00700000) | 0x00200000;
|
||||
|
||||
print(": ");
|
||||
print_hex(cmd_benchmark(false, &instns), 8);
|
||||
putchar('\n');
|
||||
printf(": %x\n", cmd_benchmark(false, &instns));
|
||||
}
|
||||
|
||||
for (int i = 8; i > 0; i--)
|
||||
{
|
||||
print("qspi-crm-");
|
||||
print_dec(i);
|
||||
print(" ");
|
||||
printf("qspi-crm-%d ", i);
|
||||
|
||||
set_flash_latency(i);
|
||||
reg_spictrl = (reg_spictrl & ~0x00700000) | 0x00300000;
|
||||
|
||||
print(": ");
|
||||
print_hex(cmd_benchmark(false, &instns), 8);
|
||||
putchar('\n');
|
||||
printf(": %x\n", cmd_benchmark(false, &instns));
|
||||
}
|
||||
|
||||
for (int i = 8; i > 0; i--)
|
||||
{
|
||||
print("qspi-ddr-");
|
||||
print_dec(i);
|
||||
print(" ");
|
||||
printf("qspi-ddr-%d ", i);
|
||||
|
||||
set_flash_latency(i);
|
||||
reg_spictrl = (reg_spictrl & ~0x00700000) | 0x00600000;
|
||||
|
||||
print(": ");
|
||||
print_hex(cmd_benchmark(false, &instns), 8);
|
||||
putchar('\n');
|
||||
printf(": %x\n", cmd_benchmark(false, &instns));
|
||||
}
|
||||
|
||||
for (int i = 8; i > 0; i--)
|
||||
{
|
||||
print("qspi-ddr-crm-");
|
||||
print_dec(i);
|
||||
print(" ");
|
||||
printf("qspi-ddr-crm-%d ", i);
|
||||
|
||||
set_flash_latency(i);
|
||||
reg_spictrl = (reg_spictrl & ~0x00700000) | 0x00700000;
|
||||
|
||||
print(": ");
|
||||
print_hex(cmd_benchmark(false, &instns), 8);
|
||||
putchar('\n');
|
||||
printf(": %x\n", cmd_benchmark(false, &instns));
|
||||
}
|
||||
|
||||
print("instns : ");
|
||||
print_hex(instns, 8);
|
||||
putchar('\n');
|
||||
print("instns ");
|
||||
printf(": %x\n", instns);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -617,39 +634,31 @@ void cmd_benchmark_all()
|
|||
|
||||
print("default ");
|
||||
set_flash_mode_spi();
|
||||
print_hex(cmd_benchmark(false, &instns), 8);
|
||||
putchar('\n');
|
||||
printf("%x\n", cmd_benchmark(false, &instns));
|
||||
|
||||
print("dual ");
|
||||
set_flash_mode_dual();
|
||||
print_hex(cmd_benchmark(false, &instns), 8);
|
||||
putchar('\n');
|
||||
printf("%x\n", cmd_benchmark(false, &instns));
|
||||
|
||||
// print("dual-crm ");
|
||||
// enable_flash_crm();
|
||||
// print_hex(cmd_benchmark(false, &instns), 8);
|
||||
// putchar('\n');
|
||||
// printf("%x\n", cmd_benchmark(false, &instns));
|
||||
|
||||
print("quad ");
|
||||
set_flash_mode_quad();
|
||||
print_hex(cmd_benchmark(false, &instns), 8);
|
||||
putchar('\n');
|
||||
printf("%x\n", cmd_benchmark(false, &instns));
|
||||
|
||||
print("quad-crm ");
|
||||
enable_flash_crm();
|
||||
print_hex(cmd_benchmark(false, &instns), 8);
|
||||
putchar('\n');
|
||||
printf("%x\n", cmd_benchmark(false, &instns));
|
||||
|
||||
print("qddr ");
|
||||
set_flash_mode_qddr();
|
||||
print_hex(cmd_benchmark(false, &instns), 8);
|
||||
putchar('\n');
|
||||
printf("%x\n", cmd_benchmark(false, &instns));
|
||||
|
||||
print("qddr-crm ");
|
||||
enable_flash_crm();
|
||||
print_hex(cmd_benchmark(false, &instns), 8);
|
||||
putchar('\n');
|
||||
|
||||
printf("%x\n", cmd_benchmark(false, &instns));
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -683,10 +692,7 @@ void main()
|
|||
print(" |_| |_|\\___\\___/____/ \\___/ \\____|\n");
|
||||
print("\n");
|
||||
|
||||
print("Total memory: ");
|
||||
print_dec(MEM_TOTAL / 1024);
|
||||
print(" KiB\n");
|
||||
print("\n");
|
||||
printf("Total memory: %dKiB\n\n", MEM_TOTAL / 1024);
|
||||
|
||||
cmd_memtest();
|
||||
print("\n");
|
||||
|
|
Loading…
Reference in New Issue