How to get 250kbps, 1.250mpbs on iMX6ull

Colibri iMX6ull, V1.1A (528MHz, 256MB RAM, 512MB flash)
Colibri Evaluation Board V3.2B
Toradex Core v5 LTS (Linux kernel 5.4.193, dunfell yocto build of minimal image)
(don’t know where to get BSP version from)

I am trying to get initially 250kbps from Colibri iMX6ull module on Colibri evaluation board, with next stage getting 1.25mbps on a custom carrier.

Scanning thru dtb’s on boot volume, I can’t see any uart’s being mentioned, to implement some of the solutions proposed here (can’t find the right post right now, shame on me).

I would appreciate a two-liner example how to create / change a DTB, compile it and load it. IMHO, this whole DTB, DTBO, etc concept is way over-complicated but who I am to judge :wink:

If I understood correctly, you want to configure the UART to operate at a baud rate of 250,000. No modifications to the device tree are necessary for this. Simply use the following user space command:

stty -F /dev/desired_UART 250000

Please note that not all arbitrary baud rates are supported, but the UART driver will attempt to find the closest possible match. You can verify the set rate by executing the following command:

stty -F /dev/desired_UART

Thank you for the prompt response. However, (at least initially), I can’t select 250000. The “standard” 230400 is accepted, but with 8% difference from 250kbps I am not sure it will work.

root@Colibri:# stty -F /dev/ttymxc4
speed 115200 baud; line = 0;
intr = ^C; quit = ^\; erase = ^?; kill = ^U; eof = ^D; eol = <undef>; eol2 = <undef>;
swtch = <undef>; start = ^Q; stop = ^S; susp = ^Z; rprnt = ^R; werase = ^W; lnext = ^V;
flush = ^O; min = 0; time = 1;
-brkint -icrnl -imaxbel
-opost
-isig -icanon -echo

root@Colibri:# stty -F /dev/ttymxc4 250000
stty: invalid argument '250000'

root@Colibri:# stty -F /dev/ttymxc4 230400
root@Colibri:# stty -F /dev/ttymxc4
speed 230400 baud; line = 0;
intr = ^C; quit = ^\; erase = ^?; kill = ^U; eof = ^D; eol = <undef>; eol2 = <undef>;
swtch = <undef>; start = ^Q; stop = ^S; susp = ^Z; rprnt = ^R; werase = ^W; lnext = ^V;
flush = ^O; min = 0; time = 1;
-brkint -icrnl -imaxbel
-opost
-isig -icanon -echo

root@Colibri:#  ls -la /dev/colibri-uart*
lrwxrwxrwx    1 root     root             7 Jun 15 01:05 /dev/colibri-uarta -> ttymxc0
lrwxrwxrwx    1 root     root             7 Jun 15 01:05 /dev/colibri-uartb -> ttymxc1
lrwxrwxrwx    1 root     root             7 Jun 15 01:05 /dev/colibri-uartc -> ttymxc4

root@Colibri:#  grep uart/proc/tty/drivers
IMX-uart             /dev/ttymxc   207 16-23 serial

root@Colibri:# setserial /dev/ttymxc4
 /dev/ttymxc4, UART: undefined, Port: 0x0000, IRQ: 63

root@Colibri:#

The only difference from reference minimal recipe is adding
CORE_IMAGE_EXTRA_INSTALL += "dropbear inetutils setserial"
to conf/local.conf when baking.

Hi @Logosol,

250000 and 1250000 are not on the list of supported baud rates, this is why you see “unsupported”. You need to use ioctl to set custom baud rate

#include <stdlib.h>
#include <sys/ioctl.h>
#include <fcntl.h>
#include <asm/termbits.h>
#include <sys/ioctl.h>
#include <unistd.h>

void main(void)
{
struct termios2 newtio;

int	fd = open( "/dev/ttymxc1", O_RDWR | O_NOCTTY);
	
	ioctl(fd, TCGETS2, &newtio);	
	newtio.c_cflag &= ~CBAUD;    //Remove current baud rate
	newtio.c_cflag |= CBAUDEX;    //Allow custom baud rate using int input
	newtio.c_ispeed = 1250000;    //Set the input baud rate
	newtio.c_ospeed = 1250000;    //Set the output baud rate
	ioctl(fd, TCSETS2, &newtio);

	write (fd, "123", 3);
}

For some baud rates you may use setserial to override 38400 baud rate with custom baud rate.
`
setserial /dev/ttymxc1 spd_cust
setserial /dev/ttymxc1 divisor 555

Unfortunately both your speeds won't work on iMX6ULL without modifying DT to change base UART speed. With iMX6ULL default 66MHz UART clock, base rate is 66MHz/16=4125000Hz, which gives non integer result dividing by 250000 or 1250000.setserial` takes only integer divisor.

Regrettably, not every speed is available as it is determined by the integer divider. May I ask why you specifically require a speed of 250kbps? The majority of devices typically support the “standard” speed of 230400 bps, which should suffice for most applications.

Alex,

Our application talks to a motion controller which uses DSP clocked at 20MHz. DSP 's UART baud rates are obtained from this 20MHz clock, therefore 1.25MBps (/16) and 250KBps (/80). And as you may guess, these 20MHz are coming from a crystal, and these controllers are all around the world (for now). 1.25MBps baud rate is used for multi-axes control, where more data must be transferred.

If we can use 66MHz clock for UART, this gives us nice divisors of 264 (for 250KBps) and 53 (which will give us withing 1% of target 1.25MBps).

UART on iMX supports fractional baud rate divider. Like I said, your baud ratesates are not on the list of Linux supported baud rates, which includes quite odd ones like 5.760.000, 2000000, but not yours. You need to use ioctl to switch to your custom baud rates. Custom integer divider with setserial is impractical because of very low base clock (not 66MHz, but 1/16th of 66MHz, or 4.125MHz). So either ioctl() or setserial if you manage to switch in DT from 66MHz to integer multiple of 1.25MHz*16 = 20/40/60/… MHz.
Custom baud rate is kept as it is after return from app, which calls ioctl().