KL27 LPUART strange baud-rate behaviour

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

KL27 LPUART strange baud-rate behaviour

1,382 Views
Francuzzo
Contributor I

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

Labels (1)
0 Kudos
1 Reply

622 Views
xiangjun_rong
NXP TechSupport
NXP TechSupport

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;

}

0 Kudos