TimerInt, FreeCnt, etc. calling Disable() method disables entire TPM module.

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

TimerInt, FreeCnt, etc. calling Disable() method disables entire TPM module.

Jump to solution
3,321 Views
jgirard1
Contributor III

For HCS08...

 

Why do TimerInt, FreeCnt, etc. components disable the entire TPM counter module when calling the Disable() method?  This prevents other shared components on other channels from functioning correctly because the shared timer is stopped from clocking.

 

static void HWEnDi(void)
{
  if (EnUser) {
    TPM2SC |= 0x10;                    /* Run counter (set CLKSB:CLKSA) */
  } else {
    /* TPM2SC: CLKSB=0,CLKSA=0 */
    clrReg8Bits(TPM2SC, 0x18);         /* Stop counter (CLKSB:CLKSA = 00) */  <--This disables the clocking
    /* TPM2CNTH: BIT15=0,BIT14=0,BIT13=0,BIT12=0,BIT11=0,BIT10=0,BIT9=0,BIT8=0 */
    setReg8(TPM2CNTH, 0x00);           /* Clear counter register - any write clears complete counter */
  }
}

 

Since these components use the Output Compare to generate their interrupts, why not just disable the compare operation using ELSnB:ELSnA bits and keep the timer running for other shared components?

 

I tried changing the property: [Component uses entire timer = No] ...and this doesn't help.

 

I also tried always keeping the component enabled and then using the EnableEvent() method to control the action.  The problem with this is it still keeps the output compare interrupts running when the event is disabled.  The event call is just blocked when disabled.  This is very inefficient.  If the envent is disabled, then why not disable the output compare altogether if it is not required?

 

 

0 Kudos
1 Solution
2,530 Views
ProcessorExpert
Senior Contributor III

Hello,

 

please find the attached updated hot-fix.

 

Regarding: "Please let me know how I can join the development team.  I have many more ideas and I know how to develop new components using Component Wizard."

 

We appreciate your offer for cooperation, I have passed that to my manager.

 

best regards
Vojtech Filip
Processor Expert Support Team

View solution in original post

0 Kudos
34 Replies
1,569 Views
jgirard1
Contributor III

Hi.  I appreciated this hot fix that you made for the HS(C)08 series.  It worked well for me.  My question is, can this same hot fix be applied to the S12(X) series processors?  I have to port some of the same S08(C) code over to the the S12(X) and I am afraid that I will have the same issues as I had before with the timers sharing one single counter.  If one shared timer component was disabled, then the whole timer counter register was disabled and it would no longer work for the other enabled shared timer components.

Here is what you gave me...

CodeWarrior for Microcontrollers V6.3 Processor Expert V3.09 hotfix for issue IM8614
====================================================================================

Description
-----------

- Enable/DisableEvent methods were optimized. These methods toggle the interrupt directly now. (#8702)

Installation
------------

1. Ensure you have an aministrator rights and the CodeWarrior is not running.
2. Copy the content of this archive (without readme.txt file) into the CodeWarrior
   for MCUs V6.3 installation layout.

Do you know if I will run into the same problems using shared timers on the S12(X)?

0 Kudos
1,569 Views
vfilip
NXP Employee
NXP Employee

Hello,

from the code observation seems that in case you select ECT, TIM devices in TimerInt component you should be able use the component without any limitation.

Please let me know if I have overlooked something.

best regards

Vojtech Filip

Processor Expert Support Team


0 Kudos
1,569 Views
jgirard1
Contributor III

Hi.  I have begun to use the HCS12(X) for a program and I am now having the exact same issue for the FreeCnt as mentioned in this thread.  I tried to use the hotfix for HC(S)08 that gave, but the package is not compatible with CodeWarrior 5.1 for S12(X).

Is there a possibility that you can do this same hotfix for me that I can integrate into CW5.1 for HC12?

Thank you.

0 Kudos
1,569 Views
vfilip
NXP Employee
NXP Employee

Hello,

Ok. Could you please just post here a demonstration project of the issue?

thanks & best regards

Vojtech Filip

Processor Expert Support Team


0 Kudos
1,569 Views
jgirard1
Contributor III

This is for HC(S)08.  This is a sample of the code before your hotfix.  This FreeCnt bean is connected to a TPM in output compare mode.

These are the methods that enable/disable the event using a local variable.

#define DTE_Timeout_EnableEvent() (DTE_Timeout_EnEvent = TRUE, (byte)ERR_OK) /* Set the flag "events enabled" */

#define DTE_Timeout_DisableEvent() (DTE_Timeout_EnEvent = FALSE, (byte)ERR_OK) /* Set the flag "events disabled" */

Here is the interrupt function that tests the local variable to see if the event is enabled or not.

ISR(DTE_Timeout_Interrupt)

{

  /* TPM1C3SC: CH3F=0 */

  clrReg8Bits(TPM1C3SC, 0x80);         /* Reset compare interrupt request flag */

  if (DTE_Timeout_EnEvent) {          /* Is a event allowed? */

    DTE_Timeout_OnInterrupt();        /* Invoke user event */

  }

}

This is inefficient coding as the output compare is still interrupting all the time, even when the event is disabled.  My original proposal to disable the event was to clear the timer interrupt enable bit which also stops the output compare from interrupting. 

So now here is the HC(S)08 code after using your "hot_fix_8702_CW_6_3_PE_3_09_CLASSIC.zip".

These new methods enable/disable the event by using the interrupt enable bit.

#define DTE3_Timeout_EnableEvent() (TPM1C3SC_CH3IE = 0x01, (byte)ERR_OK) /* Enable interrupt */
#define DTE3_Timeout_DisableEvent() (TPM1C3SC_CH3IE = 0x00, (byte)ERR_OK) /* Disable interrupt */

The ISR is different and does not have to test any local variable if the event is disabled or not.

ISR(DTE_Timeout_Interrupt)

{

  /* TPM1C3SC: CH3F=0 */

  clrReg8Bits(TPM1C3SC, 0x80);         /* Reset compare interrupt request flag */

  DTE_Timeout_OnInterrupt();          /* Invoke user event */

}

The only issue with this approach is that you need to clear the output compare interrupt flag before re-enabling the interrupt enable bit when re-enabling the event.  This I mentioned in my previous post in this thread: 

"The other thing you also need to add to the logic is an interlock to check if the event is already enabled.  You can simply test the CHxIE bit.  If the CHxIE bit is set, then do not clear the interrupt status flag.  This is because the user code may always call the EnableEvent() method.  There should be no side effects from calling the EnableEvent() method more than twice in a row if it is already enabled.  You do not want to inadvertently clear the interrupt status flag before it can be serviced, especially when interrupts are disabled."

I know you made this improvement for me in another hot fix release, but I cannot find that version and I cannot seem to download it from this thread anymore.  You gave me two hot fixes, I believe.  I seemed to have lost the final version of this fix.

Anyway, my original question was can you do the same updates, but do it for the HCS12(X) for CW5.1 Classic?  If you have the original final version of this hot fix for HC(S)08, I could use that as well.  Thanks.

0 Kudos
1,569 Views
vfilip
NXP Employee
NXP Employee

Hello,

generally you cannot apply the original hot-fix for hcs08 to another family (and product). I would recommend to use the CW V10.3 instead of using classic CW with hot-fix. Anyway I have attached it again.

Regarding hot-fix for hcs12(x) - I would just need some demonstration project in order to reproduce the issue on HCS12(X) or at least details on timer device and MCU you use.

best regards

Vojtech Filip

Processor Expert Support Team


0 Kudos
1,568 Views
jgirard1
Contributor III

Hi.  Thank you again for all your efforts.  I know this may seem like a pain to deal with and I'm sorry if it is.

I am now working with a MC9S12XA256 application using Processor Expert with classic interface.  This is all I have the license for and cannot use the new Ecplise interface.

Here is the code that is generated for my FreeCntr bean:

volatile bool FSK_Out_IRQ_EnEvent;     /* Used for Enable/Disable events */

#define FSK_Out_IRQ_EnableEvent() ( FSK_Out_IRQ_EnEvent = TRUE,          /* Set the flag "events enabled" */ \
  ERR_OK                               /* Return result */ )
#define FSK_Out_IRQ_DisableEvent() ( FSK_Out_IRQ_EnEvent = FALSE,         /* Set the flag "events disabled" */ \
  ERR_OK                               /* Return result */ )

ISR(FSK_Out_IRQ_Interrupt)

{

  TFLG1 = 0x04U;                       /* Reset interrupt request flag */

  if (FSK_Out_IRQ_EnEvent) {           /* Are the events enabled? */

    FSK_Out_IRQ_OnInterrupt();         /* Invoke user event */

  }

}

It is the same code as HC(S)08 before applying your 8702 hot fix.  It is the same inefficient code that keeps the timer output compare interrupting unneccesarily.  It would be more efficient to just disable the timer interrupt as your hot fix does.  However, the hot fix you provided is incomplete as I've already mentioned in the previous posts with respect to re-enabling the event:

"The other thing you also need to add to the logic is an interlock to check if the event is already enabled.  You can simply test the CHxIE bit.  If the CHxIE bit is set, then do not clear the interrupt status flag.  This is because the user code may always call the EnableEvent() method.  There should be no side effects from calling the EnableEvent() method more than twice in a row if it is already enabled.  You do not want to inadvertently clear the interrupt status flag before it can be serviced, especially when CPU interrupts are temporarily disabled using SEI instruction."

Here is how your hot fix re-enables the event:

#define DTE3_Timeout_EnableEvent() (TPM1C3SC_CH3IE = 0x01, (byte)ERR_OK) /* Enable interrupt */

The enable event should look like this:

if (TPM1C3SC_CH3IE != 0x01)  /* Test if event is already enabled */

{

  clrReg8Bits(TPM1C3SC, 0x80);  /* Clear any previous compare interrupt request flag */

  TPM1C3SC_CH3IE = 0x01;  /* Now enable the event */

}

I would like to have this functionality as a hot fix in both the HC(S)08 and the S12(X) for my applications.  I thought for sure you added this additional 'enable event' functionality for me in a update to your original 8702 hot fix, but I cannot find it in my files.  Maybe you can go back and look for a secondary update after Jan 19, 2012?  The additional update, after we discussed it, and according to this thread, should be Feb 14, 2012.

Please let me know if you can do this for me and I would really appreciate it.  I am sorry if this is a pain for you.  If you do not understand the history, you can take time to re-read this entire thread as it has become pretty evolved.  Everything you need to know is in this thread as you already addressed this issue once for me for the HC(S)08 application.

0 Kudos
1,568 Views
vfilip
NXP Employee
NXP Employee

Hello,

please find the attached patch from Feb 14, 2012. Regarding HCS12(X,Z): I have passed your requested to developers.

Could you please also specify which version of CW for HCS12 do you use?

best regards

Vojtech Filip

Processor Expert Support Team






0 Kudos
1,568 Views
jgirard1
Contributor III

Hi.  Do you think you can have the same fix for S12(X) anytime soon?  My project is sort of waiting on it.

I am also having more limitations with other PE components as I have posted in Embedded Components forum.  I wish it was easier to make your own components that has acess to the PE databases.

0 Kudos
1,568 Views
jgirard1
Contributor III

Hi.  Any news on getting the S12(X) FreeCntr component updated to disable events by masking the interrupt enable bits?

0 Kudos
1,568 Views
vfilip
NXP Employee
NXP Employee

Hello,

please find the hot-fix in the attachment.

best regards

Vojtech Filip

Processor Expert Support Team


0 Kudos
1,568 Views
jgirard1
Contributor III

Hi.  Thank you for the update and fix.  Unfortunately it has a problem.  I see that the EnableEvent and DisableEvent now toggle the interrupt enable bit of the timer, however, the interrupt is still check for the old event enable flag "EnEvent".

ISR(FSK_Out_IRQ_Interrupt)

{

  TFLG1 = 0x04U;                       /* Reset interrupt request flag */

  if (FSK_Out_IRQ_EnEvent) {           /* Are the events enabled? */

    __EI();

    FSK_Out_IRQ_OnInterrupt();         /* Invoke user event */

  }

}

The code to toggle this flag was removed from the EnableEvent and the DisableEvent flags, so there is no way to enable this flag to get the interrupt to work.  This check for EnEvent is no longer required and should be removed.

0 Kudos
1,568 Views
vfilip
NXP Employee
NXP Employee

Hello,

