#pragma once

#include <cstdint>
#include <span>
#include <string_view>

void InitUarts();

// block until the provided buffer is full
void UartReadBlocking(std::span<std::byte> data);
inline uint8_t UartReadByteBlocking() {
    std::byte byte;
    UartReadBlocking(std::span{&byte, 1});
    return static_cast<uint8_t>(byte);
}

// send and poll the uart until transmitted
void UartWriteCrash(std::span<const std::byte> data);
inline void UartWriteCrash(std::string_view s) {
    return UartWriteCrash(std::as_bytes(std::span{s.data(), s.size()}));
}

// block until room is available in tx fifo, then send
void UartWriteBlocking(std::span<const std::byte> data);
inline void UartWriteBlocking(std::string_view s) {
    return UartWriteBlocking(std::as_bytes(std::span{s.data(), s.size()}));
}

void HandleUartTxFromIsr(void*, unsigned int transmitted);
void HandleUartRxFromIsr(void*, unsigned int);
void HandleUartIsr();

uint8_t UartStatus();

void LogStuff();