lpcware

Lpc43xx uart baudrate calculation

Discussion created by lpcware Employee on Jun 15, 2016
Latest reply on Jun 15, 2016 by lpcware
Content originally posted in LPCWare by JoeM on Thu Apr 23 00:03:08 MST 2015
Using an NGX Xplorer with Lpc4330 and driving Uart0 at 1 MBaud for some debug output.
Currently using Lpcopen 2.12 and Lpcxpresso.

Configuring Uart0 to 1 MBaud won't work because of a rounding error within the baudrate calculation in Chip_UART_SetBaud().

Originally Chip_UART_SetBaud() code:


uint32_t Chip_UART_SetBaud(LPC_USART_T* pUART, uint32_t baudrate) {
    uint32_t div, divh, divl, clkin;

    /* Determine UART clock in rate without FDR */
    clkin = Chip_Clock_GetRate(UART_BClock[Chip_UART_GetIndex(pUART)]);
    div = clkin / (baudrate * 16);

    /* High and low halves of the divider */
    divh = div / 256;
    divl = div - (divh * 256);

    Chip_UART_EnableDivisorAccess(pUART);
    Chip_UART_SetDivisorLatches(pUART, divl, divh);
    Chip_UART_DisableDivisorAccess(pUART);

    /* Fractional FDR alreadt setup for 1 in UART init */
    return clkin / div;
}


IMHO, the errornous part resists in the statement
    div = clkin / (baudrate * 16);

and changing that to something like this:
    tmp = baudrate * 16;
    div = (clkin + tmp/2) / tmp;

make it work for e.g. 921,6 kBaud and 1 MBaud.

But now, another colleague says that it better has to be changed to:
    tmp = baudrate * 16;
    div = (clkin + (tmp - 1)) / tmp;

What is the best / most correct way for calculating the Uart baudrate?

BTW: The errornous calculation can be found both in Lpcopen 2.12 and 2.16.

Outcomes