Serial communication behavior - linux

Im trying to learn about serial communication and I saw that command in below link
http://www.tldp.org/HOWTO/Serial-HOWTO-19.html#pinout_
Only 3 of the 9 pins have a fixed assignment: transmit, receive and signal ground. This is fixed by the hardware and you can't change it.
But the other signal lines are controlled by software and may do (and mean) almost anything at all.
So, these 6 pins, are they reliable to control state of them?
I have many devices, is there any way to make hardware handshaking in a common way?
what I have to do, If some drivers does not handle this pins accurately?
Is there any way to make them fixed assigned by program?

Related

Using two USART ports on the STM32-Discovery

I am using an STM32-Discovery board for my first time. I want to use two of the USART ports on the board at the same time to read in serial information. Can the STM32 read in serial information from both of these USART ports at the same time? Do I need to set an interrupt instead, to switch between them?
I realize this is connected to threading on the board, but I do not understand the threading of the board.
You can read and write as many peripherals as you wish. But of course you need to do it a proper way. For example if you poll for the data from UART1 the data can be overrun on the another ones. So you need to implement other methods like using the interrupts. The topic is too broad for the simple answer.

How to generate a steady 37kHz GPIO trigger from inside linux kernel?

I have a micro controller taking care of infrared TX-carrier wave generation currently, but I started wondering if I could dispose of it, and do this work in linux side - thus bringing the cost of my embedded system down.
I'm running on a Freescale i.mx233 (454MHz ARM9), and if I access registry directly through /dev/mem, I can achieve quite steady 5MHz triggering to a GPIO pin.
Since I need 37kHz, I started looking ways of slowing it down, but it seems that at least nanowait() is way too rough for this purpose.
I found one solution of calling rand() in a for loop, and I seem to be able to generate 38,4kHz signal quite well, However there is some unacceptable jitter from time to time according to oscilloscope. (I understand that this is quite a bit waste of resources, but when the TX needs to be done, the system has no other tasks really)
My questions:
Freescales kernel code (3.8 branch) doesn't have CONFIG_PREEMPT_RT patches, so that is one thing maybe I should look into, but before that:
Could I achieve more accurate performance, by writing a kernel module to drive the GPIO from inside the kernel ? I do need to read up on some data from user space (data to be sent), but other than that, I only need to trigger the led on specified frequency at the end of the GPIO, so the driver should be pretty simple.
Can I force the priority of my driver, so that other tasks don't interrupt this gpio triggering ? (data sending takes currently roughly 400ms, and it's done very seldom)
Is there some better way to create an interrupt say every 37kHz, so that I don't stall the system by SW ?
Micro controller is perfect for this kind of tasks, but it would be nice to avoid this cost overhead if possible...
The i.MX23 PWM in "Multi-Chip Attachment Mode" is designed exactly for this requirement.
Use one of the PWM's in "Multi-Chip Attachment Mode", for example, assuming you are using a 24Mhz clock, with
MATT=1 (Enable multi-chip attachment mode)
MATT_SEL=1 (User 24Mhz clock)
CDIV=0x2 (or DIV_4, i.e. divide by 4)
INACTIVE_STATE=0x2 or 0x3
ACTIVE_STATE=0x3 or 0x2
PERIOD=175 (i.e 176-1)
If you use a 32Mhz clock you will need other CDIV and PERIOD parameters to get to 34Khz.
See the "i.MX23 Applications Processor Reference Manual" for example code. If I am not mistaken the driver code is in arch/arm/plat-mxc/pwm.c but it doesn't seem to support the MATT mode. You will probably have to extend the code yourself.
Regarding the implementation -
The above answer relates to the CPU only. In practice, the ability to implement the idea depends on the board design. The board would need a header (pins for external connection) that connects to a GPIO pin that can be connected via the pinmux to one of the PWMs. I would assume that most reference designs would have at least one PWM configurable GPIO exposed through a header. The the question is if there is only one and if you are already using it for some other control purpose.
After determining that there is a header with a free PWM configurable GPIO, you need to configure the pin mux and activate the PWM. There are instructions for this in the processor reference manual noted above. Most systems do this configuration in the boot loader board_init() (assuming U-boot), although it can probably be done in userspace also with some mmap trickery after Linux boots.
Finally you would need to write a driver based on the interface to the PWM module in platform-mxc_pwm.c.
If you are using the i.MX23 EVK 10.05 you might be able to modify the LED PWM driver since it is already configured at the level of the bootloader and kernel and connect your device to the LED output instead of the LED. (You will need a hardware technician to help you with this.) Make sure you config the kernel with the CONFIG_LEDS_MXS.
The above comments regarding implementation are somewhat speculative since I don't know the EVK. Perhaps someone who knows it can improve on this.
Update September 21, 2013
Another way to generate a 37kHz signal with the i.MX23 or with any SoC with a similar ARM CPU core is to use an unused on-chip timer to generate a FIQ interrupt at the required frequency and write a FIQ interrupt handler to toggle a GPIO pin. Maxime Ripard posted a complete example of this method using the i.MX28 SoC on his Free Electrons blog on April 30 this year. To use this method you will need both an unused timer and not be using the FIQ interrupt for another purpose such as one of the SPI, camera, or brownout-detection drivers that use the ARM FIQ. You will also need to write the ISR in ARM assembler.
The best way to get a 37 kHz signal would be to find some serial/audio/PWM output that can generate it in hardware.
It might be possible to raise the priority of your userspace process, but this won't help against interrupts or high-priority kernel tasks.
An RT kernel would allow you to get priority over more kernel tasks, but wouldn't help against all interrupts.
I don't know if you will be able to get the maximum latency below 37 kHz (27 µs); I think it's unlikely.
Doing this in the kernel would help because you could disable interrupt handling.
However, disabling interrupts for as long as 400 ms is frowned upon.

