Line 43... |
Line 43... |
#include "neorv32_rte.h"
|
#include "neorv32_rte.h"
|
|
|
/**********************************************************************//**
|
/**********************************************************************//**
|
* The >private< trap vector look-up table of the NEORV32 RTE.
|
* The >private< trap vector look-up table of the NEORV32 RTE.
|
**************************************************************************/
|
**************************************************************************/
|
static uint32_t __neorv32_rte_vector_lut[16] __attribute__((unused)); // trap handler vector table
|
static uint32_t __neorv32_rte_vector_lut[17] __attribute__((unused)); // trap handler vector table
|
|
|
// private functions
|
// private functions
|
static void __attribute__((__interrupt__)) __neorv32_rte_core(void) __attribute__((aligned(16))) __attribute__((unused));
|
static void __attribute__((__interrupt__)) __neorv32_rte_core(void) __attribute__((aligned(16))) __attribute__((unused));
|
static void __neorv32_rte_debug_exc_handler(void) __attribute__((unused));
|
static void __neorv32_rte_debug_exc_handler(void) __attribute__((unused));
|
static void __neorv32_rte_print_true_false(int state) __attribute__((unused));
|
static void __neorv32_rte_print_true_false(int state) __attribute__((unused));
|
Line 93... |
Line 93... |
int neorv32_rte_exception_install(uint8_t id, void (*handler)(void)) {
|
int neorv32_rte_exception_install(uint8_t id, void (*handler)(void)) {
|
|
|
// id valid?
|
// id valid?
|
if ((id == RTE_TRAP_I_MISALIGNED) || (id == RTE_TRAP_I_ACCESS) || (id == RTE_TRAP_I_ILLEGAL) ||
|
if ((id == RTE_TRAP_I_MISALIGNED) || (id == RTE_TRAP_I_ACCESS) || (id == RTE_TRAP_I_ILLEGAL) ||
|
(id == RTE_TRAP_BREAKPOINT) || (id == RTE_TRAP_L_MISALIGNED) || (id == RTE_TRAP_L_ACCESS) ||
|
(id == RTE_TRAP_BREAKPOINT) || (id == RTE_TRAP_L_MISALIGNED) || (id == RTE_TRAP_L_ACCESS) ||
|
(id == RTE_TRAP_S_MISALIGNED) || (id == RTE_TRAP_S_ACCESS) || (id == RTE_TRAP_MENV_CALL) ||
|
(id == RTE_TRAP_S_MISALIGNED) || (id == RTE_TRAP_S_ACCESS) || (id == RTE_TRAP_MENV_CALL) || (id == RTE_TRAP_UENV_CALL) ||
|
(id == RTE_TRAP_MSI) || (id == RTE_TRAP_MTI) || (id == RTE_TRAP_MEI) ||
|
(id == RTE_TRAP_MSI) || (id == RTE_TRAP_MTI) || (id == RTE_TRAP_MEI) ||
|
(id == RTE_TRAP_FIRQ_0) || (id == RTE_TRAP_FIRQ_1) || (id == RTE_TRAP_FIRQ_2) || (id == RTE_TRAP_FIRQ_3)) {
|
(id == RTE_TRAP_FIRQ_0) || (id == RTE_TRAP_FIRQ_1) || (id == RTE_TRAP_FIRQ_2) || (id == RTE_TRAP_FIRQ_3)) {
|
|
|
__neorv32_rte_vector_lut[id] = (uint32_t)handler; // install handler
|
__neorv32_rte_vector_lut[id] = (uint32_t)handler; // install handler
|
|
|
Line 120... |
Line 120... |
int neorv32_rte_exception_uninstall(uint8_t id) {
|
int neorv32_rte_exception_uninstall(uint8_t id) {
|
|
|
// id valid?
|
// id valid?
|
if ((id == RTE_TRAP_I_MISALIGNED) || (id == RTE_TRAP_I_ACCESS) || (id == RTE_TRAP_I_ILLEGAL) ||
|
if ((id == RTE_TRAP_I_MISALIGNED) || (id == RTE_TRAP_I_ACCESS) || (id == RTE_TRAP_I_ILLEGAL) ||
|
(id == RTE_TRAP_BREAKPOINT) || (id == RTE_TRAP_L_MISALIGNED) || (id == RTE_TRAP_L_ACCESS) ||
|
(id == RTE_TRAP_BREAKPOINT) || (id == RTE_TRAP_L_MISALIGNED) || (id == RTE_TRAP_L_ACCESS) ||
|
(id == RTE_TRAP_S_MISALIGNED) || (id == RTE_TRAP_S_ACCESS) || (id == RTE_TRAP_MENV_CALL) ||
|
(id == RTE_TRAP_S_MISALIGNED) || (id == RTE_TRAP_S_ACCESS) || (id == RTE_TRAP_MENV_CALL) || (id == RTE_TRAP_UENV_CALL) ||
|
(id == RTE_TRAP_MSI) || (id == RTE_TRAP_MTI) || (id == RTE_TRAP_MEI) ||
|
(id == RTE_TRAP_MSI) || (id == RTE_TRAP_MTI) || (id == RTE_TRAP_MEI) ||
|
(id == RTE_TRAP_FIRQ_0) || (id == RTE_TRAP_FIRQ_1) || (id == RTE_TRAP_FIRQ_2) || (id == RTE_TRAP_FIRQ_3)) {
|
(id == RTE_TRAP_FIRQ_0) || (id == RTE_TRAP_FIRQ_1) || (id == RTE_TRAP_FIRQ_2) || (id == RTE_TRAP_FIRQ_3)) {
|
|
|
__neorv32_rte_vector_lut[id] = (uint32_t)(&__neorv32_rte_debug_exc_handler); // use dummy handler in case the exception is accidently triggered
|
__neorv32_rte_vector_lut[id] = (uint32_t)(&__neorv32_rte_debug_exc_handler); // use dummy handler in case the exception is accidently triggered
|
|
|
Line 175... |
Line 175... |
case TRAP_CODE_BREAKPOINT: rte_handler = __neorv32_rte_vector_lut[RTE_TRAP_BREAKPOINT]; break;
|
case TRAP_CODE_BREAKPOINT: rte_handler = __neorv32_rte_vector_lut[RTE_TRAP_BREAKPOINT]; break;
|
case TRAP_CODE_L_MISALIGNED: rte_handler = __neorv32_rte_vector_lut[RTE_TRAP_L_MISALIGNED]; break;
|
case TRAP_CODE_L_MISALIGNED: rte_handler = __neorv32_rte_vector_lut[RTE_TRAP_L_MISALIGNED]; break;
|
case TRAP_CODE_L_ACCESS: rte_handler = __neorv32_rte_vector_lut[RTE_TRAP_L_ACCESS]; break;
|
case TRAP_CODE_L_ACCESS: rte_handler = __neorv32_rte_vector_lut[RTE_TRAP_L_ACCESS]; break;
|
case TRAP_CODE_S_MISALIGNED: rte_handler = __neorv32_rte_vector_lut[RTE_TRAP_S_MISALIGNED]; break;
|
case TRAP_CODE_S_MISALIGNED: rte_handler = __neorv32_rte_vector_lut[RTE_TRAP_S_MISALIGNED]; break;
|
case TRAP_CODE_S_ACCESS: rte_handler = __neorv32_rte_vector_lut[RTE_TRAP_S_ACCESS]; break;
|
case TRAP_CODE_S_ACCESS: rte_handler = __neorv32_rte_vector_lut[RTE_TRAP_S_ACCESS]; break;
|
|
case TRAP_CODE_UENV_CALL: rte_handler = __neorv32_rte_vector_lut[RTE_TRAP_UENV_CALL]; break;
|
case TRAP_CODE_MENV_CALL: rte_handler = __neorv32_rte_vector_lut[RTE_TRAP_MENV_CALL]; break;
|
case TRAP_CODE_MENV_CALL: rte_handler = __neorv32_rte_vector_lut[RTE_TRAP_MENV_CALL]; break;
|
case TRAP_CODE_MSI: rte_handler = __neorv32_rte_vector_lut[RTE_TRAP_MSI]; break;
|
case TRAP_CODE_MSI: rte_handler = __neorv32_rte_vector_lut[RTE_TRAP_MSI]; break;
|
case TRAP_CODE_MTI: rte_handler = __neorv32_rte_vector_lut[RTE_TRAP_MTI]; break;
|
case TRAP_CODE_MTI: rte_handler = __neorv32_rte_vector_lut[RTE_TRAP_MTI]; break;
|
case TRAP_CODE_MEI: rte_handler = __neorv32_rte_vector_lut[RTE_TRAP_MEI]; break;
|
case TRAP_CODE_MEI: rte_handler = __neorv32_rte_vector_lut[RTE_TRAP_MEI]; break;
|
case TRAP_CODE_FIRQ_0: rte_handler = __neorv32_rte_vector_lut[RTE_TRAP_FIRQ_0]; break;
|
case TRAP_CODE_FIRQ_0: rte_handler = __neorv32_rte_vector_lut[RTE_TRAP_FIRQ_0]; break;
|
Line 213... |
Line 214... |
case TRAP_CODE_BREAKPOINT: neorv32_uart_print("Breakpoint"); break;
|
case TRAP_CODE_BREAKPOINT: neorv32_uart_print("Breakpoint"); break;
|
case TRAP_CODE_L_MISALIGNED: neorv32_uart_print("Load address misaligned"); break;
|
case TRAP_CODE_L_MISALIGNED: neorv32_uart_print("Load address misaligned"); break;
|
case TRAP_CODE_L_ACCESS: neorv32_uart_print("Load access fault"); break;
|
case TRAP_CODE_L_ACCESS: neorv32_uart_print("Load access fault"); break;
|
case TRAP_CODE_S_MISALIGNED: neorv32_uart_print("Store address misaligned"); break;
|
case TRAP_CODE_S_MISALIGNED: neorv32_uart_print("Store address misaligned"); break;
|
case TRAP_CODE_S_ACCESS: neorv32_uart_print("Store access fault"); break;
|
case TRAP_CODE_S_ACCESS: neorv32_uart_print("Store access fault"); break;
|
case TRAP_CODE_MENV_CALL: neorv32_uart_print("Environment call"); break;
|
case TRAP_CODE_UENV_CALL: neorv32_uart_print("Environment call from U-mode"); break;
|
|
case TRAP_CODE_MENV_CALL: neorv32_uart_print("Environment call from M-mode"); break;
|
case TRAP_CODE_MSI: neorv32_uart_print("Machine software interrupt"); break;
|
case TRAP_CODE_MSI: neorv32_uart_print("Machine software interrupt"); break;
|
case TRAP_CODE_MTI: neorv32_uart_print("Machine timer interrupt"); break;
|
case TRAP_CODE_MTI: neorv32_uart_print("Machine timer interrupt"); break;
|
case TRAP_CODE_MEI: neorv32_uart_print("Machine external interrupt"); break;
|
case TRAP_CODE_MEI: neorv32_uart_print("Machine external interrupt"); break;
|
case TRAP_CODE_FIRQ_0: neorv32_uart_print("Fast interrupt 0"); break;
|
case TRAP_CODE_FIRQ_0: neorv32_uart_print("Fast interrupt 0"); break;
|
case TRAP_CODE_FIRQ_1: neorv32_uart_print("Fast interrupt 1"); break;
|
case TRAP_CODE_FIRQ_1: neorv32_uart_print("Fast interrupt 1"); break;
|
Line 247... |
Line 249... |
char c;
|
char c;
|
|
|
neorv32_uart_printf("\n\n<< Hardware Configuration Overview >>\n");
|
neorv32_uart_printf("\n\n<< Hardware Configuration Overview >>\n");
|
|
|
// CPU configuration
|
// CPU configuration
|
neorv32_uart_printf("\n-- Central Processing Unit --\n");
|
neorv32_uart_printf("\n---- Central Processing Unit ----\n");
|
|
|
// ID
|
// ID
|
neorv32_uart_printf("Hart ID: 0x%x\n", neorv32_cpu_csr_read(CSR_MHARTID));
|
neorv32_uart_printf("Hart ID: 0x%x\n", neorv32_cpu_csr_read(CSR_MHARTID));
|
|
|
neorv32_uart_printf("Vendor ID: 0x%x\n", neorv32_cpu_csr_read(CSR_MVENDORID));
|
neorv32_uart_printf("Vendor ID: 0x%x\n", neorv32_cpu_csr_read(CSR_MVENDORID));
|
Line 283... |
Line 285... |
if (tmp == 3) {
|
if (tmp == 3) {
|
neorv32_uart_printf("RV128");
|
neorv32_uart_printf("RV128");
|
}
|
}
|
|
|
// CPU extensions
|
// CPU extensions
|
|
neorv32_uart_printf("\nEndianness: ");
|
|
if (neorv32_cpu_csr_read(CSR_MSTATUSH) & (1<<CPU_MSTATUSH_MBE)) {
|
|
neorv32_uart_printf("big\n");
|
|
}
|
|
else {
|
|
neorv32_uart_printf("little\n");
|
|
}
|
|
|
|
// CPU extensions
|
neorv32_uart_printf("\nExtensions: ");
|
neorv32_uart_printf("\nExtensions: ");
|
tmp = neorv32_cpu_csr_read(CSR_MISA);
|
tmp = neorv32_cpu_csr_read(CSR_MISA);
|
for (i=0; i<26; i++) {
|
for (i=0; i<26; i++) {
|
if (tmp & (1 << i)) {
|
if (tmp & (1 << i)) {
|
c = (char)('A' + i);
|
c = (char)('A' + i);
|
neorv32_uart_putc(c);
|
neorv32_uart_putc(c);
|
neorv32_uart_putc(' ');
|
neorv32_uart_putc(' ');
|
}
|
}
|
}
|
}
|
|
|
// Z* CPU extensions (from custom CSR "mzext")
|
// Z* CPU extensions (from custom "mzext" CSR)
|
tmp = neorv32_cpu_csr_read(CSR_MZEXT);
|
tmp = neorv32_cpu_csr_read(CSR_MZEXT);
|
if (tmp & (1<<CPU_MZEXT_ZICSR)) {
|
if (tmp & (1<<CPU_MZEXT_ZICSR)) {
|
neorv32_uart_printf("Zicsr ");
|
neorv32_uart_printf("Zicsr ");
|
}
|
}
|
if (tmp & (1<<CPU_MZEXT_ZIFENCEI)) {
|
if (tmp & (1<<CPU_MZEXT_ZIFENCEI)) {
|
neorv32_uart_printf("Zifencei ");
|
neorv32_uart_printf("Zifencei ");
|
}
|
}
|
if (tmp & (1<<CPU_MZEXT_PMP)) {
|
if (tmp & (1<<CPU_MZEXT_PMP)) {
|
neorv32_uart_printf("PMP ");
|
neorv32_uart_printf("PMP ");
|
}
|
}
|
|
if (tmp & (1<<CPU_MZEXT_ZICNT)) {
|
|
neorv32_uart_printf("Zicnt ");
|
|
}
|
|
|
|
|
// check physical memory protection
|
// check physical memory protection
|
neorv32_uart_printf("\n\nPhysical memory protection: ");
|
neorv32_uart_printf("\n\nPhysical memory protection: ");
|
if (neorv32_cpu_csr_read(CSR_MZEXT) & (1<<CPU_MZEXT_PMP)) {
|
if (neorv32_cpu_csr_read(CSR_MZEXT) & (1<<CPU_MZEXT_PMP)) {
|
|
|
// check granulartiy
|
// get minimal region siz (granulartiy)
|
neorv32_cpu_csr_write(CSR_PMPCFG0, 0);
|
neorv32_uart_printf("\n- Minimal granularity: %u bytes per region\n", neorv32_cpu_pmp_get_granularity());
|
neorv32_cpu_csr_write(CSR_PMPADDR0, 0xffffffff);
|
|
uint32_t pmp_test_g = neorv32_cpu_csr_read(0x3b0);
|
|
|
|
// find least-significat set bit
|
|
for (i=31; i!=0; i--) {
|
|
if (((pmp_test_g >> i) & 1) == 0) {
|
|
break;
|
|
}
|
|
}
|
|
|
|
neorv32_uart_printf("\n- Min granularity: ");
|
|
if (i < 29) {
|
|
neorv32_uart_printf("%u bytes per region\n", (uint32_t)(1 << (i+1+2)));
|
|
}
|
|
else {
|
|
neorv32_uart_printf("2^%u bytes per region\n", i+1+2);
|
|
}
|
|
|
|
|
|
// test available modes
|
// test available modes
|
neorv32_uart_printf("- Mode TOR: ");
|
neorv32_uart_printf("- Mode TOR: ");
|
neorv32_cpu_csr_write(CSR_PMPCFG0, 0x08);
|
neorv32_cpu_csr_write(CSR_PMPCFG0, 0x08);
|
if ((neorv32_cpu_csr_read(CSR_PMPCFG0) & 0xFF) == 0x08) {
|
if ((neorv32_cpu_csr_read(CSR_PMPCFG0) & 0xFF) == 0x08) {
|
Line 368... |
Line 364... |
neorv32_uart_printf("not implemented\n");
|
neorv32_uart_printf("not implemented\n");
|
}
|
}
|
|
|
|
|
// Misc - system
|
// Misc - system
|
neorv32_uart_printf("\n\n-- Processor --\n");
|
neorv32_uart_printf("\n\n---- Processor - General ----\n");
|
neorv32_uart_printf("Clock: %u Hz\n", SYSINFO_CLK);
|
neorv32_uart_printf("Clock: %u Hz\n", SYSINFO_CLK);
|
neorv32_uart_printf("User ID: 0x%x\n", SYSINFO_USER_CODE);
|
neorv32_uart_printf("User ID: 0x%x\n", SYSINFO_USER_CODE);
|
|
|
|
|
// Memory configuration
|
// Memory configuration
|
neorv32_uart_printf("\n-- Processor Memory Configuration --\n");
|
neorv32_uart_printf("\n---- Processor - Memory Configuration ----\n");
|
|
|
neorv32_uart_printf("Instr. base address: 0x%x\n", SYSINFO_ISPACE_BASE);
|
neorv32_uart_printf("Instr. base address: 0x%x\n", SYSINFO_ISPACE_BASE);
|
neorv32_uart_printf("Internal IMEM: ");
|
neorv32_uart_printf("Internal IMEM: ");
|
__neorv32_rte_print_true_false(SYSINFO_FEATURES & (1 << SYSINFO_FEATURES_MEM_INT_IMEM));
|
__neorv32_rte_print_true_false(SYSINFO_FEATURES & (1 << SYSINFO_FEATURES_MEM_INT_IMEM));
|
neorv32_uart_printf("IMEM size: %u bytes\n", SYSINFO_IMEM_SIZE);
|
neorv32_uart_printf("IMEM size: %u bytes\n", SYSINFO_IMEM_SIZE);
|
neorv32_uart_printf("Internal IMEM as ROM: ");
|
neorv32_uart_printf("Internal IMEM as ROM: ");
|
__neorv32_rte_print_true_false(SYSINFO_FEATURES & (1 << SYSINFO_FEATURES_MEM_INT_IMEM_ROM));
|
__neorv32_rte_print_true_false(SYSINFO_FEATURES & (1 << SYSINFO_FEATURES_MEM_INT_IMEM_ROM));
|
|
|
neorv32_uart_printf("Data base address: 0x%x\n", SYSINFO_DSPACE_BASE);
|
neorv32_uart_printf("\nData base address: 0x%x\n", SYSINFO_DSPACE_BASE);
|
neorv32_uart_printf("Internal DMEM: ");
|
neorv32_uart_printf("Internal DMEM: ");
|
__neorv32_rte_print_true_false(SYSINFO_FEATURES & (1 << SYSINFO_FEATURES_MEM_INT_DMEM));
|
__neorv32_rte_print_true_false(SYSINFO_FEATURES & (1 << SYSINFO_FEATURES_MEM_INT_DMEM));
|
neorv32_uart_printf("DMEM size: %u bytes\n", SYSINFO_DMEM_SIZE);
|
neorv32_uart_printf("DMEM size: %u bytes\n", SYSINFO_DMEM_SIZE);
|
|
|
neorv32_uart_printf("Bootloader: ");
|
neorv32_uart_printf("Bootloader: ");
|
__neorv32_rte_print_true_false(SYSINFO_FEATURES & (1 << SYSINFO_FEATURES_BOOTLOADER));
|
__neorv32_rte_print_true_false(SYSINFO_FEATURES & (1 << SYSINFO_FEATURES_BOOTLOADER));
|
|
|
neorv32_uart_printf("External M interface: ");
|
neorv32_uart_printf("\nExternal memory bus interface: ");
|
__neorv32_rte_print_true_false(SYSINFO_FEATURES & (1 << SYSINFO_FEATURES_MEM_EXT));
|
__neorv32_rte_print_true_false(SYSINFO_FEATURES & (1 << SYSINFO_FEATURES_MEM_EXT));
|
|
neorv32_uart_printf("External memory bus Endianness: ");
|
|
if (SYSINFO_FEATURES & (1 << SYSINFO_FEATURES_MEM_EXT_ENDIAN)) {
|
|
neorv32_uart_printf("big\n");
|
|
}
|
|
else {
|
|
neorv32_uart_printf("little\n");
|
|
}
|
|
|
// peripherals
|
// peripherals
|
neorv32_uart_printf("\n-- Available Processor Peripherals --\n");
|
neorv32_uart_printf("\n\n---- Processor - Peripherals ----\n");
|
|
|
tmp = SYSINFO_FEATURES;
|
tmp = SYSINFO_FEATURES;
|
|
|
neorv32_uart_printf("GPIO - ");
|
neorv32_uart_printf("GPIO - ");
|
__neorv32_rte_print_true_false(tmp & (1 << SYSINFO_FEATURES_IO_GPIO));
|
__neorv32_rte_print_true_false(tmp & (1 << SYSINFO_FEATURES_IO_GPIO));
|
Line 514... |
Line 517... |
/**********************************************************************//**
|
/**********************************************************************//**
|
* NEORV32 runtime environment: Print project credits
|
* NEORV32 runtime environment: Print project credits
|
**************************************************************************/
|
**************************************************************************/
|
void neorv32_rte_print_logo(void) {
|
void neorv32_rte_print_logo(void) {
|
|
|
neorv32_uart_print(
|
const uint32_t logo_data_c[11][4] =
|
"\n"
|
{
|
" ##\n"
|
{0b00000000000000000000000000000000,0b00000000000000000000000000000000,0b00000000000000000000000110000000,0b00000000000000000000000000000000},
|
" ## ## ## ##\n"
|
{0b00000000000000000000000000000000,0b00000000000000000000000000000000,0b00000000000000000000000110000000,0b00110001100011000000000000000000},
|
" ## ## ######### ######## ######## ## ## ######## ######## ## ###############\n"
|
{0b01100000110001111111110001111111,0b10000111111110001100000011000111,0b11111000011111111000000110000000,0b11111111111111110000000000000000},
|
"#### ## ## ## ## ## ## ## ## ## ## ## ## ## #### ####\n"
|
{0b11110000110011000000000011000000,0b11001100000011001100000011001100,0b00001100110000001100000110000011,0b11000000000000111100000000000000},
|
"## ## ## ## ## ## ## ## ## ## ## ## ## ## ##### ##\n"
|
{0b11011000110011000000000011000000,0b11001100000011001100000011000000,0b00001100000000011000000110000000,0b11000111111000110000000000000000},
|
"## ## ## ######### ## ## ######### ## ## ##### ## ## #### ##### ####\n"
|
{0b11001100110011111111100011000000,0b11001111111110001100000011000000,0b11111000000001100000000110000011,0b11000111111000111100000000000000},
|
"## ## ## ## ## ## ## ## ## ## ## ## ## ## ##### ##\n"
|
{0b11000110110011000000000011000000,0b11001100001100000110000110000000,0b00001100000110000000000110000000,0b11000111111000110000000000000000},
|
"## #### ## ## ## ## ## ## ## ## ## ## ## #### ####\n"
|
{0b11000011110011000000000011000000,0b11001100000110000011001100001100,0b00001100011000000000000110000011,0b11000000000000111100000000000000},
|
"## ## ######### ######## ## ## ## ######## ########## ## ###############\n"
|
{0b11000001100001111111110001111111,0b10001100000011000000110000000111,0b11111000111111111100000110000000,0b11111111111111110000000000000000},
|
" ## ## ## ##\n"
|
{0b00000000000000000000000000000000,0b00000000000000000000000000000000,0b00000000000000000000000110000000,0b00110001100011000000000000000000},
|
" ##\n"
|
{0b00000000000000000000000000000000,0b00000000000000000000000000000000,0b00000000000000000000000110000000,0b00000000000000000000000000000000}
|
"\n");
|
};
|
|
|
|
int u,v,w;
|
|
uint32_t tmp;
|
|
|
|
for (u=0; u<11; u++) {
|
|
neorv32_uart_print("\n");
|
|
for (v=0; v<4; v++) {
|
|
tmp = logo_data_c[u][v];
|
|
for (w=0; w<32; w++){
|
|
if (tmp & (1 << (31-w))) {
|
|
neorv32_uart_putc('#');
|
|
}
|
|
else {
|
|
neorv32_uart_putc(' ');
|
|
}
|
|
}
|
|
}
|
|
}
|
|
neorv32_uart_print("\n");
|
}
|
}
|
|
|
|
|
/**********************************************************************//**
|
/**********************************************************************//**
|
* NEORV32 runtime environment: Print project license
|
* NEORV32 runtime environment: Print project license
|