Ciao to everybody,
a ctm is reporting me a strange behavior (that is replicable on FRDM too) on LPUART of MKL27.
They use:
MKL27Z256VLH4
1N71K
CTAB1435B
KDS: 3.0.0
KSDK: 1.3.0
They change the baud-rate with just here after code:
void ChangeUartSpeed(uint32_t xData)
{
SCI_TI_InitConfig0.baudRate = xData;
/* UART clock source is either system or bus clock depending on instance */
uint32_t uartSourceClock = CLOCK_SYS_GetUartFreq(FSL_SCI_TI);
/* Initialize UART baud rate, bit count, parity and stop bit. */
LPUART_Type * base = g_lpuartBase[FSL_SCI_TI];
LPUART_HAL_SetBaudRate(base, uartSourceClock, xData);
}
The result is a baudrate exactely 3 times less than expected, if the clock is the MCG_IRCLK (internal reference one): set for 115200 to obtain 38400.
OR
The result is a baud-rate half than expected , if the clock is the 48MHz (for the USB): set for 19200 to obtain 38400.
- Remark_1: If the same code is used for the normal UART (not LP), the result is OK.
- Remark_2: If you don't change the default baud-rate, all is OK.
- Remark_3: the issue is replicable on FRDM-KL27; Attached you can find an "example" where:
° to handle the 2 differente baud-rate edit uart_xmad_task.c file (in Source-Interface-UART)
* at line 16 the parameter #define CORR_FACTOR (1) is the correrction to obtain the right Baud-rate.
* at line 54 if you comment the "ChangeUartSpeed" function callng, --> the baud-rate is the one set by Proc.Exp.
I have alredy checked the ERRATA but there was nothing that can explain it.
...may be an SDK issue ?
The questions are:
Do you know it ?
...is HW or SW ?
do you have any workaround ?
The ctm is not so afraid of it ,because they found a way to solve....BUT of course they prefer to work with no "strange" workaround not coming from NXP.
Any suggestion is more than welcome.
Thanks a lot in advance
Franco
Original Attachment has been moved to: x-MAD-TI_FRDM-KL27z.zip
Hi, Franco,
Regarding your question, frankly speaking, I am not sure if the following code is correct or not. How about setting the osr=15? from my opinion, the transmitter baudrate=(LPUART ASYNCH Module Clock)/(SBR[12:0]*16), so the OSR bits should be equal to 15.
Pls have a try.
BR
XiangJun Rong
/*FUNCTION**********************************************************************
*
* Function Name : LPUART_HAL_SetBaudRate
* Description : Configures the LPUART baud rate.
* In some LPUART instances the user must disable the transmitter/receiver
* before calling this function.
* Generally, this may be applied to all LPUARTs to ensure safe operation.
*
*END**************************************************************************/
lpuart_status_t LPUART_HAL_SetBaudRate(LPUART_Type * base,
uint32_t sourceClockInHz,
uint32_t desiredBaudRate)
{
uint16_t sbr, sbrTemp, i;
uint32_t osr, tempDiff, calculatedBaud, baudDiff;
/* This lpuart instantiation uses a slightly different baud rate calculation
* The idea is to use the best OSR (over-sampling rate) possible
* Note, osr is typically hard-set to 16 in other lpuart instantiations
* First calculate the baud rate using the minimum OSR possible (4) */
osr = 4;
sbr = (sourceClockInHz/(desiredBaudRate * osr));
/*set sbr to 1 if the sourceClockInHz can not satisfy the desired baud rate*/
if(sbr == 0)
{
sbr = 1;
}
calculatedBaud = (sourceClockInHz / (osr * sbr));
if (calculatedBaud > desiredBaudRate)
{
baudDiff = calculatedBaud - desiredBaudRate;
}
else
{
baudDiff = desiredBaudRate - calculatedBaud;
}
/* loop to find the best osr value possible, one that generates minimum baudDiff
* iterate through the rest of the supported values of osr */
for (i = 5; i <= 32; i++)
{
/* calculate the temporary sbr value */
sbrTemp = (sourceClockInHz/(desiredBaudRate * i));
/*set sbrTemp to 1 if the sourceClockInHz can not satisfy the desired baud rate*/
if(sbrTemp == 0)
{
sbrTemp = 1;
}
/* calculate the baud rate based on the temporary osr and sbr values */
calculatedBaud = (sourceClockInHz / (i * sbrTemp));
if (calculatedBaud > desiredBaudRate)
{
tempDiff = calculatedBaud - desiredBaudRate;
}
else
{
tempDiff = desiredBaudRate - calculatedBaud;
}
if (tempDiff <= baudDiff)
{
baudDiff = tempDiff;
osr = i; /* update and store the best osr value calculated */
sbr = sbrTemp; /* update store the best sbr value calculated */
}
}
/* Check to see if actual baud rate is within 3% of desired baud rate
* based on the best calculate osr value */
if (baudDiff < ((desiredBaudRate / 100) * 3))
{
/* Acceptable baud rate, check if osr is between 4x and 7x oversampling.
* If so, then "BOTHEDGE" sampling must be turned on */
if ((osr > 3) && (osr < 8))
{
LPUART_BWR_BAUD_BOTHEDGE(base, 1);
}
/* program the osr value (bit value is one less than actual value) */
LPUART_BWR_BAUD_OSR(base, (osr-1));
/* write the sbr value to the BAUD registers */
LPUART_BWR_BAUD_SBR(base, sbr);
}
else
{
/* Unacceptable baud rate difference of more than 3% */
return kStatus_LPUART_BaudRateCalculationError;
}
return kStatus_LPUART_Success;
}