RS485 support in pxa255

I want to use rs485 placed on my card. I'm working on arm-linux and with pxa255 processor. I have already checked "serial.h" located in arm-linux tool chain but unfortunately i couldn't find the appropriate rs485 settings struct although it is supported in some other environments like cris. So now, do i have to write a low-level driver to enable rs485 or is there any other easier way to do this?
I'd recommend reviewing this page about Linux RS-485 support.
There seems to be quite a lot of confusion about serial ports with regards to RS485 mode support on Linux drivers. I think I might be able to shed some light answering this question.
First off, you should ask yourself: why do I want to activate RS485 support on my serial port? I don't know what development board or hardware you're using but be aware that most UARTs work with single-ended TTL levels only (5V or 3.3V levels). That means you won't be able to talk to RS485 devices directly because they only handle differential signals. If you want more details you can see this link: https://www2.htw-dresden.de/~huhle/ArtScienceRS485.pdf for a good introduction.
So you can write as many lines of code and drivers as you want but that won't help your TTL UART talk to RS485. Even if you have a device that supports RS485 on its driver, the hardware itself needs to have a level translator IC (like a MAX485) for you to be able to use it. Fortunately, our beloved Linux Kernel developers know a lot about hardware and you don't have to worry about this (for most devices anyway). Then, answering your question: if you are not able to find the RS485 settings on your driver it will most likely mean your hardware does not offer support directly.
Luckily for you, the solution is quite easy: just get a cheap USB to RS485 dongle. You can find them from 5-10$ and they should work fine out of the box for most scenarios. In my experience, FTDI chips work well.
If you really have to go with one particular UART for any reason whatsoever, for instance, imagine you want to use the UART on your Raspberry Pi or any other where you only have TX and RX signals accessible. Then you have a slightly more difficult challenge ahead of you and you need to study a bit more about how RS485 devices work. The key aspect here is to understand that RS485 on a half-duplex two-wire link (see note below for more details on this). To be able to share a two-wire bus where one or multiple devices are listening and only one is talking at any time, you need an additional control signal (Drive Enable/~Read Enable) on top of your TX and RX (note that when you go on single-ended TTL you have two signals referred to GND using three wires compared to one differential bus with two wires for the RS485 side). Your RS485 transceiver (say MAX485) will need this RE/~DE signal to arrange who is talking and who is listening on the bus, namely: all devices listening on the bus will have this signal low (read enable set) while the talker will be high (drive enable).
Here we get to the essence of your question: where can you get this additional signal? Well, the answer is: it depends on your UART chip. Some chips don't offer anything to work with, then you're left with the option of manually driving in your software application a GPIO line or flow controls signals (RTS or DTR) for UARTS where you have them available. You can read more details on this topic for the particular case of the FTDI chips here: RS485: Inappropriate ioctl for device. There is also a reference to a nice hardware solution to this problem using the mythical 555 timer IC.
Note: more confusing areas: one, RS485 is half-duplex and sometimes mixed up with RS422, which is full duplex and needs four wires; and two: where I say two-wire and four wires I should better say three-wire and five wires because the differential voltage signals need a GND to serve as a return path; sadly, most practical implementations of RS485 are two-wire and they seem to work reliably for most people, but that's a huge topic itself and we can talk about it somewhere else.

