pl011 uart: Fix fifo states
* Lets wait for space *before* writing to the fifo instead of after. * Flush functions now really flush the fifo waiting for them to enter an empty state. * Simple memory barriers added (may need revised) We don't have access to the kernel barriers here.
This commit is contained in:
@@ -14,13 +14,20 @@
|
|||||||
//#include <target/debugconfig.h>
|
//#include <target/debugconfig.h>
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
barrier()
|
||||||
|
{
|
||||||
|
asm volatile ("" : : : "memory");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
UartPL011::UartPL011(addr_t base)
|
UartPL011::UartPL011(addr_t base)
|
||||||
:
|
:
|
||||||
fUARTEnabled(true),
|
fUARTEnabled(true),
|
||||||
fUARTBase(base)
|
fUARTBase(base)
|
||||||
{
|
{
|
||||||
// TODO: Nice, but not required
|
barrier();
|
||||||
#if 0
|
|
||||||
// ** Loopback test
|
// ** Loopback test
|
||||||
uint32 cr = PL01x_CR_UARTEN;
|
uint32 cr = PL01x_CR_UARTEN;
|
||||||
// Enable UART
|
// Enable UART
|
||||||
@@ -37,23 +44,19 @@ UartPL011::UartPL011(addr_t base)
|
|||||||
// Write a 0 to the port and wait for confim..
|
// Write a 0 to the port and wait for confim..
|
||||||
WriteUart(PL01x_DR, 0);
|
WriteUart(PL01x_DR, 0);
|
||||||
|
|
||||||
while (ReadUart(PL01x_FR) & PL01x_FR_BUSY);
|
while (ReadUart(PL01x_FR) & PL01x_FR_BUSY)
|
||||||
// Wait for xmit on loopback
|
barrier();
|
||||||
|
|
||||||
// ** Disable loopback, enable uart
|
// ** Disable loopback, enable uart
|
||||||
cr = PL01x_CR_UARTEN | PL011_CR_RXE | PL011_CR_TXE;
|
cr = PL01x_CR_UARTEN | PL011_CR_RXE | PL011_CR_TXE;
|
||||||
WriteUart(PL011_CR, cr);
|
WriteUart(PL011_CR, cr);
|
||||||
|
|
||||||
// Enable DMA to received request outputs
|
|
||||||
WriteUart(PL011_DMACR, PL011_DMAONERR);
|
|
||||||
|
|
||||||
// ** Clear interrupts
|
// ** Clear interrupts
|
||||||
WriteUart(PL011_ICR, PL011_OEIS | PL011_BEIS
|
WriteUart(PL011_ICR, PL011_OEIS | PL011_BEIS
|
||||||
| PL011_PEIS | PL011_FEIS);
|
| PL011_PEIS | PL011_FEIS);
|
||||||
|
|
||||||
// Set Rx timeout interrupt mask and Rx interrput mask
|
// ** Disable interrupts
|
||||||
WriteUart(PL011_IMSC, PL011_RTIM | PL011_RXIM);
|
WriteUart(PL011_IMSC, 0);
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -134,9 +137,11 @@ int
|
|||||||
UartPL011::PutChar(char c)
|
UartPL011::PutChar(char c)
|
||||||
{
|
{
|
||||||
if (fUARTEnabled == true) {
|
if (fUARTEnabled == true) {
|
||||||
|
// Wait until there is room in fifo
|
||||||
|
while ((ReadUart(PL01x_FR) & PL01x_FR_TXFF) != 0)
|
||||||
|
barrier();
|
||||||
|
|
||||||
WriteUart(PL01x_DR, c);
|
WriteUart(PL01x_DR, c);
|
||||||
// Empty the transmit buffer
|
|
||||||
FlushTx();
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -155,12 +160,16 @@ UartPL011::GetChar(bool wait)
|
|||||||
void
|
void
|
||||||
UartPL011::FlushTx()
|
UartPL011::FlushTx()
|
||||||
{
|
{
|
||||||
while (ReadUart(PL01x_FR) & PL01x_FR_TXFF);
|
// Wait until transmit fifo empty
|
||||||
|
while ((ReadUart(PL01x_FR) & PL011_FR_TXFE) == 0)
|
||||||
|
barrier();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
UartPL011::FlushRx()
|
UartPL011::FlushRx()
|
||||||
{
|
{
|
||||||
#warning ARM Amba PL011 UART incomplete
|
// Wait until receive fifo empty
|
||||||
|
while ((ReadUart(PL01x_FR) & PL01x_FR_RXFE) == 0)
|
||||||
|
barrier();
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user