* Multidrop support
@ 2019-09-12 8:40 Rodolfo Giometti
2019-09-12 8:40 ` [PATCH 1/2] tty: add bits to manage multidrop mode Rodolfo Giometti
2019-09-12 8:40 ` [PATCH 2/2] tty serial: add multidrop support for atmel serial controllers Rodolfo Giometti
0 siblings, 2 replies; 7+ messages in thread
From: Rodolfo Giometti @ 2019-09-12 8:40 UTC (permalink / raw)
To: linux-arch; +Cc: Greg Kroah-Hartman, Jiri Slaby, Arnd Bergmann, Richard Genoud
Here are two patches to introduce multidrop support.
First one defines new termios bits useful to enable multidrop support,
while the second one effectively implements multidrop for the
Atmel/Microchip serial controllers.
Of course other serial drivers can do similar steps if the hardware
they control can do similar operations.
Rodolfo
^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH 1/2] tty: add bits to manage multidrop mode
2019-09-12 8:40 Multidrop support Rodolfo Giometti
@ 2019-09-12 8:40 ` Rodolfo Giometti
2019-09-12 8:48 ` Arnd Bergmann
2019-09-12 11:01 ` Richard Genoud
2019-09-12 8:40 ` [PATCH 2/2] tty serial: add multidrop support for atmel serial controllers Rodolfo Giometti
1 sibling, 2 replies; 7+ messages in thread
From: Rodolfo Giometti @ 2019-09-12 8:40 UTC (permalink / raw)
To: linux-arch
Cc: Greg Kroah-Hartman, Jiri Slaby, Arnd Bergmann, Richard Genoud,
Rodolfo Giometti, Joshua Henderson
From: Rodolfo Giometti <giometti@linux.it>
Multidrop mode differentiates the data characters and the address
characters. Data is transmitted with the parity bit to 0 and addresses
are transmitted with the parity bit to 1. However this usually slow
down communication by adding a delay between the first byte and the
others.
This patch defines two non-stadard bits PARMD (that enables multidrop)
and SENDA (that marks the next transmitted byte as address) that can
be used to completely remove the delay during transmission by
correctly managing the parity bit generation in hardware.
A simple example code about how to set up it is reported below:
struct termios term;
tcgetattr(fd, &term);
/* Transmission: enable parity multidrop and mark 1st byte as address */
term.c_cflag |= PARENB | CMSPAR | PARMD | SENDA;
/* Reception: enable parity multidrop and parity check */
term.c_iflag |= PARENB | PARMD | INPCK;
tcsetattr(fd, TCSADRAIN, &term);
After that we can start 9 bits data transmission.
Signed-off-by: Rodolfo Giometti <giometti@linux.it>
Signed-off-by: Joshua Henderson <joshua.henderson@microchip.com>
---
include/linux/tty.h | 2 ++
include/uapi/asm-generic/termbits.h | 2 ++
2 files changed, 4 insertions(+)
diff --git a/include/linux/tty.h b/include/linux/tty.h
index bfa4e2ee94a9..66a25294f125 100644
--- a/include/linux/tty.h
+++ b/include/linux/tty.h
@@ -168,6 +168,8 @@ struct tty_bufhead {
#define C_CIBAUD(tty) _C_FLAG((tty), CIBAUD)
#define C_CRTSCTS(tty) _C_FLAG((tty), CRTSCTS)
#define C_CMSPAR(tty) _C_FLAG((tty), CMSPAR)
+#define C_PARMD(tty) _C_FLAG((tty), PARMD)
+#define C_SENDA(tty) _C_FLAG((tty), SENDA)
#define L_ISIG(tty) _L_FLAG((tty), ISIG)
#define L_ICANON(tty) _L_FLAG((tty), ICANON)
diff --git a/include/uapi/asm-generic/termbits.h b/include/uapi/asm-generic/termbits.h
index 2fbaf9ae89dd..ead5eaebdd3b 100644
--- a/include/uapi/asm-generic/termbits.h
+++ b/include/uapi/asm-generic/termbits.h
@@ -141,6 +141,8 @@ struct ktermios {
#define HUPCL 0002000
#define CLOCAL 0004000
#define CBAUDEX 0010000
+#define PARMD 040000000
+#define SENDA 0100000000
#define BOTHER 0010000
#define B57600 0010001
#define B115200 0010002
--
2.17.1
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH 2/2] tty serial: add multidrop support for atmel serial controllers
2019-09-12 8:40 Multidrop support Rodolfo Giometti
2019-09-12 8:40 ` [PATCH 1/2] tty: add bits to manage multidrop mode Rodolfo Giometti
@ 2019-09-12 8:40 ` Rodolfo Giometti
1 sibling, 0 replies; 7+ messages in thread
From: Rodolfo Giometti @ 2019-09-12 8:40 UTC (permalink / raw)
To: linux-arch
Cc: Greg Kroah-Hartman, Jiri Slaby, Arnd Bergmann, Richard Genoud,
Rodolfo Giometti, Joshua Henderson
From: Rodolfo Giometti <giometti@linux.it>
This patch adds multidrop support for atmel serial controllers and it
has been tested by using a SAMA5D3 CPU.
Signed-off-by: Rodolfo Giometti <giometti@linux.it>
Signed-off-by: Joshua Henderson <joshua.henderson@microchip.com>
---
drivers/tty/serial/atmel_serial.c | 14 ++++++++++----
1 file changed, 10 insertions(+), 4 deletions(-)
diff --git a/drivers/tty/serial/atmel_serial.c b/drivers/tty/serial/atmel_serial.c
index 0b4f36905321..b30b4a336907 100644
--- a/drivers/tty/serial/atmel_serial.c
+++ b/drivers/tty/serial/atmel_serial.c
@@ -2178,7 +2178,7 @@ static void atmel_set_termios(struct uart_port *port, struct ktermios *termios,
{
struct atmel_uart_port *atmel_port = to_atmel_uart_port(port);
unsigned long flags;
- unsigned int old_mode, mode, imr, quot, baud, div, cd, fp = 0;
+ unsigned int old_mode, mode, mdrop, imr, quot, baud, div, cd, fp = 0;
/* save the current mode register */
mode = old_mode = atmel_uart_readl(port, ATMEL_US_MR);
@@ -2211,9 +2211,11 @@ static void atmel_set_termios(struct uart_port *port, struct ktermios *termios,
/* parity */
if (termios->c_cflag & PARENB) {
- /* Mark or Space parity */
+ /* Mark, Space or Multidrop parity */
if (termios->c_cflag & CMSPAR) {
- if (termios->c_cflag & PARODD)
+ if (termios->c_cflag & PARMD)
+ mode |= ATMEL_US_PAR_MULTI_DROP;
+ else if (termios->c_cflag & PARODD)
mode |= ATMEL_US_PAR_MARK;
else
mode |= ATMEL_US_PAR_SPACE;
@@ -2221,8 +2223,11 @@ static void atmel_set_termios(struct uart_port *port, struct ktermios *termios,
mode |= ATMEL_US_PAR_ODD;
else
mode |= ATMEL_US_PAR_EVEN;
+
} else
mode |= ATMEL_US_PAR_NONE;
+ mdrop = termios->c_cflag & SENDA ? ATMEL_US_SENDA : 0;
+ termios->c_cflag &= ~SENDA; /* SENDA bit must be cleared once used */
spin_lock_irqsave(&port->lock, flags);
@@ -2363,7 +2368,8 @@ static void atmel_set_termios(struct uart_port *port, struct ktermios *termios,
if (!(port->iso7816.flags & SER_ISO7816_ENABLED))
atmel_uart_writel(port, ATMEL_US_BRGR, quot);
atmel_uart_writel(port, ATMEL_US_CR, ATMEL_US_RSTSTA | ATMEL_US_RSTRX);
- atmel_uart_writel(port, ATMEL_US_CR, ATMEL_US_TXEN | ATMEL_US_RXEN);
+ atmel_uart_writel(port, ATMEL_US_CR,
+ mdrop | ATMEL_US_TXEN | ATMEL_US_RXEN);
atmel_port->tx_stopped = false;
/* restore interrupts */
--
2.17.1
^ permalink raw reply related [flat|nested] 7+ messages in thread
* Re: [PATCH 1/2] tty: add bits to manage multidrop mode
2019-09-12 8:40 ` [PATCH 1/2] tty: add bits to manage multidrop mode Rodolfo Giometti
@ 2019-09-12 8:48 ` Arnd Bergmann
2019-09-12 11:01 ` Richard Genoud
1 sibling, 0 replies; 7+ messages in thread
From: Arnd Bergmann @ 2019-09-12 8:48 UTC (permalink / raw)
To: Rodolfo Giometti
Cc: linux-arch, Greg Kroah-Hartman, Jiri Slaby, Richard Genoud,
Rodolfo Giometti, Joshua Henderson
On Thu, Sep 12, 2019 at 10:40 AM Rodolfo Giometti <giometti@enneenne.com> wrote:
> diff --git a/include/uapi/asm-generic/termbits.h b/include/uapi/asm-generic/termbits.h
> index 2fbaf9ae89dd..ead5eaebdd3b 100644
> --- a/include/uapi/asm-generic/termbits.h
> +++ b/include/uapi/asm-generic/termbits.h
> @@ -141,6 +141,8 @@ struct ktermios {
> #define HUPCL 0002000
> #define CLOCAL 0004000
> #define CBAUDEX 0010000
> +#define PARMD 040000000
> +#define SENDA 0100000000
> #define BOTHER 0010000
> #define B57600 0010001
> #define B115200 0010002
If you add these to the asm-generic version of this file, please also
add them to
the architecture specific ones that don't use asm-generic/termbits.h:
alpha, ia64, mips, parisc, powerpc, sparc, and xtensa.
Please pick values that are the same everywhere and do not clash with
any of the existing bits of any of the above (this is probably the case, but
I have not checked)
Arnd
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH 1/2] tty: add bits to manage multidrop mode
2019-09-12 8:40 ` [PATCH 1/2] tty: add bits to manage multidrop mode Rodolfo Giometti
2019-09-12 8:48 ` Arnd Bergmann
@ 2019-09-12 11:01 ` Richard Genoud
2019-09-12 12:47 ` Rodolfo Giometti
1 sibling, 1 reply; 7+ messages in thread
From: Richard Genoud @ 2019-09-12 11:01 UTC (permalink / raw)
To: Rodolfo Giometti, linux-arch
Cc: Greg Kroah-Hartman, Jiri Slaby, Arnd Bergmann, Rodolfo Giometti,
Joshua Henderson
Hi Rodolfo,
You could also add these mailing lists:
- linux-serial@vger.kernel.org
- linux-arm-kernel@lists.infradead.org
- linux-kernel@vger.kernel.org
For reference, I've dug the conversation we had 2 years ago:
0/2 : https://marc.info/?t=149192176100002&r=1&w=2
1/2 : https://marc.info/?t=149192176300001&r=1&w=2
2/2 : https://marc.info/?t=149192176700001&r=1&w=2
And, like I said at that time, one problem I see with this
implementation (setting a SENDA bit that automatically unsets itself)
will break the way tcgetattr() is working:
https://marc.info/?l=linux-serial&m=149209522108027&w=2
Le 12/09/2019 à 10:40, Rodolfo Giometti a écrit :
> From: Rodolfo Giometti <giometti@linux.it>
>
> Multidrop mode differentiates the data characters and the address
> characters. Data is transmitted with the parity bit to 0 and addresses
> are transmitted with the parity bit to 1. However this usually slow
> down communication by adding a delay between the first byte and the
> others.
>
> This patch defines two non-stadard bits PARMD (that enables multidrop)
> and SENDA (that marks the next transmitted byte as address) that can
> be used to completely remove the delay during transmission by
> correctly managing the parity bit generation in hardware.
>
> A simple example code about how to set up it is reported below:
>
> struct termios term;
>
> tcgetattr(fd, &term);
>
> /* Transmission: enable parity multidrop and mark 1st byte as address */
> term.c_cflag |= PARENB | CMSPAR | PARMD | SENDA;
> /* Reception: enable parity multidrop and parity check */
> term.c_iflag |= PARENB | PARMD | INPCK;
>
> tcsetattr(fd, TCSADRAIN, &term);
>
> After that we can start 9 bits data transmission.
>
> Signed-off-by: Rodolfo Giometti <giometti@linux.it>
> Signed-off-by: Joshua Henderson <joshua.henderson@microchip.com>
> ---
> include/linux/tty.h | 2 ++
> include/uapi/asm-generic/termbits.h | 2 ++
> 2 files changed, 4 insertions(+)
>
> diff --git a/include/linux/tty.h b/include/linux/tty.h
> index bfa4e2ee94a9..66a25294f125 100644
> --- a/include/linux/tty.h
> +++ b/include/linux/tty.h
> @@ -168,6 +168,8 @@ struct tty_bufhead {
> #define C_CIBAUD(tty) _C_FLAG((tty), CIBAUD)
> #define C_CRTSCTS(tty) _C_FLAG((tty), CRTSCTS)
> #define C_CMSPAR(tty) _C_FLAG((tty), CMSPAR)
> +#define C_PARMD(tty) _C_FLAG((tty), PARMD)
> +#define C_SENDA(tty) _C_FLAG((tty), SENDA)
>
> #define L_ISIG(tty) _L_FLAG((tty), ISIG)
> #define L_ICANON(tty) _L_FLAG((tty), ICANON)
> diff --git a/include/uapi/asm-generic/termbits.h b/include/uapi/asm-generic/termbits.h
> index 2fbaf9ae89dd..ead5eaebdd3b 100644
> --- a/include/uapi/asm-generic/termbits.h
> +++ b/include/uapi/asm-generic/termbits.h
> @@ -141,6 +141,8 @@ struct ktermios {
> #define HUPCL 0002000
> #define CLOCAL 0004000
> #define CBAUDEX 0010000
> +#define PARMD 040000000
> +#define SENDA 0100000000
> #define BOTHER 0010000
> #define B57600 0010001
> #define B115200 0010002
>
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH 1/2] tty: add bits to manage multidrop mode
2019-09-12 11:01 ` Richard Genoud
@ 2019-09-12 12:47 ` Rodolfo Giometti
2019-09-13 14:36 ` Richard Genoud
0 siblings, 1 reply; 7+ messages in thread
From: Rodolfo Giometti @ 2019-09-12 12:47 UTC (permalink / raw)
To: Richard Genoud, linux-arch
Cc: Greg Kroah-Hartman, Jiri Slaby, Arnd Bergmann, Rodolfo Giometti,
Joshua Henderson
On 12/09/2019 13:01, Richard Genoud wrote:
> Hi Rodolfo,
>
> You could also add these mailing lists:
> - linux-serial@vger.kernel.org
> - linux-arm-kernel@lists.infradead.org
> - linux-kernel@vger.kernel.org
OK. No problem!
> For reference, I've dug the conversation we had 2 years ago:
> 0/2 : https://marc.info/?t=149192176100002&r=1&w=2
> 1/2 : https://marc.info/?t=149192176300001&r=1&w=2
> 2/2 : https://marc.info/?t=149192176700001&r=1&w=2
Thanks.
> And, like I said at that time, one problem I see with this
> implementation (setting a SENDA bit that automatically unsets itself)
> will break the way tcgetattr() is working:
> https://marc.info/?l=linux-serial&m=149209522108027&w=2
I see... however the problem here is that this attribute is not sticky and it is
reset by the controller after the first byte as been sent. Here is how
Atmel/Microchip multidrop works (from the SAMA5D3's datasheet):
44.7.3.9 Multidrop Mode
If the value 0x6 or 0x07 is written to the PAR field in the US_MR, the USART
runs in Multidrop Mode. This mode differentiates the data characters and the
address characters. Data is transmitted with the parity bit to 0 and addresses
are transmitted with the parity bit to 1.
...
The transmitter sends an address byte (parity bit set) when SENDA is written to
in the US_CR. In this case, the next byte written to the US_THR is transmitted
as an address. Any character written in the US_THR without having written the
command SENDA is transmitted normally with the parity to 0.
So, if we have a 4 bytes message where the first one is the address byte we can
use multidrop by setting the SENDA bit at the beginning and then by just
invoking a write() with the four bytes message. The controller automatically
will set the 9th bit to 1 for the first byte and then to 0 for the following
three bytes.
To do so we need a syscall to tell to the controller when the address bit
(SENDA) must be set, each time, before sending the message.
In this implementation I used the syscall within tcsetattr() function but if
this is not right, then I have to use another one... maybe a custom ioctl? Or
can you please suggest a suitable solution? :-)
Thanks for your help,
Rodolfo Giometti
--
GNU/Linux Solutions e-mail: giometti@enneenne.com
Linux Device Driver giometti@linux.it
Embedded Systems phone: +39 349 2432127
UNIX programming skype: rodolfo.giometti
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH 1/2] tty: add bits to manage multidrop mode
2019-09-12 12:47 ` Rodolfo Giometti
@ 2019-09-13 14:36 ` Richard Genoud
0 siblings, 0 replies; 7+ messages in thread
From: Richard Genoud @ 2019-09-13 14:36 UTC (permalink / raw)
To: Rodolfo Giometti, linux-arch
Cc: Greg Kroah-Hartman, Jiri Slaby, Arnd Bergmann, Rodolfo Giometti,
Joshua Henderson
Le 12/09/2019 à 14:47, Rodolfo Giometti a écrit :
> On 12/09/2019 13:01, Richard Genoud wrote:
>> Hi Rodolfo,
>>
>> You could also add these mailing lists:
>> - linux-serial@vger.kernel.org
>> - linux-arm-kernel@lists.infradead.org
>> - linux-kernel@vger.kernel.org
>
> OK. No problem!
>
>> For reference, I've dug the conversation we had 2 years ago:
>> 0/2 : https://marc.info/?t=149192176100002&r=1&w=2
>> 1/2 : https://marc.info/?t=149192176300001&r=1&w=2
>> 2/2 : https://marc.info/?t=149192176700001&r=1&w=2
>
> Thanks.
>
>> And, like I said at that time, one problem I see with this
>> implementation (setting a SENDA bit that automatically unsets itself)
>> will break the way tcgetattr() is working:
>> https://marc.info/?l=linux-serial&m=149209522108027&w=2
>
> I see... however the problem here is that this attribute is not sticky and it is
> reset by the controller after the first byte as been sent. Here is how
> Atmel/Microchip multidrop works (from the SAMA5D3's datasheet):
>
> 44.7.3.9 Multidrop Mode
> If the value 0x6 or 0x07 is written to the PAR field in the US_MR, the USART
> runs in Multidrop Mode. This mode differentiates the data characters and the
> address characters. Data is transmitted with the parity bit to 0 and addresses
> are transmitted with the parity bit to 1.
> ...
> The transmitter sends an address byte (parity bit set) when SENDA is written to
> in the US_CR. In this case, the next byte written to the US_THR is transmitted
> as an address. Any character written in the US_THR without having written the
> command SENDA is transmitted normally with the parity to 0.
>
> So, if we have a 4 bytes message where the first one is the address byte we can
> use multidrop by setting the SENDA bit at the beginning and then by just
> invoking a write() with the four bytes message. The controller automatically
> will set the 9th bit to 1 for the first byte and then to 0 for the following
> three bytes.
>
> To do so we need a syscall to tell to the controller when the address bit
> (SENDA) must be set, each time, before sending the message.
>
> In this implementation I used the syscall within tcsetattr() function but if
> this is not right, then I have to use another one... maybe a custom ioctl? Or
> can you please suggest a suitable solution? :-)
What's bothering me with this implementation, is that it's too close to
the hardware. Some other micro-controllers may not have the SENDA bit.
For instance, i.MX6ULL:
--->8----
To transmit 9-bit RS-485 frames, user need to enable parity (PREN=1) to
enable
trasmitting the ninth data bit, set 8-bit data word size (WS=1), and
write TXB8
(UMCR[2]) as the 9 th bit (bit [8]) to be transmitted (write '0' to TXB8
to transmit a data
frame, write '1' to transmit a address frame). The other data bit [7:0]
is written to TxFIFO
by writing to the UTXD same as normal RS-232 operation.
---8<----
And the TXB8 bit doesn't seem to clear itself automatically.
I maybe wrong, but I think that writing a line discipline for multidrop
mode would be more versatile.
Regards,
Richard
>
> Thanks for your help,
>
> Rodolfo Giometti
>
^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2019-09-13 14:36 UTC | newest]
Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2019-09-12 8:40 Multidrop support Rodolfo Giometti
2019-09-12 8:40 ` [PATCH 1/2] tty: add bits to manage multidrop mode Rodolfo Giometti
2019-09-12 8:48 ` Arnd Bergmann
2019-09-12 11:01 ` Richard Genoud
2019-09-12 12:47 ` Rodolfo Giometti
2019-09-13 14:36 ` Richard Genoud
2019-09-12 8:40 ` [PATCH 2/2] tty serial: add multidrop support for atmel serial controllers Rodolfo Giometti
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox