UART problem with FRDMKL03 (with KDSK + PE + FreeRTOS)

取消
显示结果 
显示  仅  | 搜索替代 
您的意思是: 
已解决

UART problem with FRDMKL03 (with KDSK + PE + FreeRTOS)

跳至解决方案
2,936 次查看
vcanuel
Contributor II

Hi,

I am trying to setup an environment under KDS with the new FRDMKL03. For that, I use Processor Expert to setup everything.

My goal is simple : output the stout to uart (which runs fine with demos provided).

I have tried it in 2 ways.

1/ Use Hal UART directly

But It hungs up on LPUART_HAL_IsTxDataRegEmpty (always false).

Capture d’écran 2014-11-28 à 16.36.33.png

2 / Use fsl_debug_console.

But it does not solve my issue, and hangs up on Reserved 45_IRQHandler(). ( issue occurs even if I printf first or wait for task creation)

Capture d’écran 2014-11-28 à 13.04.06.png

Capture d’écran 2014-11-28 à 12.44.18.png.

How do I correct this ? Do i have to import a specific .c in my path to handle this or correct my setup in PE ?


Thanks in advance,

P.S : My project uses FreeRTOS and KSDK.

标签 (1)
标记 (5)
1 解答
1,797 次查看
mjbcswitzerland
Specialist V

Hi

I loaded your binary and could see that the code was spinning at the location that you reported (from the map file it is towards the end of the function writeToConsole()).

The problem is that the LPUART is not receiving a clock - your system is using the IRC8M (rather than IRC48M) and I suspect that the intension is that the LPUART is to be driven from the MCGIRCLK output, which is the same frequency as the IRC8M.

However the LPUART's clock source is selected in SIM_SOPT2 using the LPUART0SRC field. This is 0 by default and so disabled. I see that the register has been written to 0x03000000 - compare with the following table:

pastedImage_9.png

As is seen the clock source to the TPM (Timer PWM Module) has been selected to use MCGIRCLK (b11) but the LPUART0 is still at b00 - disabled).

I manually changed this to 0x0c000000 with the debugger and then the LPUART send the data out and no longer hung in the routine.

Therefore my conclusion is that you either selected the TPM by mistake or else the code generator made an error in selecting the clock source - rather than selecting it from the LPUART it selected it for the TPM module.

If the second is true it shows how any bugs in such code generating tools can become serious in terms of time loss due to the fact that using them automatically reduces the amount of knowledge available as to what is actually being done; the resulting difficultly to debug and correct is much greater for people who rely on such tools and don't have the understanding/experience to quickly solve them.

Regards

Mark

P.S: Your output is 7 bits in length at 115kBaud and looks like this:

pastedImage_0.png

在原帖中查看解决方案

0 项奖励
回复
7 回复数
1,797 次查看
mjbcswitzerland
Specialist V

Hi

The KL03 has 2k of SRAM. Are you sure that you can use FreeRTOS with this amount of memory?

Check stack and heap settings carefully because if anything runs out of memory probably crazy things will happen.

The KL03 doesn't support the interrupt vector 45 so I suppose your code must be landing there after using an uninitialised pointer or such that happens to result in a jump to that location.

Regards

Mark

0 项奖励
回复
1,797 次查看
vcanuel
Contributor II

Hello Mark,

Thanks for answering me.

Yes FreeRTOS adds some overhead but I could lower ram size to 1Ko (thanks to this tutorial by Erich Styger ).

Anyway, I have switch to a "bare metal" implementation of RTOS but still no luck.  It hungs up on LPUART_HAL_IsTxDataRegEmpty...

I have export the project (c.f attached).

Any ideas ?

0 项奖励
回复
1,797 次查看
mjbcswitzerland
Specialist V

Hi

I would have liked to quickly run the code but there are many paths that can't be found (like C:/Freescale/KSDK_1.0.0-KL03Z which may be a special version just for the KL03?).

The generated code is not easy to follow since it is spread out in many files (some of these are also missing) so I didn't invest too much time trying to work out what it was doing.

If you post a binary that can be loaded to the HW it is usually easier to see problems by looking at some registers than trying to follow code sequences.

What I do see is that the LPUART is using a simple blocking polled transmission and it it is not getting past spinning on an empty flag. It is probably that the Tx hasn't been enabled or possibly the LPUART clock hasn't been set to one that is enabled, etc.

As reference I can show you the KL03 LPUART Tx code in the uTasker project so that you can check the initialisation steps to see whether something is missing in yours. This assumes that the UART is run from the IRC48M clock (MCGPCLK) 8 bit mode, 1 stop, no parity 19200 Baud. I have added the register values for comparison. It doesn't show the interrupt configuration and operation for simplicty. As you can see there is in fact very little code required for initialisation and transmission.

POWER_UP(5, SIM_SCGC5_LPUART0); // power up the LPUART [sets bit 0x00100000 in SIM_SCGC5]

SIM_SOPT2 |= (SIM_SOPT2_UART0SRC_IRC48M); // select the 48MHz IRC48MHz clock as source for the LPUART [0x04000000]

#define SPECIAL_UART_CLOCK (48000000)

LPUART0_BAUD = (((((SPECIAL_UART_CLOCK/16/19200) + 1) * 2)/2) | LPUART_BAUD_OSR_16);  // set 19200 (x16 oversampling) [0x0f00009d]

