48 lines
1.2 KiB
C
48 lines
1.2 KiB
C
|
#include <serial.h>
|
||
|
#include <clock.h>
|
||
|
#include <mem.h>
|
||
|
|
||
|
#define DEFAULT_BAUDRATE 115200
|
||
|
|
||
|
void gilbraltar_serial_init(void) {
|
||
|
uint32_t baudrate = DEFAULT_BAUDRATE;
|
||
|
uint32_t clock_rate = gilbraltar_get_clock(2);
|
||
|
uint32_t baud16 = baudrate * 16;
|
||
|
uint32_t int_div = clock_rate / baud16;
|
||
|
uint32_t fract_div_2 = (clock_rate % baud16) * 8 / baudrate;
|
||
|
uint32_t fract_div = fract_div_2 / 2 + fract_div_2 % 2;
|
||
|
|
||
|
write32(ARM_UART0_IMSC, 0);
|
||
|
write32(ARM_UART0_ICR, 0x7ff);
|
||
|
write32(ARM_UART0_IBRD, int_div);
|
||
|
write32(ARM_UART0_FBRD, fract_div);
|
||
|
write32(ARM_UART0_LCRH, (1 << 4) | (3 << 5));
|
||
|
write32(ARM_UART0_CR, (1 << 0) | (1 << 8) | (1 << 9));
|
||
|
}
|
||
|
|
||
|
void gilbraltar_serial_send(uint8_t chr) {
|
||
|
while (1)
|
||
|
if (!(read32(ARM_UART0_FR) & 0x20)) break;
|
||
|
|
||
|
write32(ARM_UART0_DR, chr);
|
||
|
}
|
||
|
|
||
|
uint8_t gilbraltar_serial_recv(void) {
|
||
|
while (1)
|
||
|
if (!(read32(ARM_UART0_FR) & 0x10)) break;
|
||
|
|
||
|
return (read32(ARM_UART0_DR) & 0xff);
|
||
|
}
|
||
|
|
||
|
void gilbraltar_serial_puts(const char *str) {
|
||
|
while (*str) gilbraltar_serial_send(*str++);
|
||
|
}
|
||
|
|
||
|
void gilbraltar_serial_putchar(int chr) {
|
||
|
gilbraltar_serial_send(chr & 0xff);
|
||
|
}
|
||
|
|
||
|
void gilbraltar_serial_write(const char *str, size_t len) {
|
||
|
while (len--) gilbraltar_serial_send(*str++);
|
||
|
}
|