Rocksolid Light

Welcome to novaBBS (click a section below)

mail  files  register  newsreader  groups  login

Message-ID:  

All syllogisms have three parts, therefore this is not a syllogism.


devel / comp.arch.embedded / Re: LPC1788: uart TX interrupt problem

SubjectAuthor
* LPC1788: uart TX interrupt problempozz
+* Re: LPC1788: uart TX interrupt problemRick C
|`* Re: LPC1788: uart TX interrupt problempozz
| `- Re: LPC1788: uart TX interrupt problemRick C
`* Re: LPC1788: uart TX interrupt problemChris
 `* Re: LPC1788: uart TX interrupt problempozz
  `- Re: LPC1788: uart TX interrupt problemRick C

1
LPC1788: uart TX interrupt problem

<u40tme$3j0p6$1@dont-email.me>

  copy mid

https://www.novabbs.com/devel/article-flat.php?id=1592&group=comp.arch.embedded#1592

  copy link   Newsgroups: comp.arch.embedded
Path: i2pn2.org!i2pn.org!eternal-september.org!news.eternal-september.org!.POSTED!not-for-mail
From: pozzu...@gmail.com (pozz)
Newsgroups: comp.arch.embedded
Subject: LPC1788: uart TX interrupt problem
Date: Tue, 16 May 2023 23:47:58 +0200
Organization: A noiseless patient Spider
Lines: 74
Message-ID: <u40tme$3j0p6$1@dont-email.me>
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8; format=flowed
Content-Transfer-Encoding: 7bit
Injection-Date: Tue, 16 May 2023 21:47:58 -0000 (UTC)
Injection-Info: dont-email.me; posting-host="9d7a0ce860a660ab86c457fef50f8480";
logging-data="3769126"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX1/t1oc6z22N5lbqwxtSHYVDmJsWg/I0DlM="
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:102.0) Gecko/20100101
Thunderbird/102.11.0
Cancel-Lock: sha1:JheHt33mvw9V8bWiwI+QRnii7t0=
 by: pozz - Tue, 16 May 2023 21:47 UTC

This issue is very difficult to understand when you see it, so it's
quite impossible to find the solution here in a newsgroup. However,
after scratching my head for long days, I want to try. Maybe some guy
here could enlighten me on the right direction.

I have a critical issue with a board based on LPC1788, specifically with
UART peripheral. The issue is very annoying because it brings to a non
funcional device and moreover because it happens rarely, maybe after
many months. So it's very difficult to see it in lab and try some debug.
This device works usually without supply interruption (it is powered by
mains and a lead-acid battery in case of black-out).

The interesting parts of the UART driver (written by others) is here[1].
It's an interrupt-based driver with two circular buffers: one for RX and
one for TX (the uart can be configured to use callbacks, but I use
circular buffers). When the application wants to write, data is pushed
in a TX FIFO in RAM and TX interrupt is enabled (sending the first byte,
see below). In the TX interrupt the next data is popped up from the TX
FIFO and written to the TX register of UART peripheral.

There are some complications.

The driver adds a few dummy bytes before real transmission. TX and RX
signals are connected to an external RS485 transceiver. The direction is
connected to a GPIO.
If the TX is in idle and the application writes the first byte to
transmit (uart_putchar), some dummy bytes are sent first and the real
data pushed in TX FIFO in RAM. After the last dummy byte is transmitted,
the direction toggles to enable transmission over RS485 bus. In this way
the author implemented a small delay that is useful when the receiver
device on the bus is slow changing its direction from TX to RX.

Another point is the use of TX interrupt. This MCU has an hw TX FIFO
that is enabled, but *not* used. Indeed, only a byte at a time is pushed
in hw FIFO. In this case, the TX interrupt is triggered only when the
data is shifted out completely. This way, we can enable RS485
transmitter after the last dummy byte at the exact timing
(txstart_callback). After the last byte was transmitted, the UART TX
interrupt is disabled *and* the RS485 transitter is disabled
(txend_callback).

In many MCUs, if the TX FIFO (or single register) is empty and the TX
interrupt is enabled, the interrupt is triggered immediately. This isn't
the case in this MCU, where you need to send at least the first byte to
trigger the interrupt (after it's shifted out).

When the issue happens (as I said, even after many months), the RS485
direction is stuck high (transmission enabled), but I didn't see any
activity on TX UART signal. This should mean that the TX interrupt is
disabled.
Consequently, the device can't receive nothing fro the bus (the
transceiver is half-duplex). Other functions of the device are ok even
in this situation. For example, I can see the status LED blinking as usual.

The uart data structure is configured in the following way:

* rx_callback=NULL
* tx_callback=NULL
* txstart_callback: set the GPIO of RS485 direction high
* txend_callback: set the GPIO of RS485 direction low
* txdummy_num=1
* txdummy_value=0xFF (it isn't important here)

I can't understand how the MCU reaches this incorrect state (RS485
transmitter always enabled). With two consecutive instructions the
driver disables the TX interrupt after last byte was transmitted
completely and the direction is set low.

I know I could refactor the UART driver, but at the moment I'd like to
fix this issue without rewriting so low-level part of the firmware.

Any idea?

[1] https://justpaste.it/8swct

Re: LPC1788: uart TX interrupt problem

<35e16f29-dbcc-47bd-9098-071482285e64n@googlegroups.com>

  copy mid

https://www.novabbs.com/devel/article-flat.php?id=1593&group=comp.arch.embedded#1593

  copy link   Newsgroups: comp.arch.embedded
X-Received: by 2002:ad4:4b62:0:b0:61a:facb:3618 with SMTP id m2-20020ad44b62000000b0061afacb3618mr7011901qvx.9.1684275752906;
Tue, 16 May 2023 15:22:32 -0700 (PDT)
X-Received: by 2002:a05:622a:2595:b0:3f4:e662:3fa8 with SMTP id
cj21-20020a05622a259500b003f4e6623fa8mr136111qtb.4.1684275752680; Tue, 16 May
2023 15:22:32 -0700 (PDT)
Path: i2pn2.org!i2pn.org!usenet.blueworldhosting.com!diablo1.usenet.blueworldhosting.com!peer01.iad!feed-me.highwinds-media.com!news.highwinds-media.com!news-out.google.com!nntp.google.com!postnews.google.com!google-groups.googlegroups.com!not-for-mail
Newsgroups: comp.arch.embedded
Date: Tue, 16 May 2023 15:22:32 -0700 (PDT)
In-Reply-To: <u40tme$3j0p6$1@dont-email.me>
Injection-Info: google-groups.googlegroups.com; posting-host=2605:ba00:3228:c1c:359c:27b3:43cd:2ee;
posting-account=I-_H_woAAAA9zzro6crtEpUAyIvzd19b
NNTP-Posting-Host: 2605:ba00:3228:c1c:359c:27b3:43cd:2ee
References: <u40tme$3j0p6$1@dont-email.me>
User-Agent: G2/1.0
MIME-Version: 1.0
Message-ID: <35e16f29-dbcc-47bd-9098-071482285e64n@googlegroups.com>
Subject: Re: LPC1788: uart TX interrupt problem
From: gnuarm.d...@gmail.com (Rick C)
Injection-Date: Tue, 16 May 2023 22:22:32 +0000
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable
X-Received-Bytes: 1637
 by: Rick C - Tue, 16 May 2023 22:22 UTC

I can't say I follow some of your description, in particular the FIFO and getting an interrupt when the last character is transmitted completely (meaning the shift register is empty and ready for a new character). The FIFO knows nothing of the transmitter shift register status. Perhaps I did not read carefully enough?

--

Rick C.

- Get 1,000 miles of free Supercharging
- Tesla referral code - https://ts.la/richard11209

Re: LPC1788: uart TX interrupt problem

<fdbc47a5-e3e8-42e2-b639-4e7886e3a8bcn@googlegroups.com>

  copy mid

https://www.novabbs.com/devel/article-flat.php?id=1594&group=comp.arch.embedded#1594

  copy link   Newsgroups: comp.arch.embedded
X-Received: by 2002:a37:5d5:0:b0:759:32d8:eba7 with SMTP id 204-20020a3705d5000000b0075932d8eba7mr222129qkf.7.1684281246115;
Tue, 16 May 2023 16:54:06 -0700 (PDT)
X-Received: by 2002:ac8:59c5:0:b0:3f5:16af:17e4 with SMTP id
f5-20020ac859c5000000b003f516af17e4mr4256252qtf.2.1684281245775; Tue, 16 May
2023 16:54:05 -0700 (PDT)
Path: i2pn2.org!i2pn.org!weretis.net!feeder6.news.weretis.net!usenet.blueworldhosting.com!diablo1.usenet.blueworldhosting.com!peer01.iad!feed-me.highwinds-media.com!news.highwinds-media.com!news-out.google.com!nntp.google.com!postnews.google.com!google-groups.googlegroups.com!not-for-mail
Newsgroups: comp.arch.embedded
Date: Tue, 16 May 2023 16:54:05 -0700 (PDT)
In-Reply-To: <u40tme$3j0p6$1@dont-email.me>
Injection-Info: google-groups.googlegroups.com; posting-host=202.67.75.58; posting-account=Qldn6woAAADpKSXOFggZ2oKrkHh1H-fQ
NNTP-Posting-Host: 202.67.75.58
References: <u40tme$3j0p6$1@dont-email.me>
User-Agent: G2/1.0
MIME-Version: 1.0
Message-ID: <fdbc47a5-e3e8-42e2-b639-4e7886e3a8bcn@googlegroups.com>
Subject: Re: LPC1788: uart TX interrupt problem
From: chris.ho...@gmail.com (Chris)
Injection-Date: Tue, 16 May 2023 23:54:06 +0000
Content-Type: text/plain; charset="UTF-8"
X-Received-Bytes: 5542
 by: Chris - Tue, 16 May 2023 23:54 UTC

On Wednesday, 17 May 2023 at 07:49:53 UTC+10, pozz wrote:
> This issue is very difficult to understand when you see it, so it's
> quite impossible to find the solution here in a newsgroup. However,
> after scratching my head for long days, I want to try. Maybe some guy
> here could enlighten me on the right direction.
>
> I have a critical issue with a board based on LPC1788, specifically with
> UART peripheral. The issue is very annoying because it brings to a non
> funcional device and moreover because it happens rarely, maybe after
> many months. So it's very difficult to see it in lab and try some debug.
> This device works usually without supply interruption (it is powered by
> mains and a lead-acid battery in case of black-out).
>
> The interesting parts of the UART driver (written by others) is here[1].
> It's an interrupt-based driver with two circular buffers: one for RX and
> one for TX (the uart can be configured to use callbacks, but I use
> circular buffers). When the application wants to write, data is pushed
> in a TX FIFO in RAM and TX interrupt is enabled (sending the first byte,
> see below). In the TX interrupt the next data is popped up from the TX
> FIFO and written to the TX register of UART peripheral.
>
> There are some complications.
>
> The driver adds a few dummy bytes before real transmission. TX and RX
> signals are connected to an external RS485 transceiver. The direction is
> connected to a GPIO.
> If the TX is in idle and the application writes the first byte to
> transmit (uart_putchar), some dummy bytes are sent first and the real
> data pushed in TX FIFO in RAM. After the last dummy byte is transmitted,
> the direction toggles to enable transmission over RS485 bus. In this way
> the author implemented a small delay that is useful when the receiver
> device on the bus is slow changing its direction from TX to RX.
>
> Another point is the use of TX interrupt. This MCU has an hw TX FIFO
> that is enabled, but *not* used. Indeed, only a byte at a time is pushed
> in hw FIFO. In this case, the TX interrupt is triggered only when the
> data is shifted out completely. This way, we can enable RS485
> transmitter after the last dummy byte at the exact timing
> (txstart_callback). After the last byte was transmitted, the UART TX
> interrupt is disabled *and* the RS485 transitter is disabled
> (txend_callback).
>
> In many MCUs, if the TX FIFO (or single register) is empty and the TX
> interrupt is enabled, the interrupt is triggered immediately. This isn't
> the case in this MCU, where you need to send at least the first byte to
> trigger the interrupt (after it's shifted out).
>
> When the issue happens (as I said, even after many months), the RS485
> direction is stuck high (transmission enabled), but I didn't see any
> activity on TX UART signal. This should mean that the TX interrupt is
> disabled.
> Consequently, the device can't receive nothing fro the bus (the
> transceiver is half-duplex). Other functions of the device are ok even
> in this situation. For example, I can see the status LED blinking as usual.
>
> The uart data structure is configured in the following way:
>
> * rx_callback=NULL
> * tx_callback=NULL
> * txstart_callback: set the GPIO of RS485 direction high
> * txend_callback: set the GPIO of RS485 direction low
> * txdummy_num=1
> * txdummy_value=0xFF (it isn't important here)
>
> I can't understand how the MCU reaches this incorrect state (RS485
> transmitter always enabled). With two consecutive instructions the
> driver disables the TX interrupt after last byte was transmitted
> completely and the direction is set low.
>
> I know I could refactor the UART driver, but at the moment I'd like to
> fix this issue without rewriting so low-level part of the firmware.
>
> Any idea?
>
> [1] https://justpaste.it/8swct

Which variant of LCP1788?
Which UART within the MCU?

Looking at the generic datasheet there are up to 5 UARTs. UART1 is described as supporting RS485 together with modem handshake signals DTR/DSR, RTS/CTS etc which surely could be utilised for Tx/Rx direction.

Another feature is that the register layout for the UARTs are 16C550 standard compliant so re-writing a driver from scratch should not be necessary (assuming plenty of freely available source code?).

--
Cheers,
Chris.

Re: LPC1788: uart TX interrupt problem

<u42cb0$3ro17$1@dont-email.me>

  copy mid

https://www.novabbs.com/devel/article-flat.php?id=1595&group=comp.arch.embedded#1595

  copy link   Newsgroups: comp.arch.embedded
Path: i2pn2.org!i2pn.org!eternal-september.org!news.eternal-september.org!.POSTED!not-for-mail
From: pozzu...@gmail.com (pozz)
Newsgroups: comp.arch.embedded
Subject: Re: LPC1788: uart TX interrupt problem
Date: Wed, 17 May 2023 13:04:00 +0200
Organization: A noiseless patient Spider
Lines: 33
Message-ID: <u42cb0$3ro17$1@dont-email.me>
References: <u40tme$3j0p6$1@dont-email.me>
<35e16f29-dbcc-47bd-9098-071482285e64n@googlegroups.com>
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8; format=flowed
Content-Transfer-Encoding: 7bit
Injection-Date: Wed, 17 May 2023 11:04:00 -0000 (UTC)
Injection-Info: dont-email.me; posting-host="751c36e7d82c600923114dcded193c5b";
logging-data="4055079"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX1+emmeKITceU3etZIkT3vKrGpYt0Lquv/o="
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:102.0) Gecko/20100101
Thunderbird/102.11.0
Cancel-Lock: sha1:Emt2dIpOcjKkL01MRcCm5rWDD5o=
In-Reply-To: <35e16f29-dbcc-47bd-9098-071482285e64n@googlegroups.com>
 by: pozz - Wed, 17 May 2023 11:04 UTC

Il 17/05/2023 00:22, Rick C ha scritto:
> I can't say I follow some of your description, in particular the FIFO and getting an interrupt when the last character is transmitted completely (meaning the shift register is empty and ready for a new character). The FIFO knows nothing of the transmitter shift register status. Perhaps I did not read carefully enough?

I agree with you, the TX interrupt is a mess on these MCUs. This is what
is written in the datasheet:

> The UARTn THRE interrupt (UnIIR[3:1] = 001) is a third level interrupt and is activated
> when the UARTn THR FIFO is empty provided certain initialization conditions have been
> met. These initialization conditions are intended to give the UARTn THR FIFO a chance to
> fill up with data to eliminate many THRE interrupts from occurring at system start-up. The
> initialization conditions implement a one character delay minus the stop bit whenever
> THRE = 1 and there have not been at least two characters in the UnTHR at one time
> since the last THRE = 1 event. This delay is provided to give the CPU time to write data to
> UnTHR without a THRE interrupt to decode and service. A THRE interrupt is set
> immediately if the UARTn THR FIFO has held two or more characters at one time and
> currently, the UnTHR is empty. The THRE interrupt is reset when a UnTHR write occurs or
> a read of the UnIIR occurs and the THRE is the highest interrupt (UnIIR[3:1] = 001).

So you were right, FIFO knows nothing of transmitter shift register. The
UART of this MCU implements a delay of one full frame (minus stop bit
length), that is exactly the time when the shift register finished its
job of sending bits (and it's the right time to enable/disable the
driver of external transceiver).

Here a point to stress is about the first interrupt. In uart_putchar(),
when the TX is idle (THRE interrupt is disabled), the driver not only
needs to enable THRE interrupt, it also needs to push the first byte
into hw TX FIFO, otherwise no interrupt will be fired.
After the delay above, the THRE interrupt is fired. The driver push
another byte in the hw TX FIFO and, after the same delay, the second
interrupt is fired and so on. When the last byte interrupt is fired, the
THRE interrupt is disabled *and* the direction is set back to RX.

Re: LPC1788: uart TX interrupt problem

<u42d8q$3s045$1@dont-email.me>

  copy mid

https://www.novabbs.com/devel/article-flat.php?id=1596&group=comp.arch.embedded#1596

  copy link   Newsgroups: comp.arch.embedded
Path: i2pn2.org!i2pn.org!eternal-september.org!news.eternal-september.org!.POSTED!not-for-mail
From: pozzu...@gmail.com (pozz)
Newsgroups: comp.arch.embedded
Subject: Re: LPC1788: uart TX interrupt problem
Date: Wed, 17 May 2023 13:19:54 +0200
Organization: A noiseless patient Spider
Lines: 97
Message-ID: <u42d8q$3s045$1@dont-email.me>
References: <u40tme$3j0p6$1@dont-email.me>
<fdbc47a5-e3e8-42e2-b639-4e7886e3a8bcn@googlegroups.com>
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8; format=flowed
Content-Transfer-Encoding: 7bit
Injection-Date: Wed, 17 May 2023 11:19:54 -0000 (UTC)
Injection-Info: dont-email.me; posting-host="751c36e7d82c600923114dcded193c5b";
logging-data="4063365"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX1822d91h2xp7709NiqdZt+m0JonNGMJoLM="
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:102.0) Gecko/20100101
Thunderbird/102.11.0
Cancel-Lock: sha1:GxH8r3T5sV6Q/0eVkgeZA8c+1ZY=
In-Reply-To: <fdbc47a5-e3e8-42e2-b639-4e7886e3a8bcn@googlegroups.com>
 by: pozz - Wed, 17 May 2023 11:19 UTC

Il 17/05/2023 01:54, Chris ha scritto:
> On Wednesday, 17 May 2023 at 07:49:53 UTC+10, pozz wrote:
>> This issue is very difficult to understand when you see it, so it's
>> quite impossible to find the solution here in a newsgroup. However,
>> after scratching my head for long days, I want to try. Maybe some guy
>> here could enlighten me on the right direction.
>>
>> I have a critical issue with a board based on LPC1788, specifically with
>> UART peripheral. The issue is very annoying because it brings to a non
>> funcional device and moreover because it happens rarely, maybe after
>> many months. So it's very difficult to see it in lab and try some debug.
>> This device works usually without supply interruption (it is powered by
>> mains and a lead-acid battery in case of black-out).
>>
>> The interesting parts of the UART driver (written by others) is here[1].
>> It's an interrupt-based driver with two circular buffers: one for RX and
>> one for TX (the uart can be configured to use callbacks, but I use
>> circular buffers). When the application wants to write, data is pushed
>> in a TX FIFO in RAM and TX interrupt is enabled (sending the first byte,
>> see below). In the TX interrupt the next data is popped up from the TX
>> FIFO and written to the TX register of UART peripheral.
>>
>> There are some complications.
>>
>> The driver adds a few dummy bytes before real transmission. TX and RX
>> signals are connected to an external RS485 transceiver. The direction is
>> connected to a GPIO.
>> If the TX is in idle and the application writes the first byte to
>> transmit (uart_putchar), some dummy bytes are sent first and the real
>> data pushed in TX FIFO in RAM. After the last dummy byte is transmitted,
>> the direction toggles to enable transmission over RS485 bus. In this way
>> the author implemented a small delay that is useful when the receiver
>> device on the bus is slow changing its direction from TX to RX.
>>
>> Another point is the use of TX interrupt. This MCU has an hw TX FIFO
>> that is enabled, but *not* used. Indeed, only a byte at a time is pushed
>> in hw FIFO. In this case, the TX interrupt is triggered only when the
>> data is shifted out completely. This way, we can enable RS485
>> transmitter after the last dummy byte at the exact timing
>> (txstart_callback). After the last byte was transmitted, the UART TX
>> interrupt is disabled *and* the RS485 transitter is disabled
>> (txend_callback).
>>
>> In many MCUs, if the TX FIFO (or single register) is empty and the TX
>> interrupt is enabled, the interrupt is triggered immediately. This isn't
>> the case in this MCU, where you need to send at least the first byte to
>> trigger the interrupt (after it's shifted out).
>>
>> When the issue happens (as I said, even after many months), the RS485
>> direction is stuck high (transmission enabled), but I didn't see any
>> activity on TX UART signal. This should mean that the TX interrupt is
>> disabled.
>> Consequently, the device can't receive nothing fro the bus (the
>> transceiver is half-duplex). Other functions of the device are ok even
>> in this situation. For example, I can see the status LED blinking as usual.
>>
>> The uart data structure is configured in the following way:
>>
>> * rx_callback=NULL
>> * tx_callback=NULL
>> * txstart_callback: set the GPIO of RS485 direction high
>> * txend_callback: set the GPIO of RS485 direction low
>> * txdummy_num=1
>> * txdummy_value=0xFF (it isn't important here)
>>
>> I can't understand how the MCU reaches this incorrect state (RS485
>> transmitter always enabled). With two consecutive instructions the
>> driver disables the TX interrupt after last byte was transmitted
>> completely and the direction is set low.
>>
>> I know I could refactor the UART driver, but at the moment I'd like to
>> fix this issue without rewriting so low-level part of the firmware.
>>
>> Any idea?
>>
>> [1] https://justpaste.it/8swct
>
> Which variant of LCP1788?

LPC1788FBD208

> Which UART within the MCU?

UART2

> Looking at the generic datasheet there are up to 5 UARTs. UART1 is described as supporting RS485 together with modem handshake signals DTR/DSR, RTS/CTS etc which surely could be utilised for Tx/Rx direction.

UART2 can manage autonomously an external transceiver direction, but it
is not used in my driver. I think because of dummy bytes that mustn't be
seen on the wire.

> Another feature is that the register layout for the UARTs are 16C550 standard compliant so re-writing a driver from scratch should not be necessary (assuming plenty of freely available source code?).

I don't know 16C550. Do you think the UART in LPC1788 is compatible with
16C550? Could you suggest any source code out there?

Re: LPC1788: uart TX interrupt problem

<c7535a1a-d8d8-4da0-a675-614426c9cda9n@googlegroups.com>

  copy mid

https://www.novabbs.com/devel/article-flat.php?id=1597&group=comp.arch.embedded#1597

  copy link   Newsgroups: comp.arch.embedded
X-Received: by 2002:a05:622a:1994:b0:3f0:abe7:24a7 with SMTP id u20-20020a05622a199400b003f0abe724a7mr11583qtc.6.1684340984818;
Wed, 17 May 2023 09:29:44 -0700 (PDT)
X-Received: by 2002:a05:620a:31a0:b0:759:2fe:9931 with SMTP id
bi32-20020a05620a31a000b0075902fe9931mr96153qkb.15.1684340984559; Wed, 17 May
2023 09:29:44 -0700 (PDT)
Path: i2pn2.org!i2pn.org!weretis.net!feeder8.news.weretis.net!newsreader4.netcologne.de!news.netcologne.de!peer03.ams1!peer.ams1.xlned.com!news.xlned.com!peer03.iad!feed-me.highwinds-media.com!news.highwinds-media.com!news-out.google.com!nntp.google.com!postnews.google.com!google-groups.googlegroups.com!not-for-mail
Newsgroups: comp.arch.embedded
Date: Wed, 17 May 2023 09:29:44 -0700 (PDT)
In-Reply-To: <u42cb0$3ro17$1@dont-email.me>
Injection-Info: google-groups.googlegroups.com; posting-host=2605:ba00:3228:c1c:e833:9c05:c59c:a586;
posting-account=I-_H_woAAAA9zzro6crtEpUAyIvzd19b
NNTP-Posting-Host: 2605:ba00:3228:c1c:e833:9c05:c59c:a586
References: <u40tme$3j0p6$1@dont-email.me> <35e16f29-dbcc-47bd-9098-071482285e64n@googlegroups.com>
<u42cb0$3ro17$1@dont-email.me>
User-Agent: G2/1.0
MIME-Version: 1.0
Message-ID: <c7535a1a-d8d8-4da0-a675-614426c9cda9n@googlegroups.com>
Subject: Re: LPC1788: uart TX interrupt problem
From: gnuarm.d...@gmail.com (Rick C)
Injection-Date: Wed, 17 May 2023 16:29:44 +0000
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable
X-Received-Bytes: 4224
 by: Rick C - Wed, 17 May 2023 16:29 UTC

On Wednesday, May 17, 2023 at 7:06:00 AM UTC-4, pozz wrote:
> Il 17/05/2023 00:22, Rick C ha scritto:
> > I can't say I follow some of your description, in particular the FIFO and getting an interrupt when the last character is transmitted completely (meaning the shift register is empty and ready for a new character). The FIFO knows nothing of the transmitter shift register status. Perhaps I did not read carefully enough?
> I agree with you, the TX interrupt is a mess on these MCUs. This is what
> is written in the datasheet:
>
> > The UARTn THRE interrupt (UnIIR[3:1] = 001) is a third level interrupt and is activated
> > when the UARTn THR FIFO is empty provided certain initialization conditions have been
> > met. These initialization conditions are intended to give the UARTn THR FIFO a chance to
> > fill up with data to eliminate many THRE interrupts from occurring at system start-up. The
> > initialization conditions implement a one character delay minus the stop bit whenever
> > THRE = 1 and there have not been at least two characters in the UnTHR at one time
> > since the last THRE = 1 event. This delay is provided to give the CPU time to write data to
> > UnTHR without a THRE interrupt to decode and service. A THRE interrupt is set
> > immediately if the UARTn THR FIFO has held two or more characters at one time and
> > currently, the UnTHR is empty. The THRE interrupt is reset when a UnTHR write occurs or
> > a read of the UnIIR occurs and the THRE is the highest interrupt (UnIIR[3:1] = 001).
>
> So you were right, FIFO knows nothing of transmitter shift register. The
> UART of this MCU implements a delay of one full frame (minus stop bit
> length), that is exactly the time when the shift register finished its
> job of sending bits (and it's the right time to enable/disable the
> driver of external transceiver).
>
> Here a point to stress is about the first interrupt. In uart_putchar(),
> when the TX is idle (THRE interrupt is disabled), the driver not only
> needs to enable THRE interrupt, it also needs to push the first byte
> into hw TX FIFO, otherwise no interrupt will be fired.
> After the delay above, the THRE interrupt is fired. The driver push
> another byte in the hw TX FIFO and, after the same delay, the second
> interrupt is fired and so on. When the last byte interrupt is fired, the
> THRE interrupt is disabled *and* the direction is set back to RX.

This is why I prefer FPGAs to MCUs. I can design a perfectly functioning UART in less time than it will take you to figure this out.

--

Rick C.

+ Get 1,000 miles of free Supercharging
+ Tesla referral code - https://ts.la/richard11209

Re: LPC1788: uart TX interrupt problem

<20556953-413f-4640-abdf-a76e0f2c6130n@googlegroups.com>

  copy mid

https://www.novabbs.com/devel/article-flat.php?id=1598&group=comp.arch.embedded#1598

  copy link   Newsgroups: comp.arch.embedded
X-Received: by 2002:a05:620a:28cc:b0:759:1798:d849 with SMTP id l12-20020a05620a28cc00b007591798d849mr125550qkp.3.1684341170148;
Wed, 17 May 2023 09:32:50 -0700 (PDT)
X-Received: by 2002:a05:6214:a83:b0:5ef:4ecb:b47e with SMTP id
ev3-20020a0562140a8300b005ef4ecbb47emr53632qvb.8.1684341169716; Wed, 17 May
2023 09:32:49 -0700 (PDT)
Path: i2pn2.org!i2pn.org!eternal-september.org!news.eternal-september.org!feeder1.feed.usenet.farm!feed.usenet.farm!peer03.ams4!peer.am4.highwinds-media.com!peer03.iad!feed-me.highwinds-media.com!news.highwinds-media.com!news-out.google.com!nntp.google.com!postnews.google.com!google-groups.googlegroups.com!not-for-mail
Newsgroups: comp.arch.embedded
Date: Wed, 17 May 2023 09:32:49 -0700 (PDT)
In-Reply-To: <u42d8q$3s045$1@dont-email.me>
Injection-Info: google-groups.googlegroups.com; posting-host=2605:ba00:3228:c1c:e833:9c05:c59c:a586;
posting-account=I-_H_woAAAA9zzro6crtEpUAyIvzd19b
NNTP-Posting-Host: 2605:ba00:3228:c1c:e833:9c05:c59c:a586
References: <u40tme$3j0p6$1@dont-email.me> <fdbc47a5-e3e8-42e2-b639-4e7886e3a8bcn@googlegroups.com>
<u42d8q$3s045$1@dont-email.me>
User-Agent: G2/1.0
MIME-Version: 1.0
Message-ID: <20556953-413f-4640-abdf-a76e0f2c6130n@googlegroups.com>
Subject: Re: LPC1788: uart TX interrupt problem
From: gnuarm.d...@gmail.com (Rick C)
Injection-Date: Wed, 17 May 2023 16:32:50 +0000
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable
X-Received-Bytes: 7257
 by: Rick C - Wed, 17 May 2023 16:32 UTC

On Wednesday, May 17, 2023 at 7:22:07 AM UTC-4, pozz wrote:
> Il 17/05/2023 01:54, Chris ha scritto:
> > On Wednesday, 17 May 2023 at 07:49:53 UTC+10, pozz wrote:
> >> This issue is very difficult to understand when you see it, so it's
> >> quite impossible to find the solution here in a newsgroup. However,
> >> after scratching my head for long days, I want to try. Maybe some guy
> >> here could enlighten me on the right direction.
> >>
> >> I have a critical issue with a board based on LPC1788, specifically with
> >> UART peripheral. The issue is very annoying because it brings to a non
> >> funcional device and moreover because it happens rarely, maybe after
> >> many months. So it's very difficult to see it in lab and try some debug.
> >> This device works usually without supply interruption (it is powered by
> >> mains and a lead-acid battery in case of black-out).
> >>
> >> The interesting parts of the UART driver (written by others) is here[1].
> >> It's an interrupt-based driver with two circular buffers: one for RX and
> >> one for TX (the uart can be configured to use callbacks, but I use
> >> circular buffers). When the application wants to write, data is pushed
> >> in a TX FIFO in RAM and TX interrupt is enabled (sending the first byte,
> >> see below). In the TX interrupt the next data is popped up from the TX
> >> FIFO and written to the TX register of UART peripheral.
> >>
> >> There are some complications.
> >>
> >> The driver adds a few dummy bytes before real transmission. TX and RX
> >> signals are connected to an external RS485 transceiver. The direction is
> >> connected to a GPIO.
> >> If the TX is in idle and the application writes the first byte to
> >> transmit (uart_putchar), some dummy bytes are sent first and the real
> >> data pushed in TX FIFO in RAM. After the last dummy byte is transmitted,
> >> the direction toggles to enable transmission over RS485 bus. In this way
> >> the author implemented a small delay that is useful when the receiver
> >> device on the bus is slow changing its direction from TX to RX.
> >>
> >> Another point is the use of TX interrupt. This MCU has an hw TX FIFO
> >> that is enabled, but *not* used. Indeed, only a byte at a time is pushed
> >> in hw FIFO. In this case, the TX interrupt is triggered only when the
> >> data is shifted out completely. This way, we can enable RS485
> >> transmitter after the last dummy byte at the exact timing
> >> (txstart_callback). After the last byte was transmitted, the UART TX
> >> interrupt is disabled *and* the RS485 transitter is disabled
> >> (txend_callback).
> >>
> >> In many MCUs, if the TX FIFO (or single register) is empty and the TX
> >> interrupt is enabled, the interrupt is triggered immediately. This isn't
> >> the case in this MCU, where you need to send at least the first byte to
> >> trigger the interrupt (after it's shifted out).
> >>
> >> When the issue happens (as I said, even after many months), the RS485
> >> direction is stuck high (transmission enabled), but I didn't see any
> >> activity on TX UART signal. This should mean that the TX interrupt is
> >> disabled.
> >> Consequently, the device can't receive nothing fro the bus (the
> >> transceiver is half-duplex). Other functions of the device are ok even
> >> in this situation. For example, I can see the status LED blinking as usual.
> >>
> >> The uart data structure is configured in the following way:
> >>
> >> * rx_callback=NULL
> >> * tx_callback=NULL
> >> * txstart_callback: set the GPIO of RS485 direction high
> >> * txend_callback: set the GPIO of RS485 direction low
> >> * txdummy_num=1
> >> * txdummy_value=0xFF (it isn't important here)
> >>
> >> I can't understand how the MCU reaches this incorrect state (RS485
> >> transmitter always enabled). With two consecutive instructions the
> >> driver disables the TX interrupt after last byte was transmitted
> >> completely and the direction is set low.
> >>
> >> I know I could refactor the UART driver, but at the moment I'd like to
> >> fix this issue without rewriting so low-level part of the firmware.
> >>
> >> Any idea?
> >>
> >> [1] https://justpaste.it/8swct
> >
> > Which variant of LCP1788?
> LPC1788FBD208
> > Which UART within the MCU?
> UART2
> > Looking at the generic datasheet there are up to 5 UARTs. UART1 is described as supporting RS485 together with modem handshake signals DTR/DSR, RTS/CTS etc which surely could be utilised for Tx/Rx direction.
> UART2 can manage autonomously an external transceiver direction, but it
> is not used in my driver. I think because of dummy bytes that mustn't be
> seen on the wire.
> > Another feature is that the register layout for the UARTs are 16C550 standard compliant so re-writing a driver from scratch should not be necessary (assuming plenty of freely available source code?).
> I don't know 16C550. Do you think the UART in LPC1788 is compatible with
> 16C550? Could you suggest any source code out there?

16C550 is a more modern version of one of the early, very popular UARTs. The 16C550 will have a FIFO instead of buffer register. The tricky part is in the details of interrupts and status signals. I don't know how standardized they are.

Having compatible registers, does not mean compatible operation when doing things like RS-485.

--

Rick C.

-- Get 1,000 miles of free Supercharging
-- Tesla referral code - https://ts.la/richard11209

1
server_pubkey.txt

rocksolid light 0.9.8
clearnet tor