Why do I need a delay after PIT clock enable?

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

Why do I need a delay after PIT clock enable?

1,215 Views
charleszimnicki
Contributor II

I tried to write an application that uses PIT interrupt and I ran into trouble. I noticed that the timers do not advance. So I started to investigate what is wrong, printing register values. It turns out that if there is no delay after the line "SIM_SCGC6 |= SIM_SCGC6_PIT_MASK;" the PIT_MCR somehow ends up with the value 2 and the timer does not advance. This happens even when commenting a couple of the "__asm("nop"); " lines. However, with this 8-line delay everything works OK, with the PIT_MCR having value 0 and timer advancing normally.

My setup is the same as with "Writing my first KSDK Application in KDS - Hello World and Toggle LED with GPIO Interrupt", with exception that I work with FRDM-K22F, KDS 2.0.0, KSDK 1.1.0. I flash the firmware using PEMicro/OpenSDA. My plan is to investigate assembly code next but I thought that there is a good chance someone will provide an answer here.

#include "fsl_device_registers.h"

#include "board.h"

#include <stdio.h>

int main(void)

{

  hardware_init();

  dbg_uart_init();

  SIM_SCGC6 |= SIM_SCGC6_PIT_MASK;     // Enable the clock to the PIT module

  __asm("nop");     // I have no idea why I need this delay :-(

  __asm("nop");     // but without these lines timer does not advance.

  __asm("nop");     // I had a printf here before and everything started to work

  __asm("nop");     // so I put these lines to investigate how long of a delay is needed.

  __asm("nop");

  __asm("nop");

  __asm("nop");

  __asm("nop");

  PIT_MCR = 0x00; //Enable PIT module

  PIT_LDVAL1 = 8000000; //PIT Load value

  PIT_TCTRL1 |= PIT_TCTRL_TEN_MASK; // start Timer 1

  printf("Register   address  value\n\r");

  printf("SIM_SCGC6  %08x %08X\n\r",&SIM_SCGC6, SIM_SCGC6);

  printf("PIT_MCR    %08x %08X\n\r",&PIT_MCR, PIT_MCR);

  printf("PIT_LDVAL1 %08x %08X\n\r",&PIT_LDVAL1, PIT_LDVAL1);

  printf("PIT_TCTRL1 %08x %08X\n\r",&PIT_TCTRL1, PIT_TCTRL1);

  printf("PIT_CVAL1  %08x %08X\n\r",&PIT_CVAL1, PIT_CVAL1);

  while(1);

  return 0;

}

Tags (3)
0 Kudos
1 Reply

469 Views
mjbcswitzerland
Specialist V

Hi Charles

See Errata to the mask 0M50M (valid for the K22)

pastedImage_0.png

Code from uTasker framework:

    POWER_UP(6, SIM_SCGC6_PIT);   // ensure the PIT module is powered up

    #if defined ERRATA_ID_7914

    (void)PIT_MCR;                // dummy read of PIT_MCR to guaranty a minimum delay of two bus cycles after enabling the clock gate and not losing next write

    #endif

    PIT_MCR = 0;                  // ensure the PIT module is clocked

Regards

Mark

Kinetis: µTasker Kinetis support

K22: µTasker Kinetis FRDM-K22F support / µTasker Kinetis TWR-K22F120M support

Kinetis Hardware Timers and PWM - http://www.utasker.com/docs/uTasker/uTaskerHWTimers.PDF

For the complete "out-of-the-box" Kinetis experience and faster time to market

0 Kudos