mirror of
https://github.com/enjoy-digital/litex.git
synced 2025-01-04 09:52:26 -05:00
1a4a6eb445
Libbase should keep its RAM usage to a minimum as it is meant to be executed before the SDRAM is up and running. (Having lots of code is OK though as we XIP from the flash)
108 lines
2.1 KiB
C
108 lines
2.1 KiB
C
/*
|
|
* Milkymist SoC (Software)
|
|
* Copyright (C) 2007, 2008, 2009 Sebastien Bourdeauducq
|
|
*
|
|
* This program is free software: you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation, version 3 of the License.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
#include <uart.h>
|
|
#include <console.h>
|
|
#include <stdio.h>
|
|
#include <stdarg.h>
|
|
#include <irq.h>
|
|
#include <hw/interrupts.h>
|
|
|
|
static console_write_hook write_hook;
|
|
static console_read_hook read_hook;
|
|
static console_read_nonblock_hook read_nonblock_hook;
|
|
|
|
void console_set_write_hook(console_write_hook h)
|
|
{
|
|
write_hook = h;
|
|
}
|
|
|
|
void console_set_read_hook(console_read_hook r, console_read_nonblock_hook rn)
|
|
{
|
|
read_hook = r;
|
|
read_nonblock_hook = rn;
|
|
}
|
|
|
|
static void writechar(char c)
|
|
{
|
|
uart_write(c);
|
|
if(write_hook != NULL)
|
|
write_hook(c);
|
|
}
|
|
|
|
char readchar(void)
|
|
{
|
|
while(1) {
|
|
if(uart_read_nonblock())
|
|
return uart_read();
|
|
if((read_nonblock_hook != NULL) && read_nonblock_hook())
|
|
return read_hook();
|
|
}
|
|
}
|
|
|
|
int readchar_nonblock(void)
|
|
{
|
|
return (uart_read_nonblock()
|
|
|| ((read_nonblock_hook != NULL) && read_nonblock_hook()));
|
|
}
|
|
|
|
int puts(const char *s)
|
|
{
|
|
unsigned int oldmask;
|
|
|
|
oldmask = irq_getmask();
|
|
irq_setmask(IRQ_UART); // HACK: prevent UART data loss
|
|
|
|
while(*s) {
|
|
writechar(*s);
|
|
s++;
|
|
}
|
|
writechar('\n');
|
|
|
|
irq_setmask(oldmask);
|
|
return 1;
|
|
}
|
|
|
|
void putsnonl(const char *s)
|
|
{
|
|
unsigned int oldmask;
|
|
|
|
oldmask = irq_getmask();
|
|
irq_setmask(IRQ_UART); // HACK: prevent UART data loss
|
|
|
|
while(*s) {
|
|
writechar(*s);
|
|
s++;
|
|
}
|
|
|
|
irq_setmask(oldmask);
|
|
}
|
|
|
|
int printf(const char *fmt, ...)
|
|
{
|
|
va_list args;
|
|
int len;
|
|
char outbuf[256];
|
|
|
|
va_start(args, fmt);
|
|
len = vscnprintf(outbuf, sizeof(outbuf), fmt, args);
|
|
va_end(args);
|
|
outbuf[len] = 0;
|
|
putsnonl(outbuf);
|
|
|
|
return len;
|
|
}
|