# 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.

• There are many ways of doing it. For a C answer, mostly translatable to python, see this stackoverflow question. Commented Jul 20, 2016 at 19:00

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
Commented May 17, 2016 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
Commented May 17, 2016 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. Commented Jul 20, 2016 at 14:30
• @KubaOber - please move your comment into a standalone answer so that others can more easily find and upvote it. Commented Jul 20, 2016 at 19:48