2

I am trying to force a 9-bit protocol on a UART in embedded Linux. Currently I am testing this out on the am335x_evm board. I am planning on doing this using stick parity. Ideally I was hoping I would not need to actually modify any of the code for the omap-serial.c driver.

The reason for the 9-bit protocol is to support some legacy hardware that uses it. The parity bit needs to be 1 for the address portion of the message, 0 for the data portion, then 1 again for the termination byte.

I was planning on having a process running in user space that would interface with the UART through standard system calls (open, write, read, ioctl, tcsetattr, etc). I would configure the UART to enable parity and set the stick parity. I would then set the parity to even and call write() to send out my address data. I would then set the parity to 0 and send out the data. My concern is if I change the parity from 1 to 0, when does that take affect? If the UART is not done sending all the address data, will the change in parity apply to any unsent data?

tpotter01
  • 79
  • 9
  • That's a very good questions. You can always flush the channel, but that introduces a slight delay between your address and data, which may not be understood by your peripherals. – Dima Tisnek Nov 12 '14 at 12:59
  • The flush may not be a bad idea. I will keep that one in mind. You are correct about the delay though. The receivers of the message will only wait a short period before discarding what they have. – tpotter01 Nov 12 '14 at 13:02
  • Another option is to write your own serial `line discipline` driver. It's not the easiest thing in the world, but not the hardest either. That allows you to send messages to/from user space via ioctl (and possible read/write) one message at a time, as opposed to byte stream. Then discipline driver has more access from kernel space. This approach will also help you in *receiving* messages a lot. – Dima Tisnek Nov 12 '14 at 13:07
  • Something like that was going to be my fallback option. To use ioctl to send what I needed into the uart driver then at that lower level I would have more control. – tpotter01 Nov 12 '14 at 13:10
  • @qarma - *"write your own serial line discipline driver...(and) send messages to/from user space via ioctl"* -- If you use a line discipline, then abusing the **ioctl()** won't work because it bypasses the line discipline. – sawdust Nov 13 '14 at 07:58
  • 1
    Without a UART that is 9-bit capable, you could come up with a scheme to transmit 8 bits of data plus a forced 0 or 1 parity as the 9th data bit. But receiving is much more difficult, will require driver modifications, require programmed I/O (i.e. no DMA) and require transmission to be suspended while receiving. Simplified description is at http://digital.ni.com/public.nsf/allkb/3BDC7FF03541F772862564990057F919. – sawdust Nov 13 '14 at 09:11
  • @sawdust common ioctls may be handled by tty layer, but custom ioctls are possible, here's an example http://lxr.free-electrons.com/source/drivers/tty/n_r3964.c#L1183 (example only, that module that code is old, broken and outright horrible, rather use another n_xxx.c) – Dima Tisnek Nov 13 '14 at 09:33

2 Answers2

2

Ended up writing my own 9-bit uart driver. Was the easiest and most efficient solution.

tpotter01
  • 79
  • 9
  • 1
    Can you share the source with the community, please? I want to use 9-bit uart too, and it seems there are many people around the world too! – Alex Antonov Mar 27 '15 at 05:26
  • Yea, same here. That would be awesome – pdel Mar 31 '15 at 18:49
  • I'm very curious as well to see this, I've been attempting this and I've gotten Tx figured out I believe but Rx seems to be much more difficult or I'm overlooking something trivial... any guidance would be amazing! – While-E May 18 '15 at 20:26
1

Proper way is to set cs9 on your serial port (and possibly no parity), provided that hardware and driver support this.

I'll search for a link for you...

Dima Tisnek
  • 11,241
  • 4
  • 68
  • 120
  • Thank you, however the UARTs on the TI Sitara chip (the one on the avm335X_evm) do not support CS9. Hence why I am trying to go the stick parity route. – tpotter01 Nov 12 '14 at 13:04