#include <stdint.h>

#include "uart.h"


static struct uart_memory_map *const uart_mm[] = {
	(struct uart_memory_map *const)UART_0_ADDR,
	(struct uart_memory_map *const)UART_1_ADDR,
};


// set the baudrate on the chosen uart, if the baud rate is incorrect or invalid
// then set it to the default value, return the set baudrate value
int uart_set_baudrate(uart_id id, int baud)
{
	// FIXME: actually set the baud rate, for now leave it as the default
	(void)baud;
	(void)id;
	return 115200;
}


// initialize the uart registers for transmit and receive
// TODO: also initialize interrupts and thesholds
int uart_init(uart_id id, uint32_t baud, int stop_bits)
{
	// FIXME: check baud rate error and propagate it
	(void)uart_set_baudrate(id, baud);

	// change the number of stop bits only if stop_bits > 0
	if (stop_bits > 0)
		uart_mm[id]->txctrl.nstop = !!stop_bits;

	uart_mm[id]->txctrl.txen = 1;
	uart_mm[id]->rxctrl.rxen = 1;

	return 0;
}


// transmit a byte of data through a uart line
void uart_tx_byte(uart_id id, unsigned char b)
{
	uart_mm[id]->txdata.data = b;
}


// busy-wait until the uart buffer is cleared
void uart_tx_full(uart_id id)
{
	while (uart_mm[id]->txdata.full);
}


// send a buffer through uart
void uart_tx_buf(uart_id id, unsigned char *buf, unsigned int size)
{
	for (unsigned int i = 0; i < size; i++) {
		uart_tx_byte(id, buf[i]);
		uart_tx_full(id);
	}
}
