new memory and project layout
This commit is contained in:
@@ -0,0 +1,113 @@
|
||||
#include <stdint.h>
|
||||
#include "bios.h"
|
||||
#include "circ_buf.h"
|
||||
|
||||
#define UART_CTC_CARD_BASE 0x20
|
||||
#define CTC_BASE (UART_CTC_CARD_BASE + 0x00)
|
||||
#define CTC_CHANNEL_0 (CTC_BASE + 0)
|
||||
#define CTC_CHANNEL_3 (CTC_BASE + 3)
|
||||
#define UART_BASE (UART_CTC_CARD_BASE + 0x04)
|
||||
#define UART_CONTROL (UART_BASE + 0)
|
||||
#define UART_DATA (UART_BASE + 1)
|
||||
|
||||
static volatile uint8_t uart_tx_busy;
|
||||
static volatile circular_buffer_t rx_buf;
|
||||
static volatile circular_buffer_t tx_buf;
|
||||
|
||||
static void uart_kick(void)
|
||||
{
|
||||
char c;
|
||||
|
||||
disable_interrupts();
|
||||
if (!uart_tx_busy && buffer_dequeue(&tx_buf, &c)) {
|
||||
uart_tx_busy = 1;
|
||||
io_out(UART_DATA, c);
|
||||
io_out(UART_CONTROL, 0b10110101);
|
||||
}
|
||||
enable_interrupts();
|
||||
}
|
||||
|
||||
void bios_putc(char c)
|
||||
{
|
||||
uint8_t queued;
|
||||
|
||||
do {
|
||||
disable_interrupts();
|
||||
queued = buffer_enqueue(&tx_buf, c);
|
||||
enable_interrupts();
|
||||
if (!queued) uart_kick();
|
||||
} while (!queued);
|
||||
uart_kick();
|
||||
}
|
||||
|
||||
void bios_puts(const char *s)
|
||||
{
|
||||
while (*s) bios_putc(*s++);
|
||||
}
|
||||
|
||||
uint8_t bios_try_getc(void)
|
||||
{
|
||||
char c;
|
||||
uint8_t received;
|
||||
|
||||
disable_interrupts();
|
||||
received = buffer_dequeue(&rx_buf, &c);
|
||||
enable_interrupts();
|
||||
return received ? (uint8_t)c : 0;
|
||||
}
|
||||
|
||||
char bios_getc(void)
|
||||
{
|
||||
uint8_t c;
|
||||
|
||||
do {
|
||||
c = bios_try_getc();
|
||||
} while (!c);
|
||||
return (char)c;
|
||||
}
|
||||
|
||||
void bios_flush(void)
|
||||
{
|
||||
while (uart_tx_busy || !buffer_is_empty(&tx_buf)) uart_kick();
|
||||
}
|
||||
|
||||
void bios_init(void)
|
||||
{
|
||||
buffer_init(&rx_buf);
|
||||
buffer_init(&tx_buf);
|
||||
|
||||
io_out(CTC_CHANNEL_0, 0x57);
|
||||
io_out(CTC_CHANNEL_0, 13);
|
||||
io_out(CTC_CHANNEL_3, 0b11001111);
|
||||
io_out(CTC_CHANNEL_3, 1);
|
||||
io_out(CTC_CHANNEL_0, 0x00);
|
||||
io_out(CTC_CHANNEL_0, 0x40);
|
||||
|
||||
uart_tx_busy = 0;
|
||||
io_out(UART_CONTROL, 0b00000011);
|
||||
io_out(UART_CONTROL, 0b10010101);
|
||||
enable_interrupts();
|
||||
}
|
||||
|
||||
void uart_interrupt(void)
|
||||
{
|
||||
uint8_t status = io_in(UART_CONTROL);
|
||||
|
||||
if ((status & 0x21) != 0) {
|
||||
char c = io_in(UART_DATA);
|
||||
if ((status & 0x01) != 0) buffer_enqueue(&rx_buf, c);
|
||||
}
|
||||
if ((status & 0x02) != 0 && uart_tx_busy) {
|
||||
char c;
|
||||
if (buffer_dequeue(&tx_buf, &c)) {
|
||||
io_out(UART_DATA, c);
|
||||
} else {
|
||||
io_out(UART_CONTROL, 0b10010101);
|
||||
uart_tx_busy = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ctc_interrupt(void)
|
||||
{
|
||||
}
|
||||
Reference in New Issue
Block a user