please find the updated patch in the attachment. Sorry for inconvenience.

best regards

Vojtech Filip

Processor Expert Support Team


0 Kudos
1,568 Views
jgirard1
Contributor III

Hello.  I hate to keep doing this to you, but there is still a problem with this Hot Fix.  A reference to the former event enable flag "EnEvent" is still being generated in the Cpu.c - PE_low_level_init() function.

  FSK_Out_IRQ_EnEvent = FALSE;       /* Disable events */

The code will not build because of this error:

Error   : C1815: FSK_Out_IRQ_EnEvent not declared (or typename)

Cpu.c line 2290

Sorry for the inconvenience and thank you again for all your help.  We are getting closer to the target.

0 Kudos
1,568 Views
vfilip
NXP Employee
NXP Employee

Hello,

I have tried several combination but I was not able to reproduce it. Could you please post here the *.pe file from your project to analyze it?

best regards

Vojtech Filip

Processor Expert Support Team


0 Kudos
1,568 Views
jgirard1
Contributor III

Hello?  I've responded back to you many times.  Can you please help fix the hot fix you sent me?  It has been weeks since you last responded.  Thank you.

0 Kudos
1,568 Views
vfilip
NXP Employee
NXP Employee

Hello,

sorry for the delay, we are still working on the issue. The update should be ready tomorrow.

best regards

Vojtech Filip

Processor Expert Support Team


0 Kudos
1,568 Views
vfilip
NXP Employee
NXP Employee

Hello,

please find the updated patch attached. I hope that the patch will work as expected now.

best regards

Vojtech Filip

Processor Expert Support Team


0 Kudos
1,570 Views
jgirard1
Contributor III

Hi.  I am back again.

The latest hot fix to fix your other hot fix has a different problem now.

Apparently you broke TimerInt component...at least when I use it with the MC9S12XA256 API Counter or PIT, the interrupts are never enabled and it doesn't work.

After I applied and tested your latest hot fix some of my timer related features stopped working.  I have traced it to this for API Counter:

/*

** ===================================================================

**     Method      :  HWEnDi (component TimerInt)

**

**     Description :

**         Enables or disables the peripheral(s) associated with the

**         component. The method is called automatically as a part of the

**         Enable and Disable methods and several internal methods.

**         This method is internal. It is used by Processor Expert only.

** ===================================================================

*/

static void HWEnDi(void)

{

  if (EnUser) {                        /* Enable device? */

    VREGAPICL |= 0x04U;     /* Enable timer*/  <--- "This does not set APIE Flag and thus interrupts are never enabled"

  } else {                             /* Disable device? */

    clrSetReg8Bits(VREGAPICL, 0x06U, 0x01U); /* Disable API timer and interrupt */

  }

}

If I edit the processor Expert code and allow the APIE bit to be set, then it works like normal again.

    VREGAPICL |= 0x06U;     /* Enable timer*/  <--- "This also sets APIE Flag and interrupts are enabled"

I checked this with PIT0 Timer and had similar problems.

/*

** ===================================================================

**     Method      :  HWEnDi (component TimerInt)

**

**     Description :

**         Enables or disables the peripheral(s) associated with the

**         component. The method is called automatically as a part of the

**         Enable and Disable methods and several internal methods.

**         This method is internal. It is used by Processor Expert only.

** ===================================================================

*/

static void HWEnDi(void)

{

  if (EnUser) {                        /* Enable device? */

    PITCE |= 0x01U;        /* Enable timer */  <-- "PITINTE is never re-enabled, thus no interrupts occur"

  } else {                             /* Disable device? */

    PITINTE &= 0xFEU;                  /* Disable channel interrupt  */ <-- "Disabled here, but never re-enabled anywhere else"

    PITCE &= 0xFEU;                    /* Disable timer channel*/

  }

}

Apparently something was changed with TimerInt, even though I was only having issues with FreeCntr.

This pretty much makes my code useless now.  Can it be fixed soon?  Thank you.

0 Kudos
1,570 Views
vfilip
NXP Employee
NXP Employee

Hello,

I have got the fixed files from developers. Please find the patch attached.

Note:

We are sorry for inconvenience. I also hope this will be latest update of the patch...

best regards

Vojtech Filip

Processor Expert Support Team

0 Kudos