Using PWM mode in KL25z as timer

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

Using PWM mode in KL25z as timer

Jump to solution
4,031 Views
subhradeepdutta
Contributor II

I am trying to use the PWM mode as a timer to measure the execution time of a certain code block. Can someone guide me on the steps to get that working. Or point me to some resources that might be handy. I have already reviewed the manuals and data sheet. I am using the Kinetis Design Studio 3.

Tags (2)
1 Solution
2,809 Views
kerryzhou
NXP TechSupport
NXP TechSupport

Hi Subhradeep,

   Actually it is the same, you just need to refer the configuration code.

1. You should know your TPM source clock.

pastedImage_1.png

  From this picture, you can get that the TPM have four source clock: MCGIRCLK, OSCERCLK, MCGFLLCLK, MCGPLLCLK.

   Because I use the OSCERCLK 8Mhz, then the code is:

  SIM_SOPT2 = (uint32_t)((SIM_SOPT2 & (uint32_t)~(uint32_t)(
               SIM_SOPT2_TPMSRC(0x01)
              )) | (uint32_t)(
               SIM_SOPT2_TPMSRC(0x02)
              ));          

 

2.  Configure the TPM module

The TPM input clock is 8Mhz, because you want to get the 10us, then I divide the TPM clock with 8, and get 1Mhz, it is 1us.

Now, if you want to get 10us cycle, you just need to set MOD=9, then you will get (1+9)*1us=10us cycle.

The bare bone TPM code can be initialized like this:

void TPM0_Init(void)
{
  /* SIM_SCGC6: TPM0=1 */
  SIM_SCGC6 |= SIM_SCGC6_TPM0_MASK;  // enable the TPM module

  TPM0_C0SC = (TPM_CnSC_MSB_MASK | TPM_CnSC_ELSB_MASK);  // choose the channel 0 mode as edge-aligned PWM mode
  TPM0_C0V = TPM_CnV_VAL(0x05);  // choose channel 0 value = 5, dufy is 5us
  /* TPM0_MOD: MOD=9 */
  TPM0_MOD = (uint32_t)((TPM0_MOD & (uint32_t)~(uint32_t)(
              TPM_MOD_MOD(0xFFF6)
             )) | (uint32_t)(
              TPM_MOD_MOD(0x09)    
             ));  // TPM MOD =9 ,it means the TPM cycle is 10us
  /* TPM0_SC: DMA=0,TOF=1,TOIE=1,CPWMS=0,CMOD=1,PS=3 */
  TPM0_SC = (uint32_t)((TPM0_SC & (uint32_t)~(uint32_t)(
             TPM_SC_DMA_MASK |
             TPM_SC_CPWMS_MASK |
             TPM_SC_CMOD(0x02) |
             TPM_SC_PS(0x04)
            )) | (uint32_t)(
             TPM_SC_TOF_MASK |
             TPM_SC_TOIE_MASK |
             TPM_SC_CMOD(0x01) |
             TPM_SC_PS(0x03)
            ));
}

The test result is the same as PE.

You can try it on your side, but at first, you should make sure your project have 8Mhz OSC at first, you can use the FRDM-KL25 board to test it.

Wish it helps you!


Have a great day,
Kerry

-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------

View solution in original post

6 Replies
2,809 Views
kerryzhou
NXP TechSupport
NXP TechSupport

Hi Subhradeep,

   If you want to measure the execution time of a certain code block, I highly suggest you use the systick instead of the PWM.

   About the systick method, you can refer to our FRDM-KL25 sample code which can be downloaded from this link:

http://cache.nxp.com/files/32bit/software/KL25_SC.exe?fpsp=1&WT_TYPE=Lab%20and%20Test%20Software&WT_... 

Folder:kl25_sc_rev10\klxx-sc-baremetal\build\iar\LQRUG_bme_ex1

The following code is measure the GPIOA_PDOR ^= 0x20; execution time:

    systick_init();    
    logic_op_demo_with_normalc();
    systick_disable();

