summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPavel Pisa <pisa@cmp.felk.cvut.cz>2016-07-22 21:15:55 +0200
committerPavel Pisa <pisa@cmp.felk.cvut.cz>2016-10-02 11:31:19 +0200
commit94e3c8384ff2573877d61f387eb090e2e5e12aff (patch)
tree28d4b952029bccb39cc189b701168c21557c44e6
parentbsp/tms570: regenerate preinstall makefile by bootstrap -p. (diff)
downloadrtems-94e3c8384ff2573877d61f387eb090e2e5e12aff.tar.bz2
bsp/tms570: ensure that change of SCI baudrate is not applied in the middle of character Tx.
The rtems_monitor_task() setups/updates termios attributes of the opened TTY and if there is ongoing some other output it leads to the stuck. It would be better to use some termios API function which would call drainOutput() in rtems/cpukit/libcsupport/src/termios.c. But functionality is not accessible outside of core termios implementation. The loop waiting for last character to be sent has to be there anyway because hardware does not provide Tx machine/shift register empty interrupt. Closes #2794
-rw-r--r--c/src/lib/libbsp/arm/tms570/console/tms570-sci.c25
1 files changed, 23 insertions, 2 deletions
diff --git a/c/src/lib/libbsp/arm/tms570/console/tms570-sci.c b/c/src/lib/libbsp/arm/tms570/console/tms570-sci.c
index 4464859dc0..6651cd83eb 100644
--- a/c/src/lib/libbsp/arm/tms570/console/tms570-sci.c
+++ b/c/src/lib/libbsp/arm/tms570/console/tms570-sci.c
@@ -247,9 +247,31 @@ static bool tms570_sci_set_attributes(
rtems_interrupt_lock_context lock_context;
int32_t bauddiv;
int32_t baudrate;
+ uint32_t flr_tx_ready = TMS570_SCI_FLR_TX_EMPTY | TMS570_SCI_FLR_TX_EMPTY;
+
+ /* Baud rate */
+ baudrate = rtems_termios_baud_to_number(cfgetospeed(t));
rtems_termios_device_lock_acquire(base, &lock_context);
+ while ( (ctx->regs->GCR1 & TMS570_SCI_GCR1_TXENA) &&
+ (ctx->regs->FLR & flr_tx_ready) != flr_tx_ready) {
+ /*
+ * There are pending characters in the hardware,
+ * change in the middle of the character Tx leads
+ * to disturb of the character and SCI engine
+ */
+ rtems_interval tw;
+
+ rtems_termios_device_lock_release(base, &lock_context);
+
+ tw = rtems_clock_get_ticks_per_second();
+ tw = tw * 5 / baudrate + 1;
+ rtems_task_wake_after( tw );
+
+ rtems_termios_device_lock_acquire(base, &lock_context);
+ }
+
ctx->regs->GCR1 &= ~( TMS570_SCI_GCR1_SWnRST | TMS570_SCI_GCR1_TXENA |
TMS570_SCI_GCR1_RXENA );
@@ -276,8 +298,7 @@ static bool tms570_sci_set_attributes(
ctx->regs->GCR1 &= ~TMS570_SCI_GCR1_PARITY_ENA;
}
- /* Baud rate */
- baudrate = rtems_termios_baud_to_number(cfgetospeed(t));
+ /* Apply baudrate to the hardware */
baudrate *= 2 * 16;
bauddiv = (BSP_PLL_OUT_CLOCK + baudrate / 2) / baudrate;
ctx->regs->BRS = bauddiv;