LPUART0_CTRL = LPUART_CTRL_M; // 8 bit mode, one stop bit without parity [0x00000010]

_CONFIG_PERIPHERAL(B, 2, PB_2_UART0_RX); // UART0_RX on PB2 (alt. function 2) [PORT_PCR2 = 0x00000200]

LPUART0_CTRL |= (LPUART_CTRL_RIE | LPUART_CTRL_RE); // enable receiver and reception interrupt [0x00240010]

_CONFIG_PERIPHERAL(B, 1, PB_1_UART0_TX); // LPUART0_TX on PB1 (alt. function 2) [PORT_PCR1 = 0x00000200]

LPUART0_CTRL |= LPUART_CTRL_TE; // transmitter is enabled but not the transmission interrupt [0x002c0010]

// To send a byte of data (ucTxByte)

//

while ((LPUART0_STAT & LPUART_STAT_TDRE) == 0) { // wait for any transmit activity to complete

}

LPUART0_DATA = ucTxByte; // send byte

// Repeat for multiple bytes

//

//

Beware that the LPUART0_RX pin on the FRDM-KL03Z has a big 100nF capacitor connected to it (due to the fact that the pin can be used as VREF_OUT and then needs decoupling) which limits its Baud rate - 19200 Baud is OK bit higher becomes unreliable due to the fact that the input from the OpenSDA UART is just a triangular signal.

For completeness I have attached a binary which runs on the FRDM-KL03Z and has a simple menu on the LPUART interface (19200Baud). You can also use a debugger to check the register settings that it uses if required.

Regards

Mark

µTasker Kinetis support

0 项奖励
回复
1,796 次查看
vcanuel
Contributor II

Thanks Mark your help is much appreciated :smileyhappy:

I hope to have UART support out of the box (I mean with fsl_uart + Process Expert). The strange thing is that uart works with demos provide by freescale (with fsl_lpuart as well - but my configuration differs from them for sure).

I will check the clock setting and the registers. Otherwise I will go with the "bare metal way" as it seems relatively light.

Please find the generated binary file, in the case you get some an insight on this.

0 项奖励
回复
1,798 次查看
mjbcswitzerland
Specialist V

Hi

I loaded your binary and could see that the code was spinning at the location that you reported (from the map file it is towards the end of the function writeToConsole()).

The problem is that the LPUART is not receiving a clock - your system is using the IRC8M (rather than IRC48M) and I suspect that the intension is that the LPUART is to be driven from the MCGIRCLK output, which is the same frequency as the IRC8M.

However the LPUART's clock source is selected in SIM_SOPT2 using the LPUART0SRC field. This is 0 by default and so disabled. I see that the register has been written to 0x03000000 - compare with the following table:

pastedImage_9.png

As is seen the clock source to the TPM (Timer PWM Module) has been selected to use MCGIRCLK (b11) but the LPUART0 is still at b00 - disabled).

I manually changed this to 0x0c000000 with the debugger and then the LPUART send the data out and no longer hung in the routine.

Therefore my conclusion is that you either selected the TPM by mistake or else the code generator made an error in selecting the clock source - rather than selecting it from the LPUART it selected it for the TPM module.

If the second is true it shows how any bugs in such code generating tools can become serious in terms of time loss due to the fact that using them automatically reduces the amount of knowledge available as to what is actually being done; the resulting difficultly to debug and correct is much greater for people who rely on such tools and don't have the understanding/experience to quickly solve them.

Regards

Mark

P.S: Your output is 7 bits in length at 115kBaud and looks like this:

pastedImage_0.png

0 项奖励
回复
1,796 次查看
vcanuel
Contributor II

You were totally right, thanks again :smileyhappy:

For the explanation:

Code_mux is responsible for generating the proper hardware_init(). Unfortunately it does not call CLOCK_SYS_SetSource(kClockUart0Src, x) which set LPUART0SRC. ( It just jumped out at me when I compare to the hardware_init in demos now).

So i presume it's a bug in the module generation - do you know where can i report this bug?

I couldn't agree more with you about the code generation and the lack of understanding behind it ( =magic). I learned the hard way :smileyhappy:

In that case, It was a choice for quick bootstrapping and concentrate on added value feature for my current project. To be transparent, this choice was influenced by the amazing blog of Erich Styger (mcuoneclipse.com) whom seems to recommend this approach.

P.S : Do you officially support KL03 in µTasker ?

0 项奖励
回复
1,796 次查看
mjbcswitzerland
Specialist V

Hi

The KL03 is a new additional to the uTasker project which will be included in the next V1.4.8 release for the Kinetis (along with a number of other new ones, as well as many new general features).

>>Do you officially support KL03 in µTasker

Pre-release versions are available to interested users and support for new devices and features is available to early-adopters.

I have attached the uTasker project V1.4.8 build for the FRDM-KL03Z as binary. This can be easily loaded using drag-and-drop onto the hard disk that shows up when the board is connected via USB. Its UART is set to 19200 Baud, due to the large capacitor on the LPUART0_RX line, so that the command line menu can be used without having to remove it. There are various menus that allow various things to be done with it - the acceleropmeter is being samples too (enable output in the I2C menu).

Below is a screen shot showing the board running in the uTasker simulator (which enables fastest development capabilities).

Regards

Mark

pastedImage_0.png

0 项奖励
回复