Linaro ttyMSM1 (UART0) DMX 250000 baudrate


#1

I am trying to use the Dragonboard ttyMSM1 for DMX under Linaro. I need to set a custom baudrate of 250 000 baud. The 230400 supported baudrate is with 7% of 250 000 baudrate, so is out of spec.

root@linaro-developer:~# stty -F /dev/ttyMSM1 cs8 -parenb cstopb 230400 root@linaro-developer:~# stty -F /dev/ttyMSM1 cs8 -parenb cstopb 250000 stty: invalid argument ‘250000’ Try 'stty --help' for more information.

Any help would be greatly appreciated.


#2

Hi @Simon

“Technically” a UART should work with up to 5% error so you are correct a 7% error will not work. The Baud rate generator is capable of generating many baud rates, however 250k is not a ‘standard’ baud rate supported by the stty command.

I took a quick look in drivers/tty/ttyioctl.c and 250k is not listed in the possible speeds that can be set, so I think you will need to make changes to the kernel to support 250k baud.

Full Disclosure: I am an employee of Qualcomm Canada, any opinions expressed in this or any other post may no reflect the opinions of my employer.


#3

With the same Kernel, I can connect and run a FTDI USB-232 IC and I can setup the driver for 250k as below. The same type of tty configuration does not work with the APQ8016.


root@linaro-developer:~# apt-get install setserial
root@linaro-developer:~# setserial -a /dev/ttyUSB0 spd_cust
root@linaro-developer:~# setserial -a /dev/ttyUSB0 divisor 96
root@linaro-developer:~# stty cs8 -parenb cstopb -F /dev/ttyUSB0 38400
root@linaro-developer:~# setserial -a /dev/ttyUSB0
/dev/ttyUSB0, Line 0, UART: unknown, Port: 0x0000, IRQ: 0
        Baud_base: 24000000, close_delay: 0, divisor: 96
        closing_wait: infinite
        Flags: spd_cust low_latency
stty: /dev/ttyUSB0: unable to perform all requested operations
root@linaro-developer:~# stty -F /dev/ttyUSB0
speed 0 baud; line = 0;
-brkint -imaxbel
root@linaro-developer:~# echo "Hello World" > /dev/ttyUSB0

Trying the same configuration on the APQ_8016, the first error is that spd_cust is deprecated for msm_serial.


root@linaro-developer:~# apt-get install setserial
root@linaro-developer:~# setserial -av /dev/ttyMSM1 spd_cust
[  491.312449] msm_serial 78af000.serial: setserial sets custom speed on ttyMSM1. This is deprecated.
/dev/ttyMSM1, Line 1, UART: undefined, Port: 0x0000, IRQ: 137
        Baud_base: 230400, close_delay: 50, divisor: 0
        closing_wait: 3000
        Flags: spd_cust

Setting the baudrate to 500000, which is a legitimate baudrate from kernel/drivers/tty/tty_ioctl.c sets without error, but the actual baudrate of the ttyMSM1 is 921600 (rounding to nearest). Setting the baudrate to 1000000 (1M) does select the correct baudrate.


root@linaro-developer:~# stty -F /dev/ttyMSM1 500000
root@linaro-developer:~# echo "Hello World" > /dev/ttyMSM1
root@linaro-developer:~# stty -F /dev/ttyMSM1 1000000
root@linaro-developer:~# echo "Hello World" > /dev/ttyMSM1

The 1M baudrate is promising that 250k might be possible with the right divisor but selecting the 38400 custom baudrate setting does not have the desired response (is deprecated).


kernel/drivers/tty/serial/serial_core.c

    /*
     * Old custom speed handling.
     */
    if (baud == 38400 && (port->flags & UPF_SPD_MASK) == UPF_SPD_CUST)
        quot = port->custom_divisor;
    else
        quot = DIV_ROUND_CLOSEST(port->uartclk, 16 * baud);

    return quot;
...

Any advice where to start with the kernel modifications, or whether a 250k baudrate is supported by the APQ8016 or APQ8016/Linux combination.

Thanks.


#4

Have any luck with this? I too am running into this same custom baudrate issue. I can set the speed on other USB Uart bridges but I want to use the ttyMSM1 at 100000K. I have tried several methods using ioctrl and terminus that involve setting the divider as well as the baud_base… some of the suggestions are as follows:

This website gives a good overview of a few ways (all of which fail) :
https://www.downtowndougbrown.com/2013/11/linux-custom-serial-baud-rates/

I am able to set baudrates but ONLY those that are defined in the driver using these methods. Again, these methods work on a USB to UART bridge such as an FTDI chip.