/* Determines and sets best dividers to get a target baud rate */ uint32_t Chip_UART_SetBaudFDR(LPC_USART_T *pUART, uint32_t baudrate) { uint32_t uClk; uint32_t dval, mval; uint32_t dl; uint32_t rate16 = 16 * baudrate; uint32_t actualRate = 0; /* Get Clock rate */ uClk = Chip_Clock_GetMainClockRate(); /* The fractional is calculated as (PCLK % (16 * Baudrate)) / (16 * Baudrate) * Let's make it to be the ratio DivVal / MulVal */ dval = uClk % rate16; // NOTE: added initialization. Otherwise value may be used without initialization. mval = 0; /* The PCLK / (16 * Baudrate) is fractional * => dval = pclk % rate16 * mval = rate16; * now mormalize the ratio * dval / mval = 1 / new_mval * new_mval = mval / dval * new_dval = 1 */ if (dval > 0) { mval = rate16 / dval; dval = 1; /* In case mval still bigger then 4 bits * no adjustment require */ if (mval > 12) { dval = 0; } } dval &= 0xf; // TODO: mval may be non initialized. mval &= 0xf; dl = uClk / (rate16 + rate16 * dval / mval); /* Update UART registers */ Chip_UART_EnableDivisorAccess(pUART); Chip_UART_SetDivisorLatches(pUART, UART_LOAD_DLL(dl), UART_LOAD_DLM(dl)); Chip_UART_DisableDivisorAccess(pUART); /* Set best fractional divider */ pUART->FDR = (UART_FDR_MULVAL(mval) | UART_FDR_DIVADDVAL(dval)); /* Return actual baud rate */ actualRate = uClk / (16 * dl + 16 * dl * dval / mval); return actualRate; }
/* Determines and sets best dividers to get a target bit rate */ 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_GetMainClockRate(); 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; }