FRDM K82F uart problem

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

FRDM K82F uart problem

1,647 Views
akimata
Contributor IV

Hello after a while i still didn't find answer to my question and i'm still unable to set proper baudrate on lpuart0.

Before i start i want to say that i read almost every post about lpuart on the forum, config is correct except baudrate and clocking.

 

Formula from datasheet:

Baudrate clock/(SBR*(OSR+1))

So i noticed that only  value of 16 and 32 can be set in OSR field (15 and 31), any other value results in getting 16/32. Also  in SBR field there is  always "1"  on third spot from LSB,  so  if i set 8 result in 12, 1 results in 5, 12 results in 12 etc.

Also there is no way to set FLL/PPL or IRC48M in SIM_SOPT2, value in the register doesn't want to change or clear, only fast internal oscillator can be set.

Knowing these problems i can easily predict what baudrate i will get but it's so problematic because setting any of typical baudrates highter than 9600 seems impossible.

 

Noticed that on  custom K80 board  also on FRDM-K82.

 

Any ideas what might be wrong?

Maybe it's a bug?

0 Kudos
15 Replies

1,285 Views
kalei_joanel
Contributor I

The LPUART interrupt only fires 6-8 times and never again after that. This behavior is independent from the current position in the code. I tested it by sending the first batch of data long after the program enters the infinite loop and also by sending it right at the start of the program (after lpuart interrupt initialization). Same behavior in both cases.

0 Kudos

1,285 Views
akimata
Contributor IV

My problem is not related to interrupt service, i'm not even using interrupts and still can't receive anything at all, DATA register is just empty all the time and RDRF is never set

0 Kudos

1,285 Views
mjbcswitzerland
Specialist V

Hi Grzegorz

Load the binary application at http://www.utasker.com/kinetis/FRDM-K82F.html to your FRDM-K82F board.
It LPUART connects to the OpenSDA VCOM interface at 115200Baud and supplied a command line menu interface. In its UART menu you can command different Baud rates too.
In the I/O menu there is also a memory debugger interface where you can read internal registers to see how they are setup (or else use a debugger).

Like this you can see how the LPUART is set up for each of the Baud rates.

     Main menu
===================
1              Configure LAN interface
2              Configure serial interface
3              Go to I/O menu
4              Go to administration menu
5              Go to overview/statistics menu
6              Go to USB menu
7              Go to I2C menu
8              Go to utFAT disk interface
9              FTP/TELNET commands
a              CAN commands
help           Display menu specific help
quit           Leave command mode


   Serial config.
===================
up                    go to main menu
set_baud              Set serial baud rate
set_stop              Set stop bits (1/1.5/2)
set_bits              Set data bits (7/8)
set_par               Set parity (EVEN/ODD/NONE)
set_flow              Set flow control (XON/RTS/NONE)
set_high_water        Set flow stall (%) [1..99]
set_low_water         Set flow restart (%) [1..99]
show_config           Show serial configuration
save                  Save configuration to FLASH
help                  Display menu specific help
quit                  Leave command mode


 Input/Output menu
