How can I configure and use one kinetis K20 hardware timer in MQX 4.0.2

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

How can I configure and use one kinetis K20 hardware timer in MQX 4.0.2

1,335 Views
VictorLorenzo
Contributor IV

Hi,

I've created the BSP for one custom board based on the kinetis K20DN512VLK10, as base for the cloning wizard I used the tower K40 BSP that comes in the installation.

Now I need to use one hardware timer for internal timings in my application but I can't find the right way to do it.

First try was to add one TimerUnit_LDD device in the BSP PE editor but, when including the required files (I named the component ResponseTimer and it's associated header is "ResponseTimer.h") in the application the compiler showed this error:

In file included from C:/Freescale/Freescale_MQX_4_0/lib/MyBSP.cw10gcc/debug/bsp/Generated_Code/ResponseTimer.h:78:0,

                 from ../Sources/HAL/_timing.c:15:

C:/Freescale/Freescale_MQX_4_0/lib/MyBSP.cw10gcc/debug/bsp/Generated_Code/PE_Types.h:56:33: error: two or more data types in declaration specifiers

mingw32-make: *** [Sources/HAL/_timing.o] Error 1

mingw32-make: *** Waiting for unfinished jobs....

The corresponding lines in the PE_Types.h file are:

/* PE types definition */

#ifndef __cplusplus

typedef unsigned char           bool; /*<- this is the 56th line.*/

#endif

Second try was to add two new source files in the BSP project (legacy.h and legacy.c, in this case) and add there the code for accessing the timer device. It compiled without any issue but when debugging the code the application crashed on calls to function ResponseTimer_ResetCounter().

From results in the first attempt it seems that this is not the method for gaining acess to hardware. How should I do it?

My needs are simple, I want to use one hardware timer for making very precise sub-millisecond delays (one detecting one specific event I should reset the timer and keep reading the timer's count register until it reaches some precalculated value). The functionalities involved are: Up Counting, Make Counter Reset, Get Value of Input Frequency and Get Current Counter Value.

Regards, Victor

(and thanks a lot in advance)

0 Kudos
2 Replies

466 Views
DavidS
NXP Employee
NXP Employee

Hi Victor,

Right idea for porting but wrong start.  You should start with the TWR-K60D100M.

Then with your new BSP, use processor expert to add a CPU component for the MK20DN512VLK10 (make sure to have correct pinout too).

Using PE to configure your clock settings and beware that the flash configuration is enabled by default.  Simplest to just disable it.

Note that the BSP has two components enabled: PWM and GPIO.  I also disable those components and then generate code, compile RTOS.

Note once you are using PE both the BSP and MQX application project Directories (for Assembler and C Compiler) properties needs to add paths for the "Generated Code" and "Source" folders.

"${MQX_ROOT_DIR}/mqx/build/cw10gcc/bsp_k20dn512zvlk10/Generated_Code"

"${MQX_ROOT_DIR}/mqx/build/cw10gcc/bsp_k20dn512zvlk10/Source"

Regards,

David


466 Views
VictorLorenzo
Contributor IV

Hi David,

I started with the TWRK40D100 as recommended by Mr Martin Latal in response to this question here: https://community.freescale.com/thread/307573. The major difference between the K40 derivative in the TWR and the K20 we use is the K40 incorporates one LCD controller. I simply removed the sources (links in the project) and all references in the rest of the source files (initialization, configuration, etc).

Another major difference I found later was the flash configuration, the K40 has flash and flex memories, the K20 has only flash, and larger in size.

I posted this question here (https://community.freescale.com/thread/312312) with several questions, one of them is about how to solve this memory missmatch.

After testing several methods using the MQX hwtimer drivers I came up with a working solution for this timing/timer usage scenario but it was too late and I did not post it here. I ended up using one PIT and modifying the PIT hwtimer driver for adding one new function. The method I used was very simple:

  1. Configure the timer with a very low frequency so the tick interrupts occur long after all the process has completed (after the trigger event, at most 10ms lapse until the last timed operation is completed),
  2. Start the timer when the event is fired.
  3. Precalculate the thresshold for the PIT counter,
  4. Keep reading the PIT downcounter until the thresshold value is passed and end the wait.

Major problem I found with this approach was the massive overhead imposed by the driver design, the best resolution I was able to achieve with the mqx hwtimer driver functions was worst than 2.5us (with the CPU running at 96MHz), and I needed it be equal or better than 1/2us. At the end I added this function in the hwtimer_pit.c file (see below) that partly solved the timing problem:

void hwtimer_pit_wait_count(HWTIMER_PTR hwtimer, uint_32 Count ) {

    PIT_MemMapPtr pit_base  = (PIT_MemMapPtr) hwtimer->ll_context[0];

    uint_32 pit_channel    = GET_PIT_CHANNEL_FROM_PITID(hwtimer->ll_context[1]);

    Count = PIT_LDVAL_REG(pit_base, pit_channel) - Count;

  

    while (Count < PIT_CVAL_REG(pit_base, pit_channel))

    {}

}

Due to severely restricted timing constraints I can not use the classic RTOS Flag/Semafore/Mutex design pattern for this part of the application.

I will take a close look to the TWR-K60D100M, thanks for mentioning it.

Could you, please, take a look at the pending questions in the above mentioned forum posts?

Best regards,

Victor

0 Kudos