What's the maximum baud rate in MATLAB? - linux

Ubuntu 16.04 & MATLAB R2017a.
I'm trying to set serial port like that:
s=serial_port('/dev/ttyUSB0','BaudRate',115200,'DataBits',8,'InputBufferSize',80000)
It's working fine, but when I try to change baud rate, say 1000000.
I got this message:
Open failed: BaudRate could not be set to the specified value.
So, I have 2 question:
1) Is it possible to set not common baud rates, say 2000000?
2) I found, that 1500000 and 3000000 is working for me.
Is there maximum speed?
** UPDATE**
I know how to change the baud rate in OS, in my case (Ubuntu 16.04)
setserial is not working, so I'm using sudo stty -F /dev/ttyUSB3 3500000 (not all speed is allowed) or via asm/termios.h> -- all speed is allowed.
So, I'm using second way.
After that, I can easily listen the port like that cu -l /dev/ttyUSB0
And at the same time I cant set the speed in matlab.. (Error above)

Although this link should provide you enough information about how to manage baud rates on Matlab side, as #Cris Luengo already stated in his command, I would like to elaborate a little bit on the hardware side of the problem.
Using the following command:
stty -F /dev/ttyUSB0
you should be able to retrieve the current baud rate of the targeted device. Alternatively, the following command also retrieves that value:
setserial -ag /dev/ttyUSB0
together with other important information:
/dev/ttyUSB0, Line ..., UART: ..., Port: ..., IRQ: ...
Baud_base: ..., close_delay: ..., divisor: ...
closing_wait: ..., closing_wait2: ...
Flags: ...
OS side, you can play with the baud rate of some devices but if you want to avoid problems, you always have to set a coherent value when establishing a connection. Generally speaking, devices have a tolerance level (of, I think, no more than ±5%) on overspeed and underspeed concerning baud rate deviance... so you can try to force an arbitrary baud rate different from the current one, but you don't want to go too far from it.

Related

How TTY "input speed" differs from "output speed"?

There are two commands for setting "speed" - cfsetospeed and cfsetispeed.
But why only one "speed" is shown by stty?
According to bits/termios.h, c_ispeed and c_ospeed are "input speed" and "output speed".
I tried to set B4800 to "input speed" and "B57600" to "output speed", and vice versa at the other
end of serial channel. But data is corrupted. Why there are two separate speeds if it is impossible to set
them separately?
stty shows the speed which was set by cfsetospeed or cfsetispeed - whichever was called last.
Besides, B0 setting takes effect only with cfsetospeed. Is it documented somewhere?
Moreover, while B0 is set, I can receive and transmit data with whatever speed was
active before B0 was set. Is it documented somewhere? Is it undefined behavior or it is in POSIX?
EDIT:
I conducted the same tests on ordinary serial port (i.e., no usb) and obtained the following curious difference with usb serial port:
Ordinary serial port uses 9600 "speed" if we set B0, whereas
usb serial port uses whatever speed was selected before B0 was set.
(OS: Linux)
Why there are two separate speeds if it is impossible to set them separately?
Some (older) UARTs (e.g. the ubiquitous 8250 and its successors) actually have a crystal input for the transmitter and another clock input for the receiver. Hence the input baudrate can be different from the output baudrate on such UARTs.
But most (if not all) boards feed the transmit clock to the receive clock to negate this feature (e.g. the typical 8250/165x0 datasheet will show the RCLK input driven by the BAUDOUT output).
The separate termios speed elements simply reflects this obscure hardware capability (that is rarely actually available).
Also most UARTs (that are not 8250-based) in SoCs have a common clock input for transmit and receive, so the baudrate setting has to apply to both.
So specifying "separate" baudrates is typically a useless configuration.
Besides, B0 setting takes effect only with cfsetospeed. Is it documented somewhere?
Code is the documentation.
Most serial port drivers call uart_get_baud_rate() in drivers/tty/serial/serial_core.c to decode the baudrate settings from the termios structure.
/**
* uart_get_baud_rate - return baud rate for a particular port
* #port: uart_port structure describing the port in question.
* #termios: desired termios settings.
* #old: old termios (or NULL)
* #min: minimum acceptable baud rate
* #max: maximum acceptable baud rate
*
* Decode the termios structure into a numeric baud rate,
* taking account of the magic 38400 baud rate (with spd_*
* flags), and mapping the %B0 rate to 9600 baud.
*
* If the new baud rate is invalid, try the old termios setting.
* If it's still invalid, we try 9600 baud.
*
* Update the #termios structure to reflect the baud rate
* we're actually going to be using. Don't do this for the case
* where B0 is requested ("hang up").
*/
Note the special handling mentioned for B0.
I conducted the same tests on ordinary serial port (i.e., no usb) and obtained the following curious difference with usb serial port:...
The list of drivers that use uart_get_baud_rate() does not seem to include any USB serial port adapters: https://elixir.free-electrons.com/linux/latest/ident/uart_get_baud_rate
You may have to inspect the driver for your specific USB serial port adapter for its handling of the termios baudrate specifers.

