#include "uart.h" #include "gpio.h" #include "ring_buffer.h" #include "trace.h" namespace { constexpr uintptr_t kUart0BaseAddress = 0x40001000; XUartLite uart0_inst; XUartLite_Config uart0_config = { .DeviceId = 0, .RegBaseAddr = kUart0BaseAddress, .BaudRate = 115200, .UseParity = false, .DataBits = 8, }; constexpr size_t kUartTxBufferSize = 256; std::array tx_buffer = {}; RingBuffer tx_ring_buffer{.buffer = tx_buffer}; } // namespace XUartLite* uart0 = &uart0_inst; void InitUarts() { XUartLite_CfgInitialize(uart0, &uart0_config, uart0_config.RegBaseAddr); } extern "C" uint8_t XUartLite_GetSR(XUartLite* InstancePtr); #define XUL_SR_TX_FIFO_EMPTY 0x04 /* transmit FIFO empty */ void UartSendCrash(std::span data) { while (data.size() > 0) { while ((XUartLite_GetSR(uart0) & XUL_SR_TX_FIFO_EMPTY) == 0) { } auto* dat = reinterpret_cast(const_cast(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 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()); } }