0

Is the Snapdragon 410c ttyMSM1 (msm_serial) running Linux (linaro) capable of natively providing the DMX protocol 250,000 baudrate?

    root@linaro-developer:~# stty -F /dev/ttyMSM1 cs8 -parenb cstopb 250000

stty: invalid argument ‘250000’ 

Try 'stty --help' for more information.

250000 is not in the list of supported baudrates in the kernel/drivers/tty/tty_ioctl.c:baud_table[], and the setserial custom 38400 baudrate commands do not override the baudrate correctly.

root@linaro-developer:~# setserial -av /dev/ttyMSM1 spd_cust
[  491.312449] msm_serial 78af000.serial: setserial sets custom speed on ttyMSM1. This is deprecated.

Cross-posted here (I will keep both boards in sync as I work towards an answer): http://www.96boards.org/forums/topic/linaro-ttymsm1-uart0-dmx-250000-baudrate/#post-17264

Sam Protsenko
  • 14,045
  • 4
  • 59
  • 75
spearson
  • 1,016
  • 8
  • 18
  • 1
    You have to use an application that supports `BOTHER`. AFAIK *picocom* can be compiled with such support. Didn't try though. – 0andriy Sep 11 '16 at 10:30

1 Answers1

0

I had similar problem and wasn't able to find correct tool for my case, so I decided it's faster to come up with my own code. Next code uses termios2 API (and BOTHER flag, that Andy Shevchenko mentioned in his comment) for setting custom baud rate for serial port.

Never looked in your serial driver code, but you can try this code first:

main.c:

#include "termios2.h"

#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <errno.h>
#include <unistd.h>
#include <sys/ioctl.h>

int main(int argc, char *argv[])
{
    struct termios2 tio;
    int fd, ret, speed;

    if (argc != 3) {
        printf("%s device speed\n\n"
                "Set speed for a serial device.\n"
                "For instance:\n    %s /dev/ttyUSB0 75000\n",
                argv[0], argv[0]);
        return EXIT_FAILURE;
    }

    fd = open(argv[1], O_RDONLY);
    if (fd == -1) {
        perror("open() error");
        return EXIT_FAILURE;
    }

    speed = atoi(argv[2]);

    ret = ioctl(fd, TCGETS2, &tio);
    if (ret == -1) {
        perror("TCFETS2 error");
        close(fd);
        return EXIT_FAILURE;
    }

    /* Speed settings */
    tio.c_cflag &= ~CBAUD;
    tio.c_cflag |= BOTHER;
    tio.c_ispeed = speed;
    tio.c_ospeed = speed;

    /* Ignore CR (\r) characters */
    tio.c_iflag |= IGNCR;

    ret = ioctl(fd, TCSETS2, &tio);
    if (ret == -1) {
        perror("TCSETS2 error");
        close(fd);
        return EXIT_FAILURE;
    }

    close(fd);
    return 0;
}

termios2.h:

/* The content for this file was borrowed from:
 * /usr/include/asm-generic/termbits.h
 *
 * We can't just include <asm/termios.h>, because it will interfere with
 * regular <termios.h> (compiler will give some errors).
 * So it's better to copy needed stuff here instead.
 */

#ifndef TERMIOS2_H
#define TERMIOS2_H

#include <termios.h>

/* termios.h defines NCCS as 32, but for termios2 we need it to be 19 */
#undef NCCS
#define NCCS        19

#define BOTHER      0010000

struct termios2 {
    tcflag_t c_iflag;       /* input mode flags */
    tcflag_t c_oflag;       /* output mode flags */
    tcflag_t c_cflag;       /* control mode flags */
    tcflag_t c_lflag;       /* local mode flags */
    cc_t c_line;            /* line discipline */
    cc_t c_cc[NCCS];        /* control characters */
    speed_t c_ispeed;       /* input speed */
    speed_t c_ospeed;       /* output speed */
};

#endif /* TERMIOS2_H */

Build:

$ gcc -Wall -O2 main.c -o set-tty-speed

Usage:

$ ./set-tty-speed /dev/ttyMSM1 250000

Also see this question: How to set a custom baud rate on Linux?

Community
  • 1
  • 1
Sam Protsenko
  • 14,045
  • 4
  • 59
  • 75
  • Thanks for your response. I had seen this post and had struggled with the compiler errors. AFAICT this is not working on the snapdragon. I am concerned that the 250000 baudrate is not supported by the hardware, or at least requires a tweaking of the system clocks. I am going to dive into the driver later this week and will update the question at that time. – spearson Sep 14 '16 at 18:27
  • The trick is to describe `termios2` manually, rather than include `asm/termios.h`. Try to use the code I provided. It builds like a charm for me. Other than that, if the problem is actually in the driver (`msm_serial`), then this code alone won't help you, of course. But I can confirm it works for my PL2303. So at least you can use it to verify that the actual issue is in your driver. – Sam Protsenko Sep 14 '16 at 18:39