diff options
author | Thomas Doerfler <Thomas.Doerfler@embedded-brains.de> | 2008-11-18 11:28:53 +0000 |
---|---|---|
committer | Thomas Doerfler <Thomas.Doerfler@embedded-brains.de> | 2008-11-18 11:28:53 +0000 |
commit | d65b2da6cf673d0092203faa361185f25aa95f86 (patch) | |
tree | 897b9fc85c37a5de94c3ec5e72435e4f0d41855b /c/src/libchip | |
parent | console/console.c: Update for new NS16550 polled write function. (diff) | |
download | rtems-d65b2da6cf673d0092203faa361185f25aa95f86.tar.bz2 |
libchip/serial/ns16550.c: Transmit the character in the polled write
function within a critical section for printk() compatibility.
Diffstat (limited to 'c/src/libchip')
-rw-r--r-- | c/src/libchip/serial/ns16550.c | 63 |
1 files changed, 29 insertions, 34 deletions
diff --git a/c/src/libchip/serial/ns16550.c b/c/src/libchip/serial/ns16550.c index 32f7f5b467..88675bde7b 100644 --- a/c/src/libchip/serial/ns16550.c +++ b/c/src/libchip/serial/ns16550.c @@ -183,44 +183,39 @@ NS16550_STATIC int ns16550_close( return(RTEMS_SUCCESSFUL); } -/* - * ns16550_write_polled +/** + * @brief Polled write for NS16550. */ - -NS16550_STATIC void ns16550_write_polled( - int minor, - char cChar -) +NS16550_STATIC void ns16550_write_polled( int minor, char c) { - uint32_t pNS16550; - unsigned char ucLineStatus; - getRegister_f getReg; - setRegister_f setReg; - - pNS16550 = Console_Port_Tbl[minor].ulCtrlPort1; - getReg = Console_Port_Tbl[minor].getRegister; - setReg = Console_Port_Tbl[minor].setRegister; + uint32_t port = Console_Port_Tbl [minor].ulCtrlPort1; + getRegister_f get = Console_Port_Tbl [minor].getRegister; + setRegister_f set = Console_Port_Tbl [minor].setRegister; + uint32_t status; + rtems_interrupt_level level; + + while (1) { + /* Try to transmit the character in a critical section */ + rtems_interrupt_disable( level); + + /* Read the transmitter holding register and check it */ + status = get( port, NS16550_LINE_STATUS); + if ((status & SP_LSR_THOLD) != 0) { + /* Transmit character */ + set( port, NS16550_TRANSMIT_BUFFER, c); + + /* Finished */ + rtems_interrupt_enable( level); + break; + } else { + rtems_interrupt_enable( level); + } - /* - * wait for transmitter holding register to be empty - */ - ucLineStatus = (*getReg)(pNS16550, NS16550_LINE_STATUS); - while ((ucLineStatus & SP_LSR_THOLD) == 0) { - /* - * Yield while we wait - */ -#if 0 - if(_System_state_Is_up(_System_state_Get())) { - rtems_task_wake_after(RTEMS_YIELD_PROCESSOR); - } -#endif - ucLineStatus = (*getReg)(pNS16550, NS16550_LINE_STATUS); + /* Wait for transmitter holding register to be empty */ + do { + status = get( port, NS16550_LINE_STATUS); + } while ((status & SP_LSR_THOLD) == 0); } - - /* - * transmit character - */ - (*setReg)(pNS16550, NS16550_TRANSMIT_BUFFER, cChar); } /* |