Implement UART closer to how it's done on the sifive board

This commit is contained in:
Konstantin Nazarov 2024-12-22 14:07:57 +00:00
parent 844ad3b073
commit 616f70bfa4
Signed by: knazarov
GPG key ID: 4CFE0A42FA409C22
2 changed files with 19 additions and 7 deletions

View file

@ -37,9 +37,13 @@ void UART::read_mem_u8(uint8_t* dst, size_t addr) {
}
addr -= UART_ADDR;
switch (addr) {
case UART_LSR:
// Always ready to transmit
*dst = LSR_TRANSMITTER_EMPTY;
case UART_RXDATA:
*dst = 0x0;
break;
case UART_RXDATA + 3:
// receiver is always empty for now
*dst = 0x80;
break;
default:
*dst = 0;
}
@ -52,7 +56,7 @@ void UART::write_mem_u8(uint8_t* src, size_t addr) {
}
addr -= UART_ADDR;
switch (addr) {
case UART_THR:
case UART_TXDATA:
std::cout.put(static_cast<char>(*src));
break;
}
@ -66,6 +70,14 @@ void UART::write_mem_u32(uint32_t* src, size_t addr) {
}
}
void UART::read_mem_u32(uint32_t* dst, size_t addr) {
uint8_t* d = (uint8_t*)dst;
for (size_t i = 0; i < 4; i++) {
read_mem_u8(d + i, addr + i);
}
}
void Timer::update() {
using Clock = std::chrono::high_resolution_clock;
constexpr auto den = Clock::period::den;

View file

@ -78,12 +78,12 @@ class UART final : public Device {
virtual void write_mem_u32(uint32_t *src, size_t addr);
virtual void read_mem_u8(uint8_t *dst, size_t addr);
virtual void read_mem_u32(uint32_t *dst, size_t addr);
private:
enum Registers {
UART_RBR = 0x00, // Receiver Buffer Register
UART_THR = 0x00, // Transmitter Holding Register
UART_LSR = 0x05 // Line Status Register
UART_TXDATA = 0x00,
UART_RXDATA = 0x04,
};
// Line Status Register bits