# How to set non standard serial port speed

I need to set the serial port /dev/ttyS0 to 250k bit/sec in order to send commands to another device expecting 250k. I am using Python and trying to set the speed with the command

ser=serial.Serial( port='/dev/ttyS0', baudrate=250000, parity ....and so on

This generates an error because the port speed is a non standard unix speed the nearest being 230400 ....which is not close enough.

Note this is not USB. The Rasberry Pi B has the ability to go to this speeds and I have confirmed to myself that it gets to the higher speed ranges with and oscilloscope.

Looks like I need to recompile the kernel. I can do that, but can someone help with which code needs to be modified to get a new non standard uart speed.

The clock speed of the serial port is `3000000Hz` (3MHz).

We can UNDERclock this (as low as 1MHz), but we cannot OVERclock it (with any confidence).

So we will pick the Baud Rate one-above the speed you want and slow it down...

The next speed up from `250000` is `460800`

Now a bit of maths:

``````(NormalClockSpeed / NormalBaud) * DesiredBaud => NewClockSpeed
...where NormalBaud > DesiredBaud

(3000000 / 460800) * 250000 = 1627604
``````

Quick maths sanity-check: 250,000 is a bit more than half of 460,800 ...and 1,627,604 is a bit more than half of 3,000,000 ...yep that looks right :)

So if we reduce the serial clock speed to 1627604 and then specify a serial port speed of 460800, the upshot will be a serial port that runs at 250000.

You can even do the maths backwards to double check things:

``````(NewClockSpeed * NormalBaud) / NormalClockSpeed => ResultantBaud
(1627604 * 460800) / 3000000 = 249,999.97
``````

249,999.97 is uncommonly accurate, you can get away with a lot more deviation than that! [citation required]

So we edit `/boot/config.txt`; Set the serial clock speed to 1627604; And the Baud Rate to 460800

``````init_uart_clock=1627604
init_uart_baud=460800
``````

Bingo. /dev/ttyS0 is running at 250KBaud

Works for me:

On a Pi3 running Raspbian Jessie (it's still on the 4.1 kernel because Adafruit has not bothered to upgrade their PiTFT+ drivers to 4.4).

``````pi@rp3:~ \$ uname -r
4.1.14-v7+

pi@rp3:~ \$ python
Python 2.7.9 (default, Mar  8 2015, 00:52:26)
[GCC 4.9.2] on linux2
>>> from serial import Serial
>>> Serial(port='/dev/ttyS0', baudrate=250000)
Serial<id=0x76aba8d0, open=True>(port='/dev/ttyS0', baudrate=250000, bytesize=8, parity='N', stopbits=1, timeout=None, xonxoff=False, rtscts=False, dsrdtr=False)
``````

It also works on an RPi2 with a 4.4 kernel.

What error are you getting?

• Odd? I have a second PI here at work and tried the command again and it worked. Maybe different kernels? Nevertheless it still doesn't work. normally if you do the Serial(port=/dev/ttyS0,baudrate=9600, the baud rate appears using command line stty -a -F /dev/ttyS0 If I check serial output with an oscilloscope the signal is flat but is good using a standard baud rate – Keir May 17 '16 at 22:27

Linux kernel drivers should be organized by type in the kernel source. Look for the driver that your pi uses, and then inspect the code.

Long ago, I had a quad-port serial card, and supporting it just required adjusting the IRQ value in a driver for a very similar card.

Looking through `linux/drivers/tty`, I see `tty_ioctl.c` which has a table of baud rates near line 269. I haven't tried modifying `baud_table`, but this is where I would start.

``````/*
* Routine which returns the baud rate of the tty
*
* Note that the baud_table needs to be kept in sync with the
* include/asm/termbits.h file.
*/
static const speed_t baud_table[] = {
0, 50, 75, 110, 134, 150, 200, 300, 600, 1200, 1800, 2400, 4800,
9600, 19200, 38400, 57600, 115200, 230400, 460800,
#ifdef __sparc__
76800, 153600, 307200, 614400, 921600
#else
500000, 576000, 921600, 1000000, 1152000, 1500000, 2000000,
2500000, 3000000, 3500000, 4000000
#endif
};
``````
• I downloaded the Rasbery source. In linux/drivers/tty there are C files starting with tty_ and a directory called serial with many files that may be relevant. i was hoping to get a run down on what I might need to change – Keir May 17 '16 at 22:37
• The code you cite doesn't mean much. For a full scoop on how to set baudrates on linux, see this q/a. – Kuba hasn't forgotten Monica Jul 20 '16 at 14:30
• @KubaOber - please move your comment into a standalone answer so that others can more easily find and upvote it. – ObscureRobot Jul 20 '16 at 19:48