Baud rate of inb and outb commands - linux

I want to pass binary data from my PC to my micro-controller through the real serial port in my computer. At this time, I'm thinking of using INB and OUTB functions so I don't have to put up with linux tty character overrides.
Question is, how do I configure the baud rate of the serial port, if I use its address with the INB and OUTB functions? For example, if I want to write to COM1 (0x3F8), how will I be able to determine the baud rate data is being written at?
Does stty still have some sort of background control with INB and OUTB or setserial or what?
At this time, I'm thinking of using INB and OUTB functions so I don't have to put up with linux tty character overrides.
This is a terrible, no good, very bad idea, and it won't work. The existing serial drivers will get very confused if you try to change the port configuration from under them.
Use standard UNIX APIs to interact with the serial port. It's not hard.
Duskwuff is right, of course. Why go low-level and not use the API?
See http://www.tldp.org/HOWTO/text/IO-Port-Programming section 6.3:
If the device you're talking to supports something resembling RS-232,
you should be able to use the serial port to talk to it. The Linux
serial driver should be enough for almost all applications (you
shouldn't have to program the serial port directly, and you'd probably
have to write a kernel driver to do it); it is quite versatile, so
using non-standard bps rates and so on shouldn't be a problem.
To illustrate this, here is the answer to the original question "how to set the baud rate":
In addition to the port (e.g. 0x3F8 for COM1), the next few port numbers are used for various controlling purposes. For setting the baud rate, first calculate the divisor 115200 / [desired baud rate]. E.g. if you want 38400 baud, the divisor is 3. Then:
Set the highest bit of PORT+3
Send the least significant byte of the divisor to PORT
Send the most significant byte of the divisor to PORT+1
Clear the highest bit of PORT+3 (at the same time, the lower bits can be used to set the parity, stop bits etc.)
In code:
outb(PORT + 3, 0x80); // Enable DLAB (set baud rate divisor)
outb(PORT + 0, 0x03); // Set divisor to 3 (lo byte) 38400 baud
outb(PORT + 1, 0x00); // (hi byte)
outb(PORT + 3, 0x03); // 8 bits, no parity, one stop bit
Source is here: http://wiki.osdev.org/Serial_Ports

Qt - Setting a custom baud rate

I'm attempting to set a custom baud rate of 10400 to my device on Linux using Qt. However, when I run the application, the console output keeps reporting that
Baud rate of serial port /dev/ttyUSB0 is set to 10403 instead of 10400: divisor 2307.692383 unsupported
I've also set the data bits to 8, parity to no parity, and stop bits to 1, which are pretty standard.
Here's my code by the way:
serial -> setBaudRate(10400); // Set Baud Rate
serial -> setDataBits(QSerialPort::Data8);
serial -> setStopBits(QSerialPort::OneStop);
serial -> setParity(QSerialPort::NoParity);
When I run the application on Windows however, it works totally fine.
My device isn't able to connect with any other baud rate other than 10400. The application is able to compile and run, however the result is all garbage. I want to know if there's a way where I can specify this baud rate without any problems?
Relevant bug report here. Basically it means, that the exact baud rate is not available, because the actual thing configured to hardware is an integer divisor of some clock frequency, and there is no exact integer divisor for the requested baud rate. The warning message is pretty descriptive about this.
It shouldn't matter, baud rates have some tolerance, but if it does cause problems (discussion under bug suggests it may...), upgrading to Qt 5.6 is suggested in the bug report.
That's a warning; it means you should fix the code, but the code still happens to work. What you're trying to do is not supported by the hardware you run on. Windows is only quieter about this, it doesn't support it either.

Connecting to a STN1110

