diff options
author | patacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3> | 2009-05-19 22:51:33 +0000 |
---|---|---|
committer | patacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3> | 2009-05-19 22:51:33 +0000 |
commit | 30944c3d567f2e5e70e869c6ef6e08f3a69bc093 (patch) | |
tree | f83fc0714d984faafa7db1db3890b95723e0348d | |
parent | ccc7221d0cd7b18c5e2bcab40aa648135ff970d1 (diff) | |
download | px4-nuttx-30944c3d567f2e5e70e869c6ef6e08f3a69bc093.tar.gz px4-nuttx-30944c3d567f2e5e70e869c6ef6e08f3a69bc093.tar.bz2 px4-nuttx-30944c3d567f2e5e70e869c6ef6e08f3a69bc093.zip |
Fix BRD calculation; Handle edge interrupts
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@1804 42af7a65-404d-4744-a932-0658087f49c3
-rw-r--r-- | nuttx/arch/arm/src/lm3s/lm3s_serial.c | 30 |
1 files changed, 25 insertions, 5 deletions
diff --git a/nuttx/arch/arm/src/lm3s/lm3s_serial.c b/nuttx/arch/arm/src/lm3s/lm3s_serial.c index 7c4275d26..04a9bdbf0 100644 --- a/nuttx/arch/arm/src/lm3s/lm3s_serial.c +++ b/nuttx/arch/arm/src/lm3s/lm3s_serial.c @@ -398,9 +398,9 @@ static int up_setup(struct uart_dev_s *dev) * write to the UARTLCRH register for the changes to take effect. ..." */ - den = priv->baud << 16; + den = priv->baud << 4; brdi = SYSCLK_FREQUENCY / den; - remainder = priv->baud - den * brdi; + remainder = SYSCLK_FREQUENCY - den * brdi; divfrac = ((remainder << 6) + (den >> 1)) / den; up_serialout(priv, LM3S_UART_IBRD_OFFSET, brdi); @@ -465,7 +465,7 @@ static int up_setup(struct uart_dev_s *dev) /* Enable the FIFOs */ -#ifndef CONFIG_SUPPRESS_UART_CONFIG +#ifdef CONFIG_SUPPRESS_UART_CONFIG lcrh = up_serialin(priv, LM3S_UART_LCRH_OFFSET); #endif lcrh |= UART_LCRH_FEN; @@ -473,7 +473,7 @@ static int up_setup(struct uart_dev_s *dev) /* Enable Rx, Tx, and the UART */ -#ifndef CONFIG_SUPPRESS_UART_CONFIG +#ifdef CONFIG_SUPPRESS_UART_CONFIG ctl = up_serialin(priv, LM3S_UART_CTL_OFFSET); #endif ctl |= (UART_CTL_UARTEN|UART_CTL_TXE|UART_CTL_RXE); @@ -760,18 +760,38 @@ static void up_send(struct uart_dev_s *dev, int ch) static void up_txint(struct uart_dev_s *dev, boolean enable) { struct up_dev_s *priv = (struct up_dev_s*)dev->priv; + irqstate_t flags; + + flags = irqsave(); if (enable) { /* Set to receive an interrupt when the TX fifo is half emptied */ + #ifndef CONFIG_SUPPRESS_SERIAL_INTS priv->im |= UART_IM_TXIM; + up_serialout(priv, LM3S_UART_IM_OFFSET, priv->im); + + /* The serial driver wants an interrupt here, but will not get get + * one unless we "prime the pump." I believe that this is because + * behave like a level interrupt and the LM3S interrupts behave + * (at least by default) like edge interrupts. + * + * In any event, faking a TX interrupt here solves the problem; + * Call uart_xmitchars() just as would have been done if we recieved + * the TX interrupt. + */ + + uart_xmitchars(dev); #endif } else { + /* Disable the TX interrupt */ + priv->im &= ~UART_IM_TXIM; + up_serialout(priv, LM3S_UART_IM_OFFSET, priv->im); } - up_serialout(priv, LM3S_UART_IM_OFFSET, priv->im); + irqrestore(flags); } /**************************************************************************** |