This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

AM335x based Custom board : Custom UART Baud Rate

Other Parts Discussed in Thread: AM3358

Hi


I have a custom hardware based on AM3358 processor with ti-sdk-am335x-evm-07.00.00.00-Linux-x86 version. I want to set the UART baud rate to exact 10400bps.

Kindly help.

Thanks

Richin Johns

  • Hi Richin,

    Divisor value for the desired UART baud rate is calculated as:

    Divisor = UART input clock frequency / (Desired baud rate * 16) if MDR1.MODESELECT=0 or
    Divisor = UART input clock frequency / (Desired baud rate * 13) if MDR1.MODESELECT=3
    UART input clock frequency is 48MHz. so:
    48 000 000 / (10 400 *16) = 288.46
    48 000 000 / (10 400 *13) = 355.03
    Choosing a divisor value of 355 with 13x oversampling will give 10 400.87bps, which is 0.008% off the desired baud rate and can be used with no problem.
  • Thank you for the quick reply.

    1) Is it possible to set this baud rate for a particular UART port(eg. UART2)? If so will it affect other UART ports?

    2) which files in the SDK should be modified for implementing the changes?

    Thanks,

    Richin Johns

  • 1. Yes, this is individual per UART.

    2. I will ask somebody from the SW team to answer this.

  • Hi,

    The driver that needs to be modified is omap-serial.c, it is located in drivers/tty/serial

    Your starting point should be serial_omap_get_divisor() function.

    Have in mind that changing baud rate (divisor value) is not just a matter of assigning new values to DLL & DLH. The divisors are calculated per use case. Currently, as I see in SDK7, divisor is set to 16 if baud rate is MODE16x & 13 otherwise.

    Hope this helps.


    Best Regards,

    Yordan

  • As the you suggestion I have gone through the omap-serial.c file and was able to understand that the divisor is calculated automatically based on the BAUD we set for the particular UART port.(either 13 or 16).  As suggested the serial_omap_get_divisor() function gets the BAUD rate from uart_get_baud_rate() function which is defined in serial_core.c. And in uart_get_baud_rate() function baud is returned from tty_termios_baud_rate() function defined in tty_iotcl.c.

    here is that function.

    speed_t tty_termios_baud_rate(struct ktermios *termios)
    {
        unsigned int cbaud;

        cbaud = termios->c_cflag & CBAUD;

    #ifdef BOTHER
        /* Magic token for arbitrary speed via c_ispeed/c_ospeed */
        if (cbaud == BOTHER)
            return termios->c_ospeed;
    #endif
        if (cbaud & CBAUDEX) {
            cbaud &= ~CBAUDEX;

            if (cbaud < 1 || cbaud + 15 > n_baud_table)
                termios->c_cflag &= ~CBAUDEX;
            else
                cbaud += 15;
        }
        return baud_table[cbaud];
    }


    now the baud rate which is returned is found from the baud_table and cbaud points to the index. and cbaud is calculated based on : cbaud = termios->c_cflag & CBAUD.

    1) Can u tell me in which file is this c_cflag value defined so that I can modify it for 10400baud.

    What are the others things related to baud that I should modify to set 10400baud for UART2 and where these files are located?

    2) It is also specified we can define BOTHER for custom baud rate but where should it be defined and which file should i set the value of termios->c_ospeed = 10400.

    3) also I think i can hardcode 10400 as altbaud in uart_get_baud_rate() in serial_core.c in the driver file. But how to request standard baud rate of 38,4kbps via a termios call for UART2.

    Thanks

    Richin

  • Hi Richin,

    AFAIK the baud rate & divisors are set per the requirements of the specific tty port (usually defined by the user).  That is how c_cflag and other termios elements get their values assigned (not clearly assigned in the kernel as I said at the beginning). 

    There is a standard set of values in the kernel, in case user does not properly request the tty (uart) port. Check the tty_std_termios definition in tty_io.c. Also check the related headers (tty.h, termios.h, tty_flags.h, etc.... )

    Also one question: what is the purpose of this UART (?), because if it is a debug console you can change its baud rate from the console settings in your u-boot config and your kernel defconfig files.

    Best Regards,

    Yordan

  • Thank you Yordan.

    So if i set altbaud in uart_get_baud_rate() in serial_core.c as 10400 in the kernal file and define BOTHER and whenever i request to set baud for particular UART port through system call as 38400 then it will set it to 10400. correct?

    And no it is not for a debug console. it is for initialising a communication request with a hardware and then I have to change the baud to 115200.

    Thanks ,

    Richin

  • Hi Richin,

    Yes, that is my understanding as well.

    Best Regards,

    Yordan