2022-05-10 18:20:02 +00:00
|
|
|
#include "uart.h"
|
|
|
|
|
2022-05-17 03:56:25 +00:00
|
|
|
#include "gpio.h"
|
|
|
|
#include "ring_buffer.h"
|
|
|
|
#include "trace.h"
|
|
|
|
|
2022-05-10 18:20:02 +00:00
|
|
|
namespace {
|
|
|
|
|
|
|
|
constexpr uintptr_t kUart0BaseAddress = 0x40001000;
|
|
|
|
XUartLite uart0_inst;
|
|
|
|
XUartLite_Config uart0_config = {
|
|
|
|
.DeviceId = 0,
|
|
|
|
.RegBaseAddr = kUart0BaseAddress,
|
|
|
|
.BaudRate = 115200,
|
|
|
|
.UseParity = false,
|
|
|
|
.DataBits = 8,
|
|
|
|
};
|
|
|
|
|
2022-05-17 03:56:25 +00:00
|
|
|
constexpr size_t kUartTxBufferSize = 256;
|
|
|
|
std::array<std::byte, kUartTxBufferSize> tx_buffer = {};
|
|
|
|
RingBuffer tx_ring_buffer{.buffer = tx_buffer};
|
|
|
|
|
2022-05-10 18:20:02 +00:00
|
|
|
} // namespace
|
|
|
|
|
|
|
|
XUartLite* uart0 = &uart0_inst;
|
|
|
|
|
|
|
|
void InitUarts() {
|
|
|
|
XUartLite_CfgInitialize(uart0, &uart0_config, uart0_config.RegBaseAddr);
|
|
|
|
}
|
2022-05-17 03:56:25 +00:00
|
|
|
|
|
|
|
extern "C" uint8_t XUartLite_GetSR(XUartLite* InstancePtr);
|
|
|
|
#define XUL_SR_TX_FIFO_EMPTY 0x04 /* transmit FIFO empty */
|
|
|
|
|
|
|
|
void UartSendCrash(std::span<const std::byte> data) {
|
|
|
|
while (data.size() > 0) {
|
|
|
|
while ((XUartLite_GetSR(uart0) & XUL_SR_TX_FIFO_EMPTY) == 0) {
|
|
|
|
}
|
|
|
|
auto* dat =
|
|
|
|
reinterpret_cast<uint8_t*>(const_cast<std::byte*>(data.data()));
|
|
|
|
uint8_t sent = XUartLite_Send(uart0, dat, data.size());
|
|
|
|
data = data.subspan(sent);
|
|
|
|
}
|
|
|
|
while ((XUartLite_GetSR(uart0) & XUL_SR_TX_FIFO_EMPTY) == 0) {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// blocking
|
|
|
|
void UartSend(std::span<const std::byte> data) {
|
|
|
|
while (!tx_ring_buffer.Store(data)) {
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!XUartLite_IsSending(uart0)) {
|
|
|
|
XUartLite_Send(uart0, tx_ring_buffer.RawReadPointer(),
|
|
|
|
tx_ring_buffer.ContiguousAvailableData());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void HandleUartTxFromIsr(void*, unsigned int transmitted) {
|
|
|
|
tracing::trace(tracing::TraceEvent::kUartTxCb);
|
|
|
|
tx_ring_buffer.Pop(transmitted);
|
|
|
|
if (tx_ring_buffer.AvailableData() > 0) {
|
|
|
|
XUartLite_Send(uart0, tx_ring_buffer.RawReadPointer(),
|
|
|
|
tx_ring_buffer.ContiguousAvailableData());
|
|
|
|
}
|
|
|
|
}
|