void systick_init(void)
{
    SYST_CVR = 0x0;    //clear current timer value
    SYST_RVR = 0x00FFFFFF;
    SYST_CSR = SysTick_CSR_CLKSOURCE_MASK | SysTick_CSR_ENABLE_MASK;   
}

void systick_disable(void)
{
    SYST_CSR &= ~SysTick_CSR_ENABLE_MASK;
}

void logic_op_demo_with_normalc(void)
{
    uint32_t cnt_start_value;
    uint32_t cnt_end_value;
    
    uint32_t execution_cycle;    //actual execution cycle
 
    //configure PTA5 as GPIO
    PORTA_PCR5 = PORT_PCR_MUX(1);
 
    //configure PTA5 as output pin
    GPIOA_PDDR |= 0x20;
 
    cnt_start_value = SYST_CVR;
 
    GPIOA_PDOR ^= 0x20;
 
    cnt_end_value = SYST_CVR;
    
    execution_cycle = cnt_start_value - cnt_end_value - overhead;
    
#ifdef DEBUG_PRINT
    printf("systick start value: 0x%x\n\r", cnt_start_value);
    printf("systick end value: 0x%x\n\r", cnt_end_value);
    printf("actual execution cycle for logic operation with normal C code: 0x%x\n\r", execution_cycle);
#endif        
}

You should better use the systick to measure the code execution time, it is simple,easy and accurate.

Wish it helps you!

If you still have question, please let me know!


Have a great day,
Kerry

-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------

2,809 Views
subhradeepdutta
Contributor II

Hi Kerry

Thank you for your response. I understand that it can be done using the systick but the requirement is to use a 10us period edge aligned PWM to calculate the time duration. I am aware of what the registers need to be loaded with, I am just looking for a step by step guide, i.e. some kind of algorithm to generate the PWM and then use it to measure code execution time.

0 Kudos
2,809 Views
kerryzhou
NXP TechSupport
NXP TechSupport

Hi Subhradeep,

    If you just want to get 10us period PWM, you can refer to the KLQRUG.pdf document:

http://cache.nxp.com/files/32bit/doc/quick_ref_guide/KLQRUG.pdf 

Chapter 12, you can find the TPM configuration step by step.

Besides, I also help you create a TPM KDS project, and test it on my FRDM-KL25 board, it can output 10us period edge aligned PWM in PTD0.

For the detail configuration, please  check my attached KDS project.

This is the test result:

pastedImage_2.png

Wish it helps you!

If you still have question, please let me know!


Have a great day,
Kerry

-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------

2,809 Views
subhradeepdutta
Contributor II

I forgot to mention that I need to do it without processor expert code. 

I have some initial config here but it doesnt seem to work correctly 

#include "MKL25Z4.h"

void main()
{
SIM_SOPT2 |= 0x01000000; //Select MCGFLLCLK as source for TPM
SIM_SOPT2 &= ~SIM_SOPT2_PLLFLLSEL_MASK;//Clear PLLFLLSEL to select MCGFLLCLK
SIM_SCGC5 |= 0x00003E00; //Enable Clock to Port A, B, C, D, E
SIM_SCGC6 |= 0x01000000; //Enable Clock Gating for TPM0

PORTC_PCR2 = PORT_PCR_ISF_MASK |PORT_PCR_MUX(0x4)| PORT_PCR_DSE_MASK;//Enable PTC2
PORTC_PCR3 = PORT_PCR_ISF_MASK |PORT_PCR_MUX(0x4)| PORT_PCR_DSE_MASK;//Enable PTC3 as channel outputs of TPM0
PORTB_BASE_PTR->PCR[18]=PORT_PCR_MUX(3);

TPM0_SC &= 0xFFFFFFE7;//Disable clock mode CMOD
TPM0_CNT &= 0xFFFF0000;//Initialize counter
TPM0_SC |= 0x00000080; //Clear overflow flag
TPM0_SC &= 0xFFFFFFDF; //Select up counting mode
TPM0_SC &= 0xFFFFFFF9; //Prescaler selection set to divide by 2
TPM0_MOD |= 0x0000000C;//Assuming 24 MHz clock to TPM to get 1us resolution
TPM0_SC |= 0x00000008;//Enable clock mode CMOD

TPM0_C0SC = TPM_CnSC_MSB_MASK| TPM_CnSC_ELSB_MASK;//Channel 0 is set to edge aligned and high true pulses
//TPM0_C0V = 0x00;//Initialize channel value

PTB_BASE_PTR->PDDR=1 << 18;
for(;;)
{
if(TPM0_SC & 0x00000008 == 0x00000008)
{
TPM0_SC |= 0x00000080; //Clear overflow flag
//TPM0_C0V = 0x00;//Not sure about this part
PTB_BASE_PTR->PDDR=0 << 18;
}

}
}