I'm trying to connect to a STN1110 chip via screen. Unfortunately I only get strange characters as response.
My understanding is that this is due to the wrong baud rate. I tried several baud rates I could find for STN1100 (9600, 115200, 38400) but none of them work. Am I missing something?
Thanks as always for your help.
It seems like I found the solution. Screen was not the problem and the baud rate 9600 was the right one. After checking the wiring (thanks to a tipp from a budy of mine) we noticed that the ground of the ttl to usb adapter was not properly connected to the STN1110. After I fixed the ground everything worked fine.
To use 921600 I did the following:
$ setserial /dev/ttyS0 port 0x3f8 uart 16550A baud_base 921600
$ stty -F /dev/ttyS0 921600
Then brought up "putty" and set the baud rate to 921600 connected to /dev/ttyS0.
Then executed an ST command:
st sbr 921600
Seems to work.
connect via rs232 set br:9600 (default)
and to show all program protocol
atpps
if want to new br:38400
atpp 0c sv 68
atpp 0c on
atz
the new connection are br:38400

How can I set a custom baud rate on Linux?

I want to communicate over my serial port on Linux to a device with a non-standard-baud rate that is not defined in termios.h.
I tried the "baud rate aliasing"-method from this post, but when I execute my C-program (I’ve named it "testprogram"), Linux says "testprogram sets custom speed on ttyS0. This is deprecated."
I did some search on Google, and it seems that there is another (newer?) method to change the baud rate to a non-standard-value: On http://sourceware.org/ml/libc-help/2009-06/msg00016.html the author says that the c_flag of struct termios must be OR’d with BOTHER (=CBAUDEX | B0).
With this method the baud rates are set directly in the c_ispeed and c_ospeed-members of the struct termios. However, I don’t know how I use this method in my C program. Like the author said, there is no BOTHER defined/available when I include termios.h, so what should be done to set the baud rate this way?
How can I set the baud rate to a non-standard-value without changing the kernel?
I noticed the same thing about BOTHER not being defined. Like Jamey Sharp said, you can find it in <asm/termios.h>. Just a forewarning, I think I ran into problems including both it and the regular <termios.h> file at the same time.
Aside from that, I found with the glibc I have, it still didn't work because glibc's tcsetattr was doing the ioctl for the old-style version of struct termios which doesn't pay attention to the speed setting. I was able to set a custom speed by manually doing an ioctl with the new style termios2 struct, which should also be available by including <asm/termios.h>:
struct termios2 tio;
ioctl(fd, TCGETS2, &tio);
tio.c_cflag &= ~CBAUD;
tio.c_cflag |= BOTHER;
tio.c_ispeed = 12345;
tio.c_ospeed = 12345;
ioctl(fd, TCSETS2, &tio);
You can set a custom baud rate using the stty command on Linux. For example, to set a custom baud rate of 567890 on your serial port /dev/ttyX0, use the command:
stty -F /dev/ttyX0 567890
dougg3 has this pretty much (I can't comment there). The main additional thing you need to know is the headers which don't conflict with each other but do provide the correct prototypes. The answer is
#include <stropts.h>
#include <asm/termios.h>
After that you can use dougg3's code, preferably with error checking round the ioctl() calls. You will probably need to put this in a separate .c file to the rest of your serial port code which uses the normal termios to set other parameters. Doing POSIX manipulations first, then this to set the custom speed, works fine on the built-in UART of the Raspberry Pi to get a 250k baud rate.
BOTHER appears to be available from <asm/termios.h> on Linux. Pulling the definition from there is going to be wildly non-portable, but I assume this API is non-portable anyway, so it's probably no big loss.
For Mac users (possibly also for some Linux distributions)
stty ospeed 999999
stty ispeed 999999
You can just use the normal termios header and normal termios structure (it's the same as the termios2 when using header asm/termios).
So, you open the device using open() and get a file descriptor, then use it in tcgetattr() to fill your termios structure.
Then clear CBAUD and set CBAUDEX on c_cflag.
CBAUDEX has the same value as BOTHER.
After setting this, you can set a custom baud rate using normal functions, like cfsetspeed(), specifying the desired baud rate as an integer.
There is an serial I/O chip on your motherboard's CPU (16650 UART).
This chip uses 8-bit port as control and data bus, and thus you can issue a command to it through writing to this chip through the control and data bus.
Usually, an application did the following steps on the serial port
Set baud rate, parity, encoding, flow control, and starting / ending sequence length during program start. This setup can be done via ioctl to the serial device or 'stty' command. In fact, the stty command uses ioctl to that serial device.
Write characters of data to the serial device and the driver will be writing data charaters to the UART chip through its 8-bit data bus.
In short, you can specify the baud rate only in the STTY command, and then all other options would be kept as default, and it should enough to connect to ohter devices.

Resources