Forum Discussion
Hi Balerion,
The trick is figuring out the same register address FIFO is used for input AND output.
I did it like this:
#define REG(addr) (*((volatile uint32_t * const)(addr)))
#define ADDR_UART0 0xFFC02000
#define ADDR_UART0_RBR ((ADDR_UART0) + 0x0 ) // RO 0x00000000 Receive Buffer Register, LCR->DLAB=0
#define ADDR_UART0_THR ((ADDR_UART0) + 0x0 ) // WO 0x00000000 Transmit Holding Register, LCR->DLAB=1
#define ADDR_UART0_IER ((ADDR_UART0) + 0x4 ) // RW 0x00000000 Interrupt Enable Register
#define ADDR_UART0_IIR ((ADDR_UART0) + 0x8 ) // RO 0x00000001 Interrupt Identification Register
#define ADDR_UART0_LCR ((ADDR_UART0) + 0xC ) // RW 0x00000000 Line Control Register
#define ADDR_UART0_MCR ((ADDR_UART0) + 0x10) // RW 0x00000000 Modem Control Register
#define ADDR_UART0_LSR ((ADDR_UART0) + 0x14) // RO 0x00000060 Line Status Register
#define ADDR_UART0_MSR ((ADDR_UART0) + 0x18) // RO 0x00000000 Modem Status Register
#define ADDR_UART0_SCR ((ADDR_UART0) + 0x1C) // RW 0x00000000 Scratchpad Register
#define ADDR_UART0_SRBR0 ((ADDR_UART0) + 0x30) // RO 0x00000000 Shadow Receive Buffer Register
#define ADDR_UART0_SRBR1 ((ADDR_UART0) + 0x34) // RO 0x00000000 Shadow Receive Buffer Register 1
#define ADDR_UART0_SRBR2 ((ADDR_UART0) + 0x38) // RO 0x00000000 Shadow Receive Buffer Register 2
#define ADDR_UART0_SRBR3 ((ADDR_UART0) + 0x3C) // RO 0x00000000 Shadow Receive Buffer Register 3
#define ADDR_UART0_SRBR4 ((ADDR_UART0) + 0x40) // RO 0x00000000 Shadow Receive Buffer Register 4
#define ADDR_UART0_SRBR5 ((ADDR_UART0) + 0x44) // RO 0x00000000 Shadow Receive Buffer Register 5
#define ADDR_UART0_SRBR6 ((ADDR_UART0) + 0x48) // RO 0x00000000 Shadow Receive Buffer Register 6
#define ADDR_UART0_SRBR7 ((ADDR_UART0) + 0x4C) // RO 0x00000000 Shadow Receive Buffer Register 7
#define ADDR_UART0_SRBR8 ((ADDR_UART0) + 0x50) // RO 0x00000000 Shadow Receive Buffer Register 8
#define ADDR_UART0_SRBR9 ((ADDR_UART0) + 0x54) // RO 0x00000000 Shadow Receive Buffer Register 9
#define ADDR_UART0_SRBR10 ((ADDR_UART0) + 0x58) // RO 0x00000000 Shadow Receive Buffer Register 10
#define ADDR_UART0_SRBR11 ((ADDR_UART0) + 0x5C) // RO 0x00000000 Shadow Receive Buffer Register 11
#define ADDR_UART0_SRBR12 ((ADDR_UART0) + 0x60) // RO 0x00000000 Shadow Receive Buffer Register 12
#define ADDR_UART0_SRBR13 ((ADDR_UART0) + 0x64) // RO 0x00000000 Shadow Receive Buffer Register 13
#define ADDR_UART0_SRBR14 ((ADDR_UART0) + 0x68) // RO 0x00000000 Shadow Receive Buffer Register 14
#define ADDR_UART0_SRBR15 ((ADDR_UART0) + 0x6C) // RO 0x00000000 Shadow Receive Buffer Register 15
#define ADDR_UART0_FAR ((ADDR_UART0) + 0x70) // RW 0x00000000 FIFO Access Register
#define ADDR_UART0_TFR ((ADDR_UART0) + 0x74) // RO 0x00000000 Transmit FIFO Read
#define ADDR_UART0_RFW ((ADDR_UART0) + 0x78) // RW 0x00000000 Receive FIFO Write
#define ADDR_UART0_USR ((ADDR_UART0) + 0x7C) // RO 0x00000006 UART Status register
#define ADDR_UART0_TFL ((ADDR_UART0) + 0x80) // RO 0x00000000 Transmit FIFO Level
#define ADDR_UART0_RFL ((ADDR_UART0) + 0x84) // RO 0x00000000 Receive FIFO Level
#define ADDR_UART0_SRR ((ADDR_UART0) + 0x88) // RW 0x00000000 Software Reset Register
#define ADDR_UART0_SRTS ((ADDR_UART0) + 0x8C) // RW 0x0000000 Shadow Request to Send
#define ADDR_UART0_SBCR ((ADDR_UART0) + 0x90) // RW 0x00000000 Shadow Break Control Register
#define ADDR_UART0_SDMAM ((ADDR_UART0) + 0x94) // RW 0x00000000 Shadow DMA Mode
#define ADDR_UART0_SFE ((ADDR_UART0) + 0x98) // RW 0x00000000 Shadow FIFO Enable
#define ADDR_UART0_SRT ((ADDR_UART0) + 0x9C) // RW 0x00000000 Shadow RCVR Trigger
#define ADDR_UART0_STET ((ADDR_UART0) + 0xA0) // RW 0x00000000 Shadow TX Empty Trigger
#define ADDR_UART0_HTX ((ADDR_UART0) + 0xA4) // RW 0x00000000 Halt TX
#define ADDR_UART0_DMASA ((ADDR_UART0) + 0xA8) // RW 0x00000000 DMA Software Acknowledge
#define ADDR_UART0_CPR ((ADDR_UART0) + 0xF4) // RO 0x00083F32 Component Parameter Register
#define ADDR_UART0_UCV ((ADDR_UART0) + 0xF8) // RO 0x3331352A Component Version
#define ADDR_UART0_CTR ((ADDR_UART0) + 0xFC) // RO 0x44570110 Component Type Register
#define UART_USR_BUSY 0x01
#define UART_USR_TFNF 0x02 // tx fifo not full
#define UART_USR_TFE 0x04 // tx fifo empty
#define UART_USR_RFNE 0x08 // rx fifo not empty
#define UART_USR_RFF 0x10 // rx fifo full
#define UART_LSR_DR 0x01 // rx data ready
#define uart_IsTransmitFull() ((REG(ADDR_UART0_USR) & (uint32_t)UART_USR_TFNF) != (uint32_t)UART_USR_TFNF)
#define uart_IsTransmitEmpty() ((REG(ADDR_UART0_USR) & (uint32_t)UART_USR_TFE) == (uint32_t)UART_USR_TFE)
#define uart_IsReceiveData() ((REG(ADDR_UART0_USR) & (uint32_t)UART_USR_RFNE) == (uint32_t)UART_USR_RFNE)
//#define uart_IsReceiveData() ((REG(ADDR_UART0_LSR) & (uint32_t)UART_LSR_DR) == (uint32_t)UART_LSR_DR)
#define uart_rx_byte() REG(ADDR_UART0_RBR)
#define uart_tx_byte() REG(ADDR_UART0_THR)
void uart0_init(void)
{
uint32_t reg;
// disable the FIFO's
reg = REG(ADDR_UART0_IIR);
reg &= ~0xC0;
REG(ADDR_UART0_IIR) = reg;
// enable the FIFO's
reg = REG(ADDR_UART0_IIR);
reg |= 0xC0;
REG(ADDR_UART0_IIR) = reg;
}
void outbyte(uint8_t data)
{
// wait until tx fifo is not full
while (uart_IsTransmitFull());
uart_tx_byte() = ((uint32_t)data);
}
void printz(const char *str)
{
//while (*str != (uint32_t)NULL)
while (*str != '\0')
{
if (*str == '\n')
{
outbyte((uint8_t)('\r'));
}
outbyte((uint8_t)(*str));
str ++;
}
return;
}
Be mindful of the WDT if you code an inbyte(). You have to clear it before it triggers or reset occurs.
Kiebach