2 // Allwinner A64 UART (16550)
16 constexpr uintptr_t UART0_BASE = 0x01c28000;
18 constexpr auto SERIAL_CLOCK = 24000000;
19 constexpr auto BAUDRATE = 115200;
20 constexpr auto BAUDRATE_DIVISOR = (BAUDRATE * 16);
21 constexpr auto CLOCK_DIVISOR = (SERIAL_CLOCK + (BAUDRATE_DIVISOR / 2)) / BAUDRATE_DIVISOR;
23 static_assert(CLOCK_DIVISOR == 13, "Should be 13");
28 return Hw::read8(UART0_BASE + T::OFFSET);
39 void write8(uint8_t nValue)
41 Hw::write8(UART0_BASE + T::OFFSET, nValue);
45 void write(T Register)
47 write8<T>(Register.m_u.m_nValue);
51 } // anonymous namespace
58 const auto LineStatusRegister{read<Uart16550::LineStatusRegister>()};
59 if (LineStatusRegister.m_u.m_Bits.m_TransmitterEmpty)
63 write(Uart16550::InterruptEnableRegister{});
65 Uart16550::ModemControlRegister ModemControlRegister;
66 ModemControlRegister.m_u.m_Bits.m_DataTerminalReady = 1;
67 ModemControlRegister.m_u.m_Bits.m_RequestToSend = 1;
68 write(ModemControlRegister);
70 Uart16550::FifoControlRegister FifoControlRegister;
71 FifoControlRegister.m_u.m_Bits.m_EnableFifos = 1;
72 FifoControlRegister.m_u.m_Bits.m_RcvrFifoReset = 1;
73 FifoControlRegister.m_u.m_Bits.m_XmitFifoReset = 1;
74 write(FifoControlRegister);
76 Uart16550::LineControlRegister LineControlRegister;
77 LineControlRegister.m_u.m_Bits.m_DataLengthSelect = Uart16550::LineControlRegister::BITS_8;
78 write(LineControlRegister);
80 LineControlRegister.m_u.m_Bits.m_DivisorLatchAccess = 1;
81 write(LineControlRegister);
83 write8<Uart16550::DivisorLatchLowRegister>(CLOCK_DIVISOR & 0xff);
84 write8<Uart16550::DivisorLatchHighRegister>((CLOCK_DIVISOR >> 8) & 0xff);
86 LineControlRegister.m_u.m_Bits.m_DivisorLatchAccess = 0;
87 write(LineControlRegister);
91 void send(uint8_t nValue)
95 const auto LineStatusRegister{read<Uart16550::LineStatusRegister>()};
96 if (LineStatusRegister.m_u.m_Bits.m_TxHoldingRegisterEmpty)
99 write8<Uart16550::TransmitHoldingRegister>(nValue);
107 const auto LineStatusRegister{read<Uart16550::LineStatusRegister>()};
108 if (LineStatusRegister.m_u.m_Bits.m_DataReady)
111 return read8<Uart16550::ReceiveBufferRegister>();