S12Z Output Compare Module Unexpected Behaviour

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

S12Z Output Compare Module Unexpected Behaviour

Jump to solution
1,503 Views
kaslewis
Contributor III


I have been working with the S12ZV trying to get the OC to change the state on the output pin when the next interrupt occurs. The issue I have been facing is that instead of the next event causing the effect on the output pin the change happens IMMEDIATELY. I have included my TEST below.

 

void output_compare_software_controled(int number_of_pulses, int low_duration, int high_duration){   long i = 0;   int j = 0;     TIM0TSCR1 |= 0x80; //Enable OC module    TIM0TIE = 0x00;   TIM0TTOV = 0x00;   TIM0TFLG1 = 0xFF;   TIM0TFLG2 = 0xFF;    TIM0TIOS = 0x02; //Set channel 1 as OC   TIM0TCTL2 = 0x0C; //Set pin output on next OC event   TIM0OCPD &= ~0x02; //Enable the timer channel port for desired action   TIM0CFORC = 0x02; //Force OC action on specified channel     for(j = 0; j < number_of_pulses; j++){     for(i = 0; i < high_duration; i++){       //Wait      }     PTS_PTS1 = 0;//***********     PTS_PTS2 = 0;//***********     TIM0TCTL2 = 0x08; //Clear pin output on next OC event     TIM0OCPD = 0x00; //Enable the timer channel port for desired action     TIM0CFORC = 0x02; //Force OC action on specified channel      PTP_PTP7 = 0;     for(i = 0; i < low_duration; i++){       //Wait      }     PTS_PTS1 = 1;//***********     PTS_PTS2 = 1;//***********     TIM0TCTL2 = 0x0C; //Set pin output on next OC event     TIM0OCPD = 0x00; //Enable the timer channel port for desired action     TIM0CFORC = 0x02; //Force OC action on specified channel    } }    }

 

I understand that this is NOT interrupt driven but the behaviour is the same. When the code reaches line 14, 24 or 33 the state of the pin changes immediately. What should happen is that the state should only change when the code reaches line 16, 26 or 35 when the force register is set indicating that the change should happen.

 

I have similar code running that initializes the code in a function and sets the compare register to a set value but again the change happens when reaching TCTL2 and not when the next interrupt occurs. Any help in resolving this issue would be very much appreciated.

 

Thanks

Kas

Labels (1)
Tags (2)
0 Kudos
Reply
1 Solution
1,190 Views
RadekS
NXP Employee
NXP Employee

Hi Kas,

In fact, the PT1 is set to high at line 26.

The first widest low pulse refers to TIM0TC1, TIM0TSCR1, TIM0TIE, TIM0TTOV, TIM0TFLG1 and TIM0TFLG2 registers settings.

The second low pulse refers to TIM0TCTL2 = 0x0C; command.

The third low pulse refers to TIM0CFORC = 0x02;.

After that, there is the wide high pulse which refers to for loop.

The fourth low pulse refers to TIM0TCTL2 = 0x04; command.

The fifth low pulse refers to TIM0CFORC = 0x02;.

I am really sorry. I made a mistake and I copy here code with additional change. I just tested my period calculation and I forget to change the code back.

Please look at line 32. The command “TIM0TCTL2 = 0x04;” configured TIM channel 1 to toggling mode – but I didn’t change the comment.

So, timer toggle with PT1 during every positive comparing TIM0TCNT counter value with TIM0TC1 register = every 65535 bus clock cycles.

You used command TIM0TCTL2 = 0x08; in your original code for to “Clear pin output on next OC event”.

Attached are three simple S12Z TIM example codes for your reference.

I hope it helps you.

Have a great day,
Radek

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

View solution in original post

4 Replies
1,190 Views
RadekS
NXP Employee
NXP Employee

Hi Kas,

I am afraid that something missing there or that is a just misunderstanding.

I tested it on my TRK-S12ZVL board and everything works fine on my side.

I used a slightly simplified code with PS1 GPIO pin toggling for my reference.

My code:

void main(void) {

    unsigned int i;

    DDRS=0x02;

    PTS_PTS1 = 0;//***********

    TIM0TC1=0xFFFE;

    TIM0TSCR1 |= 0x80; //Enable OC module

    TIM0TIE = 0x00;

    TIM0TTOV = 0x00;

    TIM0TFLG1 = 0xFF;

    TIM0TFLG2 = 0xFF;

    PTS_PTS1 = 1;//***********

    TIM0TIOS = 0x02; //Set channel 1 as OC

    PTS_PTS1 = 0;//***********

    TIM0TCTL2 = 0x0C; //Set pin output on next OC event

    PTS_PTS1 = 1;//***********

    TIM0OCPD &= ~0x02; //Enable the timer channel port for desired action

    PTS_PTS1 = 0;//***********

    TIM0CFORC = 0x02; //Force OC action on specified channel

    PTS_PTS1 = 1;//***********

    for(i = 0; i < 3; i++){

        asm NOP;  //Wait  - just for waveform alignment

        }

    PTS_PTS1 = 0;//***********

    TIM0TCTL2 = 0x04; //Clear pin output on next OC event

    PTS_PTS1 = 1;//***********

    TIM0OCPD = 0x00; //Enable the timer channel port for desired action

    PTS_PTS1 = 0;//***********

    TIM0CFORC = 0x02; //Force OC action on specified channel

    PTS_PTS1 = 1;//***********

  for(;;) {

  } /* loop forever */

  /* please make sure that you never leave main */

}

Result waveform:

SNC01143-1.jpg

Could you please specify your MCU derivative?

What is your TIM0TC1 value?

How did you detect that “the output pin change happens IMMEDIATELY”?

I suppose that you just debugging code step by step. Please be aware that TCNT is free running counter and it is not stopped during debugging. So, when you set TIM0TCTL2, the next OC event may happen very early – depends on TIM0TC1, TIM0TCNT and prescaler values. In my case after approximately 10ms (6.25MHz, prescaler=1 => OC event every 0.0104856 second).

I hope it helps you.

Have a great day,
Radek

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

1,190 Views
kaslewis
Contributor III

Hello Radek,

I have tried running your code and I have the same issue. I understand that you say the counter does not stop running while in debug mode but the event should still not fire. All the interrupts have been disabled, therefore there should be no overflow event, no compare interrupt or any other interrupt. I therefore do not understand why when I reach the line 22 the pin is set high.

#include <hidef.h> /* for EnableInterrupts macro */

#include "derivative.h" /* include peripheral declarations */

void main(void) { 

    unsigned int i; 

    DDRS=0x02; 

    PTS_PTS1 = 0;//*********** 

 

    TIM0TC1=0xFFFE;  

 

    TIM0TSCR1 |= 0x80; //Enable OC module 

 

    TIM0TIE = 0x00; 

    TIM0TTOV = 0x00; 

    TIM0TFLG1 = 0xFF; 

    TIM0TFLG2 = 0xFF; 

 

    PTS_PTS1 = 1;//*********** 

    TIM0TIOS = 0x02; //Set channel 1 as OC 

    PTS_PTS1 = 0;//*********** 

    TIM0TCTL2 = 0x0C; //Set pin output on next OC event 

    PTS_PTS1 = 1;//*********** 

    TIM0OCPD &= ~0x02; //Enable the timer channel port for desired action 

    PTS_PTS1 = 0;//*********** 

    TIM0CFORC = 0x02; //Force OC action on specified channel 

    PTS_PTS1 = 1;//*********** 

    for(i = 0; i < 3; i++){ 

        asm NOP;  //Wait  - just for waveform alignment 

        } 

    PTS_PTS1 = 0;//*********** 

    TIM0TCTL2 = 0x04; //Clear pin output on next OC event 

    PTS_PTS1 = 1;//*********** 

    TIM0OCPD = 0x00; //Enable the timer channel port for desired action 

    PTS_PTS1 = 0;//*********** 

    TIM0CFORC = 0x02; //Force OC action on specified channel 

    PTS_PTS1 = 1;//*********** 

 

  for(;;) { 

  } /* loop forever */ 

  /* please make sure that you never leave main */ 

I have run the code with no stepping but rather using the scope as you suggest and I get

TEK00000.PNG

Whoich is the same as yours and makes sence, however when I let the program run, that is I let it carry on into the infinite for loop I get

TEK00003.PNG TEK00004.PNG

which considering there are no interrupts, and no request to toggle the pin should not be happening. If you could therefore please explain why I am getting this toggling when there is no code telling the pin to do so and why when I do single stepping I get the change at line 22 when again no event has occurred. I understand that the counter keeps on running but that alone should not be a reason for the pin to change state since there has been no event to cause this change to occur (no interrupt since they are all disabled and no FORC as that line on the code has not yet been reached).

Thankfully

Kas

0 Kudos
Reply
1,191 Views
RadekS
NXP Employee
NXP Employee

Hi Kas,

In fact, the PT1 is set to high at line 26.

The first widest low pulse refers to TIM0TC1, TIM0TSCR1, TIM0TIE, TIM0TTOV, TIM0TFLG1 and TIM0TFLG2 registers settings.

The second low pulse refers to TIM0TCTL2 = 0x0C; command.

The third low pulse refers to TIM0CFORC = 0x02;.

After that, there is the wide high pulse which refers to for loop.

The fourth low pulse refers to TIM0TCTL2 = 0x04; command.

The fifth low pulse refers to TIM0CFORC = 0x02;.

I am really sorry. I made a mistake and I copy here code with additional change. I just tested my period calculation and I forget to change the code back.

Please look at line 32. The command “TIM0TCTL2 = 0x04;” configured TIM channel 1 to toggling mode – but I didn’t change the comment.

So, timer toggle with PT1 during every positive comparing TIM0TCNT counter value with TIM0TC1 register = every 65535 bus clock cycles.

You used command TIM0TCTL2 = 0x08; in your original code for to “Clear pin output on next OC event”.

Attached are three simple S12Z TIM example codes for your reference.

I hope it helps you.

Have a great day,
Radek

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

1,190 Views
kaslewis
Contributor III

Hello Radek,

After going over the code again I know understand the confusion. I did not realize that TIM0CTL2 = 0x04; (that it should toggle) and therefore on every compare match with the timer the pin would continue to toggle. I was looking to have it set to 0x08 or 0x0C.

I also now understand that the timer does not stop during debug mode which added a bit of confusion during debugging. Thank you for your help.

Sincerely

Kas

0 Kudos
Reply