===================
up             go to main menu
md             Memory Display [address] [<l>|<w>|<b>] [num]
mm             Memory Modify [address] [<l>|<w>|<b>] [val]
mf             Memory Fill [address] [<l>|<w>|<b>] [val] [num]
sd             Storage Display {as md}
sm             Storage Modify {as mm}
sf             Storage Fill {as mf}
se             Storage Erase [address] [len-hex]
set_ddr        Set port type [1..4] [<i>|<o>
get_ddr        Get data direction [1..4]
read_port      Read port input [1..4]
write_port     Set port output [1..4] [0/1]
lp_cnt         Read LPTMR CNT
save           Save port setting as default
help           Display menu specific help
quit           Leave command mode

It is using IRC48MHz as LPUART clock and here are relevant code snippets that may help you:

SIM_SOPT2 = ((SIM_SOPT2 & ~(SIM_SOPT2_LPUARTSRC_MGC)) | (SIM_SOPT2_LPUARTSRC_SEL | SIM_SOPT2_PLLFLLSEL_IRC48M)); // select the 48MHz IRC48MHz clock as source for the LPUART

usDivider = (((48000000/8/115200) + 1)/2);

lpuart_reg->LPUART_BAUD = ((lpuart_reg->LPUART_BAUD & ~LPUART_BAUD_SBR) | (usDivider | LPUART_BAUD_OSR_16)); // set the (new) baud rate

Regards

Mark


Kinetis: http://www.utasker.com/kinetis.html
Kinetis KL82:
- http://www.utasker.com/kinetis/FRDM-KL82Z.html
- http://www.utasker.com/kinetis/TWR-KL82Z72M.html


For less questions and faster, cheaper developments: try uTasker for Kinetis

pastedImage_5.png

0 Kudos

1,285 Views
akimata
Contributor IV

I managed to set correct dividers by using "=" instead of "|=" now the baudrate is really close to 57600.

Clock is set to 4Mhz and with these dividers i should get close to 57150 which is in 1,5% error. Sending works fine and i can receive frames correctly on other divices.

The problem now is that i can't receive anything. RDRF flag is never set.

Here is the simplest code i wrote just to test if uart is working:

#include <stdio.h>
#include "board.h"
#include "peripherals.h"
#include "pin_mux.h"
#include "clock_config.h"
#include "MK80F25615.h"
#include "fsl_debug_console.h"

uint8_t data[1000];
uint8_t i=0;


int main(void) {

/* Init board hardware. */
BOARD_InitBootPins();
BOARD_InitBootClocks();
BOARD_InitBootPeripherals();
/* Init FSL debug console. */
BOARD_InitDebugConsole();

MCG -> SC &= ~MCG_SC_FCRDIV_MASK;
MCG -> C1 |= MCG_C1_IRCLKEN_MASK |MCG_C1_IREFSTEN_MASK;
MCG -> C2 |= MCG_C2_IRCS_MASK;

SIM -> SOPT2 = (SIM_SOPT2_LPUARTSRC(3));
SIM -> SCGC5 |= SIM_SCGC5_PORTD_MASK;
SIM -> SCGC2 |= SIM_SCGC2_LPUART0_MASK;


PORTD-> PCR[6] = PORT_PCR_MUX(0x03);
PORTD-> PCR[7] = PORT_PCR_MUX(0x03);

LPUART0 -> CTRL &= ~LPUART_CTRL_TE_MASK;
LPUART0 -> CTRL &= ~LPUART_CTRL_RE_MASK;

//baud settings
LPUART0 -> BAUD = (LPUART_BAUD_SBR(14)|LPUART_BAUD_OSR(4));


LPUART0 -> CTRL &= ~LPUART_CTRL_M_MASK;
LPUART0 -> CTRL &= ~LPUART_CTRL_PE_MASK;
LPUART0 -> BAUD &= ~LPUART_BAUD_SBNS_MASK;


LPUART0 -> CTRL |= LPUART_CTRL_TE_MASK;
LPUART0 -> CTRL |= LPUART_CTRL_RE_MASK;

while(1)
{

while(!(LPUART0 -> STAT & LPUART_STAT_RDRF_MASK));
data[i] =LPUART0->DATA;
i++;

}
return 0 ;
}

0 Kudos

1,285 Views
mjbcswitzerland
Specialist V

Hi

Have you checked other flags in the status register to see whether there are error flags being set?

I would also question the Baud rate calculation:

LPUART0 -> BAUD = (LPUART_BAUD_SBR(14)|LPUART_BAUD_OSR(4));

You are using 4MHz (don't forget that it also has its own tolerance too) and in 4x oversampling mode, which seems to give 4000000/4/14 = 71.428kHz

The closest you can get to 57600Baud is with divide 18 (55.556kHz) or divide 17 (58.824kHz)

Question:
- LPUART_BAUD_OSR(4) - have you checked how this macro works ? Does it subtract 1 from the OSR value to program 0x3, which is the correct value for 4x oversampling

Regards

Mark

0 Kudos

1,285 Views
akimata
Contributor IV

Yes i checked LPUART0_STAT and there is no errors. 

According to this formula: Baudrate clock/(SBR*(OSR+1))

4000000/(14*(4+1)) = 57142

Checked with oscilloscope and the baudrate seems  to be around 57000

Question:
- LPUART_BAUD_OSR(4) - have you checked how this macro works ? Does it subtract 1 from the OSR value to program 0x3, which is the correct value for 4x oversampling

If i use this macro LPUART_BAUD_OSR(4) , the OSR is set to 4 but the main baudrate clock is divided by value +1

0 Kudos

1,285 Views
mjbcswitzerland
Specialist V

Grzegorz

The Baud is indeed correct - I didn't realise that an oversampling rate of 5 was possible (I though it was 4, 16 or 32) as typically 16x is used by UARTs.

Otherwise I didn't see why you weren'r receiving anything....

Regards

Mark

0 Kudos

1,285 Views
akimata
Contributor IV

How about this line:

data[i] =LPUART0->DATA;

Is it correct way to read from UART? because there is no separate register here and i'm a little confused. I don't receive any data, even corrupted. 

Strange  that RDRF is always 0, but correct data is comming to uC for sure

0 Kudos

1,285 Views
mjbcswitzerland
Specialist V

Grzegorz

Yes, the DATA register is read for reception and written for transmission.

By the way, it is technically more elegant to use a an oversampling of 14 and divide by 5, than oversampling of 5 and divide by 14 - higher oversampling gives better reception sampling points. It has nothing to do with basic operation though....See figure 2.1 of http://www.utasker.com/docs/uTasker/uTaskerUART.PDF

Regards

Mark

P.S. As I initially noted, if you load the reference binary you can then compare the UART registers to see whether you can find a difference that explains something. It will be using DMA for transmission but rx interrupts for reception.

0 Kudos

1,285 Views
akimata
Contributor IV

I changed OSR and SBR as u suggested because it makes a lot of sense but still nothing can received and i don't have frdm board now to test your binary, only custom board.

I checked almost every register and everything seems fine, electrical connection is also correct

0 Kudos

1,285 Views
mjbcswitzerland
Specialist V

Grzegorz

I though that you have a FRDM-K82F from your first post stating "Noticed that on  custom K80 board  also on FRDM-K82.".

If you tell me which clock source your board has (I understand you want LPUART0 on PTD6 and PTD7) I can send you a binary that will run on it (as long as you know how to load binaries - or SREC, Hex etc. images).

If you are doing this for a school project or hobby I can also give you access to a complete solution with interrupt or DMA operation on all LPUARTs (and simulation of the internal operation so that you will be able to understand all details).

If you are doing your work in a professional capacity ask you employer to test the professional uTasker solution for the K82F which will also give you immediate and complete operation, in order to reduce project costs and delays.

Regards

Mark

0 Kudos

1,285 Views
akimata
Contributor IV

So i checked everything twice and LPUART1 works without any problem with these settings when LPUART0 doesn't and the problem exists on custom board and also on frdm k82f. Is LPUART0 somehow used (maybe debugging console) and i'm not aware of it?

0 Kudos

1,285 Views
mjbcswitzerland
Specialist V

Grzegorz

All LPUARTs in the K82 use the same LPUART clock so if it works on one LPUART but not on another it more likely to be a problem with the configuration of the particular LPUARTx_RX input.

Regards

Mark

0 Kudos

1,285 Views
jorge_a_vazquez
NXP Employee
NXP Employee

Hi Grzegorz Mikitiuk

I use the SDK example frdmk82f_lpuart_interrupt_transfer and I only modify #define DEMO_LPUART LPUART4 for LPUART0, enable the pins and tests with different baud rates, I don't see any issue in the functionality of this demo. Could you try this test to verify that this is not a hardware issue related?

Regards

Jorge Alcala

0 Kudos

1,285 Views
akimata
Contributor IV

I'm testing it now on k80 chip at the moment and yes i'm using PTD6 and PTD7 for lpuart0.Clock source is fast internal oscillator, it seems pretty accurate comparing to FLL one I don't know how to flash binaries but i will find it out eventually. Yeah it's kind of school project and i just want to know how to do few things and learn some basics. Also i would like to know why it's not working at the moment so i won't get stuck on it again in the future.

0 Kudos