diff options
author | Pavel Pisa <pisa@cmp.felk.cvut.cz> | 2019-02-25 00:32:54 +0100 |
---|---|---|
committer | Pavel Pisa <pisa@cmp.felk.cvut.cz> | 2019-02-25 00:32:54 +0100 |
commit | a921347d7e4ceb212021599469e38c5ac9e19598 (patch) | |
tree | 1268231267ce58f9a1d8d6055586be67ec54b649 | |
parent | 076d85eaeeeb5ca37cfa6836cb8dd3c5368cf424 (diff) | |
download | qtmips-a921347d7e4ceb212021599469e38c5ac9e19598.tar.gz qtmips-a921347d7e4ceb212021599469e38c5ac9e19598.tar.bz2 qtmips-a921347d7e4ceb212021599469e38c5ac9e19598.zip |
Change serial port peripheral to match SPIM registers definition.
Still Tx only and keep 0xffffc000 base to allows single
instruction LW and SW access.
Signed-off-by: Pavel Pisa <pisa@cmp.felk.cvut.cz>
-rw-r--r-- | README.md | 32 | ||||
-rw-r--r-- | qtmips_machine/serialport.cpp | 40 | ||||
-rw-r--r-- | qtmips_machine/serialport.h | 3 |
3 files changed, 61 insertions, 14 deletions
@@ -90,19 +90,29 @@ Peripherals The simulator implements emulation of two peripherals for now. The firs is simple serial port (UART) which transmission -(Tx) support only for now. It provides two registers, the -first is status port. Bit 0 is reserved for notification -that UART is busy and cannot accept next character. -The second register is actual Tx buffer. The LSB byte -of writtent word is transmitted to terminal window. -Definition of peripheral base address and registers -offsets follows. - +(Tx) support only for now. Actual version implements only +two registers, the 'SERP_TX_ST_REG' is trasmit status register. +Bit 0 signals by value 1 that UART is ready and can +accept next character to be sent. +The second register 'SERP_TX_DATA_REG' is actual Tx buffer. +The LSB byte of writtent word is transmitted to terminal +window. Definition of peripheral base address and registers +offsets follows including reserve for the future Rx port +implementation. ``` #define SERIAL_PORT_BASE 0xffffc000 -#define SERP_ST_REG_o 0x00 -#define SERP_ST_REG_TX_BUSY_m 0x1 -#define SERP_TX_REG_o 0x04 + +#define SERP_RX_ST_REG_o 0x00 +#define SERP_RX_ST_REG_READY_m 0x1 +#define SERP_RX_ST_REG_IE_m 0x2 + +#define SERP_RX_DATA_REG_o 0x04 + +#define SERP_TX_ST_REG_o 0x08 +#define SERP_TX_ST_REG_READY_m 0x1 +#define SERP_TX_ST_REG_IE_m 0x2 + +#define SERP_TX_DATA_REG_o 0x0c ``` The another peripheral allows to set three byte values diff --git a/qtmips_machine/serialport.cpp b/qtmips_machine/serialport.cpp index 0fc0ad2..9e4177b 100644 --- a/qtmips_machine/serialport.cpp +++ b/qtmips_machine/serialport.cpp @@ -35,10 +35,23 @@ #include "serialport.h" +#define SERP_RX_ST_REG_o 0x00 +#define SERP_RX_ST_REG_READY_m 0x1 +#define SERP_RX_ST_REG_IE_m 0x2 + +#define SERP_RX_DATA_REG_o 0x04 + +#define SERP_TX_ST_REG_o 0x08 +#define SERP_TX_ST_REG_READY_m 0x1 +#define SERP_TX_ST_REG_IE_m 0x2 + +#define SERP_TX_DATA_REG_o 0x0c + using namespace machine; SerialPort::SerialPort() { - + rx_st_reg = 0; + tx_st_reg = 0; } SerialPort::~SerialPort() { @@ -52,9 +65,19 @@ bool SerialPort::wword(std::uint32_t address, std::uint32_t value) { #endif emit write_notification(address, value); - if (address == 0x04) + switch (address) { + case SERP_RX_ST_REG_o: + rx_st_reg &= ~SERP_RX_ST_REG_IE_m; + rx_st_reg |= value & SERP_RX_ST_REG_IE_m; + break; + case SERP_TX_ST_REG_o: + tx_st_reg &= ~SERP_TX_ST_REG_IE_m; + tx_st_reg |= value & SERP_TX_ST_REG_IE_m; + break; + case SERP_TX_DATA_REG_o: emit tx_byte(value & 0xff); - + break; + } return true; } @@ -65,6 +88,17 @@ std::uint32_t SerialPort::rword(std::uint32_t address, bool debug_access) const printf("SerialPort::rword address 0x%08lx\n", (unsigned long)address); #endif + switch (address) { + case SERP_RX_ST_REG_o: + value = rx_st_reg; + break; + case SERP_RX_DATA_REG_o: + value = 0; + break; + case SERP_TX_ST_REG_o: + value = tx_st_reg | SERP_TX_ST_REG_READY_m; + break; + } emit read_notification(address, &value); diff --git a/qtmips_machine/serialport.h b/qtmips_machine/serialport.h index 2b14a7e..add1fe6 100644 --- a/qtmips_machine/serialport.h +++ b/qtmips_machine/serialport.h @@ -58,6 +58,9 @@ signals: public: bool wword(std::uint32_t address, std::uint32_t value); std::uint32_t rword(std::uint32_t address, bool debug_access = false) const; +private: + std::uint32_t rx_st_reg; + std::uint32_t tx_st_reg; }; } |