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?
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.
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
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 ;
}
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
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
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
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
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.
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
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
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?
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
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
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.