Linux serial port priority

At present we are using Fedora Core 3 for a system we are working on. This system needs to communicate via serial. The timing of communications is timing critical. At present it seems that the serial driver has delays in pushing the data from the 4k fifo into the 16byte hardware uart.
Is there any way in force Linux to treat this action with a higher priority?
Try the using setserial to set the low_latency option.
By default serial ports are optimised for throughput not latency, this option I think lets you change it.
If you have a hard real-time processing requirement, you may be better off using a distribution that's built with that in mind, for example RTLinux.
Consider getting the device vendor to change the protocol to something less stupid where timing doesn't matter.
Having a timing-critical serial protocol, or indeed one which requires you to acknowledge one message before sending the next, is really stupid.
rs232-style serial ports are really slow, and anything which makes them worse is a bad idea.
I wrote a program to control a device which had a stupid protocol - each byte of data was individually acknowledged (duuh!) and the next one wasn't sent until the ack arrived - which meant that the data transfer rate was a tiny fraction of what it should have been.
Look at the zmodem protocol, for example, which is less stupid.
Better still, get the vendor to enter the 1990s and use USB.

Is forcing I2C communication safe?

For a project I'm working on I have to talk to a multi-function chip via I2C. I can do this from linux user-space via the I2C /dev/i2c-1 interface.
However, It seems that a driver is talking to the same chip at the same time. This results in my I2C_SLAVE accesses to fail with An errno-value of EBUSY. Well - I can override this via the ioctl I2C_SLAVE_FORCE. I tried it, and it works. My commands reach the chip.
Question: Is it safe to do this? I know for sure that the address-ranges that I write are never accessed by any kernel-driver. However, I am not sure if forcing I2C communication that way may confuse some internal state-machine or so.(I'm not that into I2C, I just use it...)
For reference, the hardware facts:
OS: Linux
Architecture: TI OMAP3 3530
I2C-Chip: TWL4030 (does power, audio, usb and lots of other things..)
I don't know that particular chip, but often you have commands that require a sequence of writes, first to one address to set a certain mode, then you read or write another address -- where the function of the second address changes based on what you wrote to the first one. So if the driver is in the middle of one of those operations, and you interrupt it (or vice versa), you have a race condition that will be difficult to debug. For a reliable solution, you better communicate through the chip's driver...
I mostly agree with #Wim. But I would like to add that this can definitely cause irreversible problems, or destruction, depending on the device.
I know of a Gyroscope (L3GD20) that requires that you don't write to certain locations. The way that the chip is setup, these locations contain manufacturer's settings which determine how the device functions and performs.
This may seem like an easy problem to avoid, but if you think about how I2C works, all of the bytes are passed one bit at a time. If you interrupt in the middle of the transmission of another byte, results can not only be truly unpredictable, but they can also increase the risk of permanent damage exponentially. This is, of course, entirely up to the chip on how to handle the problem.
Since microcontrollers tend to operate at speeds much faster than the bus speeds allowed on I2C, and since the bus speeds themselves are dynamic based on the speeds at which devices process the information, the best bet is to insert pauses or loops between transmissions that wait for things to finish. If you have to, you can even insert a timeout. If these pauses aren't working, then something is wrong with the implementation.

Resources