Configuring UART in Linux on iMX6

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Configuring UART in Linux on iMX6

8,533 Views
danlaks
Contributor II

I'm getting confused how to interface with the peripherals on the iMX6 in Linux. I'm very familiar with directly accessing hardware registers in the context of a microcontroller, but I don't understand how that translates in the Linux user environment.

I have a Gateworks GW5510 board that comes with a Yocto Linux build on it from the manufacturer. I did not have to create my own Linux build nor do I have any experience creating Linux builds for embedded systems. I want to interface the board with an external device that speaks logic-level serial, but in a slightly uncommon configuration: inverted 8E2 (8 bits, even parity, 2 stop bits). I read the UART section of the reference manual for the iMX6 and found all of the register bits I need to change to set up the serial port appropriately.

What is the typical way to adjust the registers on a UART? Is that usually done when creating the Linux build and not in the user space? I discovered the devmem2 tool that allowed me to directly access and modify the registers by physical memory address, but that seems clunky and dangerous.

I found imx.c in the Gateworks git repository, which I believe is the serial uart driver. But I don't understand the context of how that driver is applicable. Is that driver just "behind the scenes" stuff or do I need to use it in my own code to access the serial port?

My end goal is to be able to write a program in c++ (cross-compiled on my desktop PC) that will allow me to read the serial port on the Gateworks board.

Labels (2)
Tags (1)
0 Kudos
3 Replies

3,558 Views
igorpadykov
NXP Employee
NXP Employee

Hi Daniel

please refer to attached Linux Manual Chapter 45 Universal Asynchronous Receiver/Transmitter
(UART) Driver and AN5125 Introduction to Device Trees

http://www.nxp.com/assets/documents/data/en/application-notes/AN5125.pdf 

documentation in linux/Documentation/devicetree/bindings/serial/fsl-imx-uart.txt

linux-2.6-imx.git - Freescale i.MX Linux Tree 

linux-2.6-imx.git - Freescale i.MX Linux Tree 

Best regards
igor
-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------

0 Kudos

3,558 Views
danlaks
Contributor II

Igor,

Thank you for your response. I think I'm starting to wrap my head around the concept. The uart driver simply presents a "Linux standard" serial port to the operating system and users need not concern themselves with low-level register access. In my googling, I've discovered how to use ioctl to change the various run-time parameters of the uart, such as parity, stop bits, and baud rate (this was the crux of my original question above).

That said, I'm running into an issue that I could solve if I had direct register access, but I cannot solve using my knowledge of a Linux serial port. I have an incoming serial stream that arrives in bursts: 25 bytes of continuous data followed by 3ms of idle, then 25 bytes of data, then 3ms idle, and so on. I would like my code to be able to detect the idle time on the RX pin so I can sync up with the next burst of data. From the reference manual, I see there's a bit called RXDS in the USR1 register that informs you if the line has gone idle. I don't see how to gain access to that information from the Linux driver.

How can I sync up to the beginning of the 25 byte burst?

Thanks,

Dan

0 Kudos

3,558 Views
danlaks
Contributor II

A follow-up to the reply I just posted. The serial input stream I mentioned above is also inverted. The imx6 has no problem with that because of the INVR bit in the UCR4 register. But it doesn't look like the Linux driver allows you to exploit the native inverting capability.

For now, I got it working by doing a direct register access:

devmem2 0x21EC08C w 0x00008200

Is there a better way to do this? Or do I need to do this in the device tree somehow?

0 Kudos