0 Kudos
2,810 Views
kerryzhou
NXP TechSupport
NXP TechSupport

Hi Subhradeep,

   Actually it is the same, you just need to refer the configuration code.

1. You should know your TPM source clock.

pastedImage_1.png

  From this picture, you can get that the TPM have four source clock: MCGIRCLK, OSCERCLK, MCGFLLCLK, MCGPLLCLK.

   Because I use the OSCERCLK 8Mhz, then the code is:

  SIM_SOPT2 = (uint32_t)((SIM_SOPT2 & (uint32_t)~(uint32_t)(
               SIM_SOPT2_TPMSRC(0x01)
              )) | (uint32_t)(
               SIM_SOPT2_TPMSRC(0x02)
              ));          

 

2.  Configure the TPM module

The TPM input clock is 8Mhz, because you want to get the 10us, then I divide the TPM clock with 8, and get 1Mhz, it is 1us.

Now, if you want to get 10us cycle, you just need to set MOD=9, then you will get (1+9)*1us=10us cycle.

The bare bone TPM code can be initialized like this:

void TPM0_Init(void)
{
  /* SIM_SCGC6: TPM0=1 */
  SIM_SCGC6 |= SIM_SCGC6_TPM0_MASK;  // enable the TPM module

  TPM0_C0SC = (TPM_CnSC_MSB_MASK | TPM_CnSC_ELSB_MASK);  // choose the channel 0 mode as edge-aligned PWM mode
  TPM0_C0V = TPM_CnV_VAL(0x05);  // choose channel 0 value = 5, dufy is 5us
  /* TPM0_MOD: MOD=9 */
  TPM0_MOD = (uint32_t)((TPM0_MOD & (uint32_t)~(uint32_t)(
              TPM_MOD_MOD(0xFFF6)
             )) | (uint32_t)(
              TPM_MOD_MOD(0x09)    
             ));  // TPM MOD =9 ,it means the TPM cycle is 10us
  /* TPM0_SC: DMA=0,TOF=1,TOIE=1,CPWMS=0,CMOD=1,PS=3 */
  TPM0_SC = (uint32_t)((TPM0_SC & (uint32_t)~(uint32_t)(
             TPM_SC_DMA_MASK |
             TPM_SC_CPWMS_MASK |
             TPM_SC_CMOD(0x02) |
             TPM_SC_PS(0x04)
            )) | (uint32_t)(
             TPM_SC_TOF_MASK |
             TPM_SC_TOIE_MASK |
             TPM_SC_CMOD(0x01) |
             TPM_SC_PS(0x03)
            ));
}

The test result is the same as PE.

You can try it on your side, but at first, you should make sure your project have 8Mhz OSC at first, you can use the FRDM-KL25 board to test it.

Wish it helps you!


Have a great day,
Kerry

-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------

2,809 Views
subhradeepdutta
Contributor II

Thanks Kerry. just need to initialize the correct clock in the beginning.

0 Kudos