mirror of https://github.com/YosysHQ/picorv32.git
130 lines
2.6 KiB
C
130 lines
2.6 KiB
C
#include <stdint.h>
|
|
|
|
// a pointer to this is a null pointer, but the compiler does not
|
|
// know that because "sram" is a linker symbol from sections.lds.
|
|
extern uint32_t sram;
|
|
|
|
#define reg_spictrl (*(volatile uint32_t*)0x02000000)
|
|
#define reg_uart_clkdiv (*(volatile uint32_t*)0x02000004)
|
|
#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)
|
|
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;
|
|
}
|
|
}
|
|
|
|
char getchar_prompt(char *prompt)
|
|
{
|
|
int32_t c = -1;
|
|
|
|
uint32_t cycles_begin, cycles_now, cycles;
|
|
__asm__ volatile ("rdcycle %0" : "=r"(cycles_begin));
|
|
|
|
if (prompt)
|
|
print(prompt);
|
|
|
|
reg_leds = ~0;
|
|
while (c == -1) {
|
|
__asm__ volatile ("rdcycle %0" : "=r"(cycles_now));
|
|
cycles = cycles_now - cycles_begin;
|
|
if (cycles > 12000000) {
|
|
if (prompt)
|
|
print(prompt);
|
|
cycles_begin = cycles_now;
|
|
reg_leds = ~reg_leds;
|
|
}
|
|
c = reg_uart_data;
|
|
}
|
|
reg_leds = 0;
|
|
return c;
|
|
}
|
|
|
|
char getchar()
|
|
{
|
|
return getchar_prompt(0);
|
|
}
|
|
|
|
// --------------------------------------------------------
|
|
|
|
extern uint32_t cmd_read_spi_flash_id_worker_begin;
|
|
extern uint32_t cmd_read_spi_flash_id_worker_end;
|
|
|
|
void cmd_read_spi_flash_id()
|
|
{
|
|
uint32_t *src_ptr = &cmd_read_spi_flash_id_worker_begin;
|
|
uint32_t *dst_ptr = &sram;
|
|
|
|
while (src_ptr != &cmd_read_spi_flash_id_worker_end)
|
|
*(dst_ptr++) = *(src_ptr++);
|
|
|
|
((void(*)())&sram)();
|
|
|
|
for (int i = 0; i < 16; i++) {
|
|
putchar(' ');
|
|
print_hex(((uint8_t*)&sram)[i], 2);
|
|
}
|
|
putchar('\n');
|
|
}
|
|
|
|
// --------------------------------------------------------
|
|
|
|
void main()
|
|
{
|
|
reg_uart_clkdiv = 104;
|
|
while (getchar_prompt("Press ENTER to continue..\n") != '\r') { /* wait */ }
|
|
|
|
print("\n");
|
|
print(" ____ _ ____ ____\n");
|
|
print(" | _ \\(_) ___ ___/ ___| ___ / ___|\n");
|
|
print(" | |_) | |/ __/ _ \\___ \\ / _ \\| |\n");
|
|
print(" | __/| | (_| (_) |__) | (_) | |___\n");
|
|
print(" |_| |_|\\___\\___/____/ \\___/ \\____|\n");
|
|
|
|
while (1)
|
|
{
|
|
print("\n");
|
|
print("\n");
|
|
print("Select an action:\n");
|
|
print("\n");
|
|
print(" [1] Read SPI Flash ID\n");
|
|
print("\n");
|
|
|
|
for (int rep = 10; rep > 0; rep--)
|
|
{
|
|
print("Command> ");
|
|
char cmd = getchar();
|
|
if (cmd > 32 && cmd < 127)
|
|
putchar(cmd);
|
|
print("\n");
|
|
|
|
switch (cmd)
|
|
{
|
|
case '1':
|
|
cmd_read_spi_flash_id();
|
|
